From 5bea44d6cba2ccf7a0d8c85a44aaa0d51b362ee6 Mon Sep 17 00:00:00 2001 From: Johnny McQuade Date: Mon, 30 Sep 2024 18:02:58 +0100 Subject: [PATCH 1/7] feat: audio component compact variant; refactor audio component logic --- .../components/audio/audio.component.html | 123 +++++----- .../components/audio/audio.component.scss | 213 ++++++++++++----- .../components/audio/audio.component.ts | 214 ++++++++++-------- src/theme/deployment/_overrides.scss | 6 + 4 files changed, 350 insertions(+), 206 deletions(-) diff --git a/src/app/shared/components/template/components/audio/audio.component.html b/src/app/shared/components/template/components/audio/audio.component.html index 4d7fc3cd4e..bffee84654 100644 --- a/src/app/shared/components/template/components/audio/audio.component.html +++ b/src/app/shared/components/template/components/audio/audio.component.html @@ -1,65 +1,76 @@ -
-
-
-

{{ params.title }}

- +
+ @if (params.title) { +
+

{{ params.title }}

+ @if (params.variant.includes("large") && params.showInfoButton) { +
+ +
+ }
-
-
- -
-
-
- {{ +currentTimeSong * 1000 | date: "mm:ss" }} -
-
- {{ !player ? "00:00" : (player.duration() * 1000 | date: "mm:ss") }} -
-
-
-
- + } +
+ @if (params.variant.includes("compact") && params.showInfoButton) { +
+ +
+ } +
+ +
+
+ {{ progressSeconds() * 1000 | date: "mm:ss" }} +
+ @if (params.variant.includes("large")) { +
+ {{ !player ? "00:00" : (player.duration() * 1000 | date: "mm:ss") }} +
+ } +
-
- +
+
+ +
+ +
+ +
-
- +
+ {{ errorTxt }}
-
- {{ errorTxt }} -
diff --git a/src/app/shared/components/template/components/audio/audio.component.scss b/src/app/shared/components/template/components/audio/audio.component.scss index e71f0f8891..a37686a734 100644 --- a/src/app/shared/components/template/components/audio/audio.component.scss +++ b/src/app/shared/components/template/components/audio/audio.component.scss @@ -2,86 +2,185 @@ $control-background: var(--audio-control-background, var(--ion-color-primary-500)); -.container-player { - background: var(--ion-color-primary-contrast); +.container-player[data-variant~="compact"] { + background: white; border: var(--ion-border-standard); box-sizing: border-box; box-shadow: var(--ion-default-box-shadow); border-radius: var(--ion-border-radius-standard); - padding: var(--regular-padding); + padding: var(--small-padding); display: flex; position: relative; flex-direction: column; .top-row { @include mixins.flex-space-between; - .title_and_help { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + min-height: var(--audio-title-and-help-height); + h3 { + margin: 0; + margin-right: var(--small-margin); + color: var(--ion-color-primary); + max-width: 85%; + font-weight: var(--font-weight-bold); + font-size: var(--audio-title-size); + } + } + + .second-row { + display: flex; + flex-direction: row-reverse; + + .controls { + @include mixins.flex-space-between; + // width: var(--audio-controls-width); + align-self: center; + .rewind, + .forward { + display: none; + } + ion-button.btn-play { + @include mixins.medium-square; + margin-right: var(--small-margin); + --background: #{$control-background}; + --border-radius: var(--ion-border-radius-rounded); + --box-shadow: var(--ion-default-box-shadow); + ion-icon { + position: absolute; + font-size: var(--icon-size-tiny); + // Fine-tune spacing of 'play' icon so that triangle appears to be centred visually + &.play-icon { + padding-left: 4px; + } + } + } + } + + .progress-block { width: 100%; display: flex; - align-items: center; - justify-content: space-between; - min-height: var(--audio-title-and-help-height); - h3 { - margin: 0; - margin-right: var(--small-margin); - color: var(--ion-color-primary); - max-width: 85%; - font-weight: var(--font-weight-bold); - font-size: var(--audio-title-size); + margin-left: var(--small-margin); + ion-range { + width: 100%; + --bar-background: var(--ion-color-gray-200); + --bar-height: 4px; + --knob-size: 18px; + --knob-background: var(--ion-color-primary); + --bar-border-radius: 10px; } - .audio-help { - color: var(--ion-color-primary); - height: var(--help-icon-standard-size); - width: var(--help-icon-standard-size); + .time { + @include mixins.flex-space-between; + margin-left: var(--small-margin); + .time-value { + font-size: var(--font-size-text-small); + line-height: var(--line-height-text-small); + color: var(--ion-color-primary); + } } } - } - .progress-block { - .audio-range { - --bar-background-active: #{$control-background}; - --bar-background: transparent; - --bar-height: 4px; - --bar-border-radius: var(--ion-border-radius-secondary); - --knob-size: 0px; - --pin-background: var(--ion-color-primary); - --knob-background: var(--ion-color-primary); - padding-inline: 0; - } - - ion-range::part(bar) { - border: var(--ion-border-thin-standard); - height: var(--audio-bar-height); + .info-icon-container { + @include mixins.flex-centered; + margin-left: var(--small-margin); + ion-icon { + color: var(--ion-color-primary); + font-size: var(--icon-size-tiny); + } } - ion-range::part(bar-active) { - top: 4px; - margin-left: 3px; + .error-text { + margin: var(--small-margin) 0; + text-align: center; } } - .time { +} + +.container-player[data-variant~="large"] { + background: var(--ion-color-primary-contrast); + border: var(--ion-border-standard); + box-sizing: border-box; + box-shadow: var(--ion-default-box-shadow); + border-radius: var(--ion-border-radius-standard); + padding: var(--regular-padding); + display: flex; + position: relative; + flex-direction: column; + .top-row { @include mixins.flex-space-between; - &-value { - font-size: var(--font-size-text-large); - line-height: var(--line-height-text-small); + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + min-height: var(--audio-title-and-help-height); + h3 { + margin: 0; + margin-right: var(--small-margin); color: var(--ion-color-primary); + max-width: 85%; + font-weight: var(--font-weight-bold); + font-size: var(--audio-title-size); } - } - .controls { - @include mixins.flex-space-between; - min-width: var(--audio-controls-width); - align-self: center; - .rewind, - .forward { + .info-icon-container { + @include mixins.flex-centered; ion-icon { - font-size: var(--icon-size-largest); color: var(--ion-color-primary); + font-size: var(--icon-size-small); } } - .rewind { - ion-icon { - transform: rotate(180deg); + } + + .second-row { + display: flex; + flex-direction: column; + + .progress-block { + width: 100%; + .audio-range { + --bar-background-active: #{$control-background}; + --bar-background: transparent; + --bar-height: 4px; + --bar-border-radius: var(--ion-border-radius-secondary); + --knob-size: 0px; + --pin-background: var(--ion-color-primary); + --knob-background: var(--ion-color-primary); + padding-inline: 0; + } + + ion-range::part(bar) { + border: var(--ion-border-thin-standard); + height: var(--audio-bar-height); + } + + ion-range::part(bar-active) { + top: 4px; + margin-left: 3px; + } + .time { + @include mixins.flex-space-between; + &-value { + font-size: var(--font-size-text-large); + line-height: var(--line-height-text-small); + color: var(--ion-color-primary); + } } } - .play { + .controls { + @include mixins.flex-space-between; + width: var(--audio-controls-width); + align-self: center; + .rewind, + .forward { + ion-icon { + font-size: var(--icon-size-largest); + color: var(--ion-color-primary); + } + } + .rewind { + ion-icon { + transform: rotate(180deg); + } + } .btn-play { @include mixins.large-square; --background: #{$control-background}; @@ -98,10 +197,10 @@ $control-background: var(--audio-control-background, var(--ion-color-primary-500 } } } - } - .error-text { - margin: var(--small-margin) 0; - text-align: center; + .error-text { + margin: var(--small-margin) 0; + text-align: center; + } } } .disabled { diff --git a/src/app/shared/components/template/components/audio/audio.component.ts b/src/app/shared/components/template/components/audio/audio.component.ts index 8fe948fe2e..516513f95f 100644 --- a/src/app/shared/components/template/components/audio/audio.component.ts +++ b/src/app/shared/components/template/components/audio/audio.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnDestroy, OnInit, signal, ViewChild } from "@angular/core"; +import { Component, computed, Input, OnDestroy, OnInit, signal } from "@angular/core"; import { FlowTypes } from "../../../../model"; import { getBooleanParamFromTemplateRow, @@ -6,7 +6,6 @@ import { getStringParamFromTemplateRow, } from "../../../../utils"; import { Howl } from "howler"; -import { IonRange } from "@ionic/angular"; import { ITemplateRowProps } from "../../models"; import { TemplateBaseComponent } from "../base"; import { PLHAssetPipe } from "../../pipes/plh-asset.pipe"; @@ -18,6 +17,8 @@ const PAUSE_ICON_DEFAULT = "pause-outline"; const FORWARD_ICON_DEFAULT = "play-forward"; interface IAudioParams { + /** TEMPLATE PARAMETER: "variant". Default "large". */ + variant: "large" | "compact"; /** TEMPLATE PARAMETER: "src". Will be overridden by a value passed as "value" to the component. */ src: string; /** TEMPLATE PARAMETER: "title" */ @@ -30,19 +31,18 @@ interface IAudioParams { * Will be mirrored to be used as the reqind icon. Default icon is ion's "play-forward" * */ forwardIconAsset: string; - /** TEMPLATE PARAMETER: "help_icon_asset". The path to an svg to override the default help icon. */ - helpIconAsset: string; - /** TEMPLATE PARAMETER: "help_text". Text to be displayed as a tooltip when clicking the "help" icon. - * Icon and tooltip will not be displayed if value not provided. Default null */ - helpText: string; + /** TEMPLATE PARAMETER: "show_info_button". Should show the info button. Default false (unless info_icon_asset is provided) */ + showInfoButton: boolean; + /** TEMPLATE PARAMETER: "info_icon_asset". The path to an svg to override the default info icon. The default is an icon indicating a transcript */ + infoIconAsset: string; /** TEMPLATE PARAMETER: "range_bar_disabled". If true, the use cannot scrub through the audio using the range bar. * Default false. */ rangeBarDisabled: boolean; - /** TEMPLATE PARAMETER: "time_to_rewind". The increment of time, in seconds, that will be applied when clicking the forward or backward buttons. + /** TEMPLATE PARAMETER: "time_to_skip". The increment of time, in seconds, that will be applied when clicking the forward or backward buttons. * Default 15. */ - timeToRewind: number; + timeToSkip: number; } @Component({ @@ -55,24 +55,35 @@ export class TmplAudioComponent implements ITemplateRowProps, OnInit, OnDestroy { @Input() template: FlowTypes.Template; - @ViewChild("range", { static: false }) range: IonRange; params: Partial = {}; /** @ignore */ player: Howl = null; - /** @ignore */ - isPlayed: boolean = false; - /** @ignore */ - errorTxt: string | null; - /** @ignore */ + /** + * Track the playing state of the player UI. Decoupled from whether the actual audio is playing (this.player.playing()) + * so that manually seeking works as expected: if player is playing before dragging the slider, playing continues after dragging + * @ignore + * */ + isPlaying: boolean = false; + /** + * Progress, as a percentage of total duration + * @ignore + * */ progress = signal(0); + /** + * Progress in seconds + * @ignore + * */ + progressSeconds = computed(() => { + return (this.progress() / 100) * this.player.duration(); + }); /** @ignore */ - rangeBarTouched: boolean = false; - /** @ignore */ - currentTimeSong: string = "0"; + errorTxt: string | null; /** @ignore */ hasStarted: boolean = false; + /** @ignore */ + trackerInterval: NodeJS.Timeout; constructor(private plhAssetPipe: PLHAssetPipe) { super(); @@ -83,7 +94,10 @@ export class TmplAudioComponent this.initPlayer(); } - getParams() { + private getParams() { + this.params.variant = getStringParamFromTemplateRow(this._row, "variant", "compact") + .split(",") + .join(" ") as IAudioParams["variant"]; this.params.src = this.plhAssetPipe.transform( this._row.value || getStringParamFromTemplateRow(this._row, "src", null) ); @@ -100,107 +114,121 @@ export class TmplAudioComponent FORWARD_ICON_DEFAULT ); this.params.title = getStringParamFromTemplateRow(this._row, "title", ""); - this.params.helpText = getStringParamFromTemplateRow(this._row, "help_text", null); - this.params.helpIconAsset = getStringParamFromTemplateRow(this._row, "help_icon_asset", null); + this.params.infoIconAsset = getStringParamFromTemplateRow(this._row, "info_icon_asset", null); + this.params.showInfoButton = + !!this.params.infoIconAsset || + getBooleanParamFromTemplateRow(this._row, "show_info_button", false); this.params.rangeBarDisabled = getBooleanParamFromTemplateRow( this._row, "range_bar_disabled", false ); - this.params.timeToRewind = getNumberParamFromTemplateRow(this._row, "time_to_rewind", 15); + this.params.timeToSkip = getNumberParamFromTemplateRow(this._row, "time_to_skip", 15); } - getAssetParamFromTemplateRow(parameterName: string, _default: string | null) { + private getAssetParamFromTemplateRow(parameterName: string, _default: string | null) { const value = getStringParamFromTemplateRow(this._row, parameterName, null); return value ? this.plhAssetPipe.transform(value) : _default; } - initPlayer() { - return this.params.src - ? (this.player = new Howl({ - src: [this.params.src], - onplay: () => { - this.isPlayed = true; - this.updateProgress(); - if (!this.hasStarted) { - this.hasStarted = true; - this.triggerActions("audio_first_start"); - } - this.triggerActions("audio_play"); - }, - onend: () => { - this.isPlayed = false; - this.range.value = 0; - this.currentTimeSong = "0"; - this.updateProgress(); - this.triggerActions("audio_end"); - }, - onpause: () => { - this.isPlayed = false; - this.updateProgress(); - this.triggerActions("audio_pause"); - }, - })) - : (this.errorTxt = "Src is undefined, player not initialized"); + private initPlayer() { + if (this.params.src) { + this.player = new Howl({ + src: [this.params.src], + onplay: () => { + this.startProgressTracker(); + if (!this.hasStarted) { + this.hasStarted = true; + this.triggerActions("audio_first_start"); + } + this.triggerActions("audio_play"); + }, + onend: () => { + this.isPlaying = false; + this.progress.set(0); + this.startProgressTracker(); + this.triggerActions("audio_end"); + }, + onpause: () => { + this.startProgressTracker(); + this.triggerActions("audio_pause"); + }, + }); + } else { + this.errorTxt = "Src is undefined, player not initialized"; + } } - togglePlayer() { - this.isPlayed = !this.isPlayed; - return this.isPlayed ? this.player.play() : this.player.pause(); + public async clickInfo() { + await this.triggerActions("info_click"); } - rewindNext() { - this.player.seek((this.player.seek() as any) + this.params.timeToRewind); - this.customUpdateWhenRewind(); + public togglePlay() { + if (this.isPlaying) { + this.player.pause(); + } else { + this.player.play(); + } + this.isPlaying = !this.isPlaying; } - rewindPrev() { - this.player.seek( - (this.player.seek() as any) < this.params.timeToRewind - ? (this.player.seek(0) as any) - : (this.player.seek() as any) - this.params.timeToRewind - ); - this.customUpdateWhenRewind(); + /** + * Handle dragging of the range bar. Does not seek within the actual audio file, + * this should only be triggered when the handle is released (on ionChange) + */ + public handleProgressDrag(event) { + this.progress.set(event.detail.value); } - seek() { - let newValue = +this.range.value; - let duration = this.player.duration(); - this.player.seek(duration * (newValue / 100)); - this.rangeBarTouched = false; - this.updateProgress(); + /** + * Jump to a specific time in the audio (i.e. "seek") + * @param targetTime in milliseconds, default is current progress + */ + public setTime(targetTime: number = this.progressSeconds()) { + // Ensure targetTime does not go below 0 + if (targetTime < 0) { + targetTime = 0; + } + this.player.seek(targetTime); + this.progress.set((targetTime / this.player.duration()) * 100 || 0); } - updateProgress() { - const ref = setInterval(() => { - if (!this.isPlayed || this.rangeBarTouched) { - clearInterval(ref); - return; - } - let seek: any = this.player.seek(); - this.progress.set((seek / this.player.duration()) * 100 || 0); - this.currentTimeSong = this.player.seek() ? (this.player.seek() as any).toString() : "0"; - }, 1000); + public skipForward() { + this.skip(this.params.timeToSkip); } - checkFocus() { - this.rangeBarTouched = true; + public skipBackward() { + this.skip(-this.params.timeToSkip); } - checkChange() { - if (this.rangeBarTouched) { - let newValue = +this.range.value; - let duration = this.player.duration(); - this.player.seek(duration * (newValue / 100)); - this.currentTimeSong = this.player.seek() ? (this.player.seek() as any).toString() : "0"; - } + /** + * Skip forward or backward by a specified interval + * @param timeToSkip in seconds + */ + public skip(timeToSkip: number) { + const currentTime = this.player.seek(); + const targetTime = currentTime + timeToSkip; + this.setTime(targetTime); + } + + /** + * Starts tracking the progress of the audio and updates the value of this.progress() accordingly + */ + private startProgressTracker() { + this.stopProgressTracker(); // Ensure any existing tracker is stopped + this.trackerInterval = setInterval(() => { + if (!this.player.playing()) { + this.stopProgressTracker(); + return; + } + this.progress.set((this.player.seek() / this.player.duration()) * 100 || 0); + }, 10); } - customUpdateWhenRewind() { - if (!this.isPlayed) { - let seek: any = this.player.seek(); - this.progress.set((seek / this.player.duration()) * 100 || 0); - this.currentTimeSong = this.player.seek() ? (this.player.seek() as any).toString() : "0"; + private stopProgressTracker() { + if (this.trackerInterval) { + clearInterval(this.trackerInterval); + this.trackerInterval = null; } } diff --git a/src/theme/deployment/_overrides.scss b/src/theme/deployment/_overrides.scss index 9ec717d482..cf08baa647 100644 --- a/src/theme/deployment/_overrides.scss +++ b/src/theme/deployment/_overrides.scss @@ -9,6 +9,12 @@ ion-content { --padding-bottom: 24px; --padding-start: 24px; --padding-end: 24px; + + // HACK: prevent scrollbar from hiding when interacting with ion-range, for example (this can cause visual glitches). + // see https://github.com/ionic-team/ionic-framework/issues/25595#issuecomment-1330293954 + &::part(scroll) { + overflow-y: auto !important; + } } ion-content.no-padding { --padding-top: 0; From 535e5afa445e9122e28d6c353804723da27e0acf Mon Sep 17 00:00:00 2001 From: Johnny McQuade Date: Tue, 1 Oct 2024 11:31:02 +0100 Subject: [PATCH 2/7] chore: move author-facing error to console --- .../template/components/audio/audio.component.html | 7 ++----- .../template/components/audio/audio.component.ts | 9 ++++++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/app/shared/components/template/components/audio/audio.component.html b/src/app/shared/components/template/components/audio/audio.component.html index bffee84654..bd14f2966e 100644 --- a/src/app/shared/components/template/components/audio/audio.component.html +++ b/src/app/shared/components/template/components/audio/audio.component.html @@ -46,7 +46,7 @@

{{ params.title }}

}
-
+
{{ params.title }} (click)="skipBackward()" >
- + {{ params.title }} >
-
- {{ errorTxt }} -
diff --git a/src/app/shared/components/template/components/audio/audio.component.ts b/src/app/shared/components/template/components/audio/audio.component.ts index 516513f95f..9ac3d6b92e 100644 --- a/src/app/shared/components/template/components/audio/audio.component.ts +++ b/src/app/shared/components/template/components/audio/audio.component.ts @@ -76,10 +76,10 @@ export class TmplAudioComponent * @ignore * */ progressSeconds = computed(() => { - return (this.progress() / 100) * this.player.duration(); + return (this.progress() / 100) * this.player?.duration(); }); /** @ignore */ - errorTxt: string | null; + sourceMissing: boolean = false; /** @ignore */ hasStarted: boolean = false; /** @ignore */ @@ -155,7 +155,10 @@ export class TmplAudioComponent }, }); } else { - this.errorTxt = "Src is undefined, player not initialized"; + console.error( + "[AUDIO COMPONENT] No audio source provided (path to audio asset should be passed as value)" + ); + this.sourceMissing = true; } } From 99a58733fa1a9c80515e5bba66a5c7e9d93ff01c Mon Sep 17 00:00:00 2001 From: Johnny McQuade Date: Tue, 1 Oct 2024 11:51:03 +0100 Subject: [PATCH 3/7] chore: code tidy --- .../components/audio/audio.component.html | 6 +++--- .../components/audio/audio.component.scss | 10 ---------- .../components/audio/audio.component.ts | 18 +++++++++--------- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/app/shared/components/template/components/audio/audio.component.html b/src/app/shared/components/template/components/audio/audio.component.html index bd14f2966e..987ad4c103 100644 --- a/src/app/shared/components/template/components/audio/audio.component.html +++ b/src/app/shared/components/template/components/audio/audio.component.html @@ -30,8 +30,8 @@

{{ params.title }}

max="100" aria-readonly="true" [value]="progress()" - (ionInput)="handleProgressDrag($event)" - (ionChange)="setTime()" + (ionInput)="onProgressDrag($event)" + (ionChange)="seekToTime()" (touchstart)="player.pause()" (touchend)="this.isPlaying ? player.play() : player.pause()" > @@ -54,7 +54,7 @@

{{ params.title }}

(click)="skipBackward()" >
- + Date: Tue, 1 Oct 2024 12:54:29 +0100 Subject: [PATCH 4/7] chore: code tidy --- .../template/components/audio/audio.component.html | 6 +++--- .../components/template/components/audio/audio.component.ts | 5 +---- src/app/shared/components/template/pipes/plh-asset.pipe.ts | 1 + 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/app/shared/components/template/components/audio/audio.component.html b/src/app/shared/components/template/components/audio/audio.component.html index 987ad4c103..16bea83783 100644 --- a/src/app/shared/components/template/components/audio/audio.component.html +++ b/src/app/shared/components/template/components/audio/audio.component.html @@ -6,7 +6,7 @@

{{ params.title }}

@@ -18,7 +18,7 @@

{{ params.title }}

@@ -54,7 +54,7 @@

{{ params.title }}

(click)="skipBackward()" >
- + Date: Mon, 7 Oct 2024 14:56:10 +0100 Subject: [PATCH 5/7] chore(audio): dynamic progress check interval; show duration on initial load; code tidying --- .../template/components/audio/audio.component.html | 9 +++++++-- .../template/components/audio/audio.component.scss | 2 -- .../template/components/audio/audio.component.ts | 7 +++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/app/shared/components/template/components/audio/audio.component.html b/src/app/shared/components/template/components/audio/audio.component.html index 16bea83783..122b44cb63 100644 --- a/src/app/shared/components/template/components/audio/audio.component.html +++ b/src/app/shared/components/template/components/audio/audio.component.html @@ -4,6 +4,7 @@

{{ params.title }}

@if (params.variant.includes("large") && params.showInfoButton) {
+ {{ params.title }} >
- {{ progressSeconds() * 1000 | date: "mm:ss" }} + {{ + hasStarted + ? (progressSeconds() * 1000 | date: "mm:ss") + : (player?.duration() * 1000 | date: "mm:ss") + }}
@if (params.variant.includes("large")) {
- {{ !player ? "00:00" : (player.duration() * 1000 | date: "mm:ss") }} + {{ !player ? "00:00" : (player?.duration() * 1000 | date: "mm:ss") }}
}
diff --git a/src/app/shared/components/template/components/audio/audio.component.scss b/src/app/shared/components/template/components/audio/audio.component.scss index 3245f579fe..2308cb153a 100644 --- a/src/app/shared/components/template/components/audio/audio.component.scss +++ b/src/app/shared/components/template/components/audio/audio.component.scss @@ -16,8 +16,6 @@ $control-background: var(--audio-control-background, var(--ion-color-primary-500 @include mixins.flex-space-between; width: 100%; display: flex; - align-items: center; - justify-content: space-between; min-height: var(--audio-title-and-help-height); h3 { margin: 0; diff --git a/src/app/shared/components/template/components/audio/audio.component.ts b/src/app/shared/components/template/components/audio/audio.component.ts index 6c387093c3..d536ac66e2 100644 --- a/src/app/shared/components/template/components/audio/audio.component.ts +++ b/src/app/shared/components/template/components/audio/audio.component.ts @@ -215,14 +215,17 @@ export class TmplAudioComponent * Begins tracking audio playback progress, updating this.progress() with the current playback percentage */ private startProgressTracker() { + const duration = this.player.duration(); + // Caculate interval (in milliseconds) as 1/200th of the audio duration (in seconds) + const interval = duration * 5; this.stopProgressTracker(); // Ensure any existing tracker is stopped this.trackerInterval = setInterval(() => { if (!this.player.playing()) { this.stopProgressTracker(); return; } - this.progress.set((this.player.seek() / this.player.duration()) * 100 || 0); - }, 10); + this.progress.set((this.player.seek() / duration) * 100 || 0); + }, interval); } private stopProgressTracker() { From 3bb9889f510d142e8be67046939171f191458254 Mon Sep 17 00:00:00 2001 From: Johnny McQuade Date: Mon, 7 Oct 2024 17:55:29 +0100 Subject: [PATCH 6/7] fix: reset clock behaviour on large variant of audio component --- .../components/audio/audio.component.html | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/app/shared/components/template/components/audio/audio.component.html b/src/app/shared/components/template/components/audio/audio.component.html index 122b44cb63..6ded95954f 100644 --- a/src/app/shared/components/template/components/audio/audio.component.html +++ b/src/app/shared/components/template/components/audio/audio.component.html @@ -37,17 +37,21 @@

{{ params.title }}

(touchend)="this.isPlaying ? player.play() : player.pause()" >
-
- {{ - hasStarted - ? (progressSeconds() * 1000 | date: "mm:ss") - : (player?.duration() * 1000 | date: "mm:ss") - }} -
@if (params.variant.includes("large")) { +
+ {{ progressSeconds() * 1000 | date: "mm:ss" }} +
{{ !player ? "00:00" : (player?.duration() * 1000 | date: "mm:ss") }}
+ } @else { +
+ {{ + hasStarted + ? (progressSeconds() * 1000 | date: "mm:ss") + : (player?.duration() * 1000 | date: "mm:ss") + }} +
}
From bb8dfad325f93e2799a6d521639b99cea8c5bd91 Mon Sep 17 00:00:00 2001 From: Johnny McQuade Date: Tue, 8 Oct 2024 14:38:36 +0100 Subject: [PATCH 7/7] chore: code tidy --- .../components/audio/audio.component.html | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/app/shared/components/template/components/audio/audio.component.html b/src/app/shared/components/template/components/audio/audio.component.html index 6ded95954f..aa59abb069 100644 --- a/src/app/shared/components/template/components/audio/audio.component.html +++ b/src/app/shared/components/template/components/audio/audio.component.html @@ -4,12 +4,11 @@

{{ params.title }}

@if (params.variant.includes("large") && params.showInfoButton) {
- - + @if (params.infoIconAsset) { + + } @else { + + }
} @@ -17,11 +16,11 @@

{{ params.title }}

@if (params.variant.includes("compact") && params.showInfoButton) {
- + @if (params.infoIconAsset) { + + } @else { + + }
}