Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/tmpz 775 build button for aduio naration #4000

Open
wants to merge 67 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 64 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
5d09508
feat/TMPZ-777-audio-player-mobile
dbuljanNewsUk Nov 15, 2024
fd71256
feat/TMPZ-777-audio-player-working-player
dbuljanNewsUk Nov 16, 2024
8033ea5
feat/TMPZ-777-audio-player-working-player
dbuljanNewsUk Nov 16, 2024
e85ad64
feat/TMPZ-777-audio-player
dbuljanNewsUk Nov 19, 2024
2535894
feat/TMPZ-777-audio-player-lin-sht
dbuljanNewsUk Nov 19, 2024
4968d1a
feat(TMPZ-775): created audio playe button
josipVuko Nov 20, 2024
4c5515a
Merge branch 'feat/TMPZ-777-audio-player' into feat/TMPZ-775-build_bu…
josipVuko Nov 20, 2024
e85f570
feat/TMPZ-777-audio-player-update-icons-from-master
dbuljanNewsUk Nov 20, 2024
39c7817
Merge branch 'master' into feat/TMPZ-777-audio-player
dbuljanNewsUk Nov 21, 2024
786dea4
feat/TMPZ-777-audio-player-icons
dbuljanNewsUk Nov 21, 2024
caf54b0
feat/TMPZ-777-audio-player-icons
dbuljanNewsUk Nov 21, 2024
4e21301
feat/TMPZ-777-audio-player-tests
dbuljanNewsUk Nov 21, 2024
6133478
feat(TMPZ-775): added imperative handle for audio player
josipVuko Nov 21, 2024
77bc1ea
feat/TMPZ-777-audio-player-tests
dbuljanNewsUk Nov 21, 2024
2d102c8
feat/TMPZ-777-audio-player-tests
dbuljanNewsUk Nov 21, 2024
22db637
feat(TMPZ-775): minor adjustments
josipVuko Nov 21, 2024
c6b3614
feat/TMPZ-777-audio-player-tests
dbuljanNewsUk Nov 21, 2024
bf060fa
feat/TMPZ-777-audio-player-tests
dbuljanNewsUk Nov 21, 2024
fd19129
feat/TMPZ-777-audio-player-tests
dbuljanNewsUk Nov 21, 2024
7d3de68
feat/TMPZ-777-audio-player-tests
dbuljanNewsUk Nov 21, 2024
36be192
feat/TMPZ-777-audio-player-no-test-cus-of-bad-and-outdated-env
dbuljanNewsUk Nov 21, 2024
45f85c9
feat/TMPZ-777-audio-player-no-test-cus-of-bad-and-outdated-env
dbuljanNewsUk Nov 21, 2024
523ad1a
feat/TMPZ-777-audio-player-no-test-audio
dbuljanNewsUk Nov 21, 2024
fffa567
feat/TMPZ-777-audio-player-no-test-audio
dbuljanNewsUk Nov 21, 2024
ef3b742
feat/TMPZ-777-audio-player-no-test-audio
dbuljanNewsUk Nov 21, 2024
3948a82
feat/TMPZ-777-audio-player-no-test-audio
dbuljanNewsUk Nov 21, 2024
85a38ff
feat/TMPZ-777-audio-player-no-test-audio
dbuljanNewsUk Nov 21, 2024
6234925
feat/TMPZ-777-audio-player-no-test-audio
dbuljanNewsUk Nov 21, 2024
a7680e6
feat/TMPZ-777-audio-player-no-test-audio
dbuljanNewsUk Nov 21, 2024
4ce9226
feat/TMPZ-777-audio-player-no-test-audio
dbuljanNewsUk Nov 22, 2024
6397c98
feat(TMPZ-775): updated new icons
josipVuko Nov 22, 2024
98114a7
feat/TMPZ-777-audio-player-components-fix
dbuljanNewsUk Nov 22, 2024
5258af2
feat/TMPZ-777-audio-player-components-fix-remove-old-player
dbuljanNewsUk Nov 22, 2024
a22d716
Merge branch 'master' into feat/TMPZ-777-audio-player
dbuljanNewsUk Nov 22, 2024
8badd22
feat/TMPZ-777-audio-player-with-tests
dbuljanNewsUk Nov 22, 2024
57b1fbc
feat/TMPZ-777-audio-player-with-tests
dbuljanNewsUk Nov 22, 2024
6ede200
feat/TMPZ-777-audio-player-with-tests
dbuljanNewsUk Nov 22, 2024
d7a37b6
feat/TMPZ-777-audio-player-with-tests
dbuljanNewsUk Nov 22, 2024
3b1597a
feat/TMPZ-777-audio-player-analyitcs-test
dbuljanNewsUk Nov 25, 2024
5318ceb
temporary reduction in thresholds code is in transition
adamosborne-tnl Nov 25, 2024
59c415e
feat/TMPZ-777-audio-player-using-ts-styles
dbuljanNewsUk Nov 25, 2024
da44476
feat/TMPZ-777-audio-player-new-tests
dbuljanNewsUk Nov 25, 2024
0d55227
feat/TMPZ-777-audio-player-new-tests
dbuljanNewsUk Nov 25, 2024
8f0b60d
feat/TMPZ-777-audio-player-new-tests
dbuljanNewsUk Nov 25, 2024
9f02d41
feat/TMPZ-777-audio-player-new-tests
dbuljanNewsUk Nov 25, 2024
2c2dca1
feat(TMPZ-775): connected with new audio-player
josipVuko Nov 26, 2024
3a8e54a
feat/TMPZ-775-build_button_for_aduio_naration-resolve-audio-branch-re…
dbuljanNewsUk Nov 26, 2024
4d0ebfa
feat/TMPZ-775-build_button_for_aduio_naration-resolve-audio-branch-re…
dbuljanNewsUk Nov 26, 2024
aa15049
feat/TMPZ-775-build_button_for_aduio_naration-resolve-audio-branch-re…
dbuljanNewsUk Nov 26, 2024
ce086e2
feat/TMPZ-775-build_button_for_aduio_naration-writing-helping-with-test
dbuljanNewsUk Nov 26, 2024
09333b8
feat/TMPZ-775-build_button_for_aduio_naration-writing-helping-with-test
dbuljanNewsUk Nov 26, 2024
e3cc592
feat(TMPZ-775): adjusted styles, adjusted tests
josipVuko Dec 2, 2024
db293e0
feat/TMPZ-775-build_button_for_aduio_naration-test-fix
dbuljanNewsUk Dec 2, 2024
c73a9f4
feat/TMPZ-775-build_button_for_aduio_naration-test-fix
dbuljanNewsUk Dec 2, 2024
826c981
Merge branch 'master' into feat/TMPZ-775-build_button_for_aduio_naration
josipVuko Dec 3, 2024
12ef98c
feat(TMPZ-775): removed unused prop from test
josipVuko Dec 3, 2024
8ce8aa9
feat(TMPZ-775): adjusted tests
josipVuko Dec 3, 2024
10cad31
feat/TMPZ-775-build_button_for_aduio_naration
dbuljanNewsUk Dec 3, 2024
086586f
feat(TMPZ-775): manualy adjusted snap
josipVuko Dec 3, 2024
8c01133
feat(TMPZ-775): adjusted player for experiment
josipVuko Dec 6, 2024
20de0eb
feat(TMPZ-775): adjusted player
josipVuko Dec 6, 2024
3452afc
feat(TMPZ-775): merged with master
josipVuko Dec 6, 2024
4897de3
feat(TMPZ-775): adjusted article audio for experiments
josipVuko Dec 9, 2024
00bd1f7
feat(TMPZ-775): removed unused param
josipVuko Dec 9, 2024
56e4cc2
feat(TMPZ-775): adjusted lint issues
josipVuko Dec 10, 2024
c17d99c
feat(TMPZ-775): fixed lint issues
josipVuko Dec 10, 2024
2457d18
feat(TMPZ-775): added test ignore for audio nutton
josipVuko Dec 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/save-and-share-bar/src/save-and-share-bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import getTokenisedArticleUrlApi from "./get-tokenised-article-url-api";
import withTrackEvents from "./tracking/with-track-events";
import SharingApiUrls from "./constants";
import styles from "./styles";
import { ArticleAudio } from "@times-components/ts-components";

import {
SaveAndShareBarContainer,
Expand Down Expand Up @@ -222,7 +223,7 @@ function SaveAndShareBar(props) {
</Popover>
</ShareButtonContainer>
)}

{savingEnabled ? (
<>
<UserState
Expand All @@ -247,6 +248,9 @@ function SaveAndShareBar(props) {
)}
</>
) : null}
<div id="audio-narration-wrapper" style={{display: "none"}}>
<ArticleAudio audioSrc="https://www.kozco.com/tech/LRMonoPhase4.mp3" />
</div>
</SaveAndShareBarContainer>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { FC, useState, useRef } from 'react';
import { AudioButton } from './styles';
import { AudioButton, AudioDuration } from './styles';
import { AudioPlayer } from '../audio-player-components/AudioPlayer';
import { PlayIcon, PauseIcon } from '@times-components/icons';
export interface ArticleAudioProps {
Expand Down Expand Up @@ -30,14 +30,17 @@ export const ArticleAudio: FC<ArticleAudioProps> = ({ audioSrc }) => {

if (audioState === 'playing') {
setAudioState('paused');
setisAudioPlayerVisible(false);
} else {
setAudioState('playing');
}
};

const hidePlayer = () => {
setisAudioPlayerVisible(false);
setAudioState('not-started');
};


return (
<div>
Expand All @@ -46,11 +49,13 @@ export const ArticleAudio: FC<ArticleAudioProps> = ({ audioSrc }) => {
src={audioSrc}
onLoadedMetadata={handleLoadedMetadata}
preload="metadata"

/>
<AudioButton
onClick={handlePlayPause}
className='article-audio-button'
style={{
backgroundColor: audioState !== 'not-started' ? '#1D1D1B' : 'unset',
backgroundColor: audioState !== 'not-started' ? '#1D1D1B' : "#fff",
color: audioState === 'not-started' ? '#333' : '#fff'
}}
>
Expand All @@ -67,25 +72,29 @@ export const ArticleAudio: FC<ArticleAudioProps> = ({ audioSrc }) => {
<PlayIcon width={16} height={16} /> Listen
</>
)}
<span
<AudioDuration
style={{
color: audioState === 'not-started' ? '#696969' : '#fff'
}}
>
{' '}
{duration} min
</span>
</AudioDuration>
</AudioButton>
{isAudioPlayerVisible && (
<div data-testid="audioPlayerWrapper" style={{

display: !isAudioPlayerVisible ? 'none' : 'block'
}}>
<AudioPlayer
src={audioSrc}
isPlayingProp={audioState === 'playing'}
onPlay={() => setAudioState('playing')}
onPause={() => setAudioState('paused')}
onEnded={() => setAudioState('not-started')}
onEnded={() => hidePlayer()}
onClose={() => hidePlayer()}
/>
)}
</div>

</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,21 @@ jest.mock('../styles', () => ({
<button data-testid="audio-button" onClick={onClick} style={style}>
{children}
</button>
),
AudioDuration: ({ children, style }: any) => (
<span data-testid="audio-duration" style={style}>
{children}
</span>
)
}));

jest.mock('@times-components/icons', () => ({
__esModule: true,
PlayIcon: ({ color }: any) => (
<svg data-testid="play-icon" style={{ color: color || '#333' }} />
PlayIcon: ({ fill }: any) => (
<svg data-testid="play-icon" style={{ fill: fill || '#333' }} />
),
PauseIcon: ({ color }: any) => (
<svg data-testid="pause-icon" style={{ color: color || '#333' }} />
PauseIcon: ({ fill }: any) => (
<svg data-testid="pause-icon" style={{ fill: fill || '#333' }} />
)
}));

Expand Down Expand Up @@ -60,133 +65,128 @@ describe('ArticleAudio', () => {
const audioButton = getByTestId('audio-button');
expect(audioButton).toBeInTheDocument();

expect(audioButton.style.backgroundColor).toBe('');
expect(audioButton).toHaveStyle('color: #333');
expect(audioButton).toHaveStyle('background-color: #fff');


// The initial state should display 'Listen' and the duration
expect(getByText('Listen')).toBeInTheDocument();
expect(getByText('3 min')).toBeInTheDocument();

// Since audioState is 'not-started', duration color should be '#696969'
const durationSpan = getByText('3 min');
// Verify duration color when 'not-started'
const durationSpan = getByTestId('audio-duration');
expect(durationSpan).toHaveStyle('color: #696969');
});

test('hides AudioPlayer when close button is clicked (using mocked AudioPlayer)', () => {
const { getByTestId, queryByTestId, container, getByText } = render(
test('handles AudioPlayer visibility toggling', () => {
const { getByTestId, queryByTestId, container } = render(
<ArticleAudio audioSrc="https://www.kozco.com/tech/LRMonoPhase4.mp3" />
);

// Trigger the 'loadedmetadata' event to set the duration

const audio = container.querySelector('audio') as HTMLAudioElement;
act(() => {
fireEvent.loadedMetadata(audio);
});

// Initially, the AudioPlayer should not be visible
expect(queryByTestId('audio-player')).not.toBeInTheDocument();

// Click the audio button to start playback

const audioPlayer = queryByTestId('audioPlayerWrapper');

// Verify the player is hidden initially
expect(audioPlayer).toBeInTheDocument();
// expect(audioPlayer).toHaveStyle('opacity: 0');
expect(audioPlayer).toHaveStyle('display: none');

// Click to show the player
const audioButton = getByTestId('audio-button');
fireEvent.click(audioButton);

// The mocked AudioPlayer should now be visible
expect(getByTestId('audio-player')).toBeInTheDocument();

// Use the mocked Close button inside the AudioPlayer to close it
const closeButton = getByText('Close');
fireEvent.click(closeButton);

// The AudioPlayer should no longer be visible
expect(queryByTestId('audio-player')).not.toBeInTheDocument();

// Verify the player is now visible
// expect(audioPlayer).toHaveStyle('opacity: 1');
expect(audioPlayer).toHaveStyle('visibility: visible');
});

test('handles play and pause', () => {
test('handles play and pause state transitions correctly', () => {
const { getByTestId, getByText, container } = render(
<ArticleAudio audioSrc="https://www.kozco.com/tech/LRMonoPhase4.mp3" />
);

// Trigger the 'loadedmetadata' event to set the duration
// Trigger the 'loadedmetadata' event
const audio = container.querySelector('audio') as HTMLAudioElement;
act(() => {
fireEvent.loadedMetadata(audio);
});

const audioButton = getByTestId('audio-button');

// Simulate clicking the play button
// Click to play
fireEvent.click(audioButton);

// Now, audioState should be 'playing'
expect(getByText('Playing')).toBeInTheDocument();
expect(audioButton).toHaveStyle('background-color: #1D1D1B');
expect(audioButton).toHaveStyle('color: #fff');
expect(getByText('Playing')).toBeInTheDocument();

// Since audioState is 'playing', duration color should be '#fff'
const durationSpan = getByText('3 min');
// Duration color should change to white
const durationSpan = getByTestId('audio-duration');
expect(durationSpan).toHaveStyle('color: #fff');

// Simulate clicking the pause button
// Click to pause
fireEvent.click(audioButton);

expect(getByText('Paused')).toBeInTheDocument();
expect(audioButton).toHaveStyle('background-color: #1D1D1B');
expect(audioButton).toHaveStyle('color: #fff');

// Simulate clicking the play button again
// Click to play again
fireEvent.click(audioButton);

expect(getByText('Playing')).toBeInTheDocument();
});

test('shows AudioPlayer when audio is played', () => {
const { getByTestId, queryByTestId, container } = render(
<ArticleAudio audioSrc="https://www.kozco.com/tech/LRMonoPhase4.mp3" />
);

// Trigger the 'loadedmetadata' event to set the duration
const audio = container.querySelector('audio') as HTMLAudioElement;
act(() => {
fireEvent.loadedMetadata(audio);
});

expect(queryByTestId('audio-player')).not.toBeInTheDocument();

const audioButton = getByTestId('audio-button');
fireEvent.click(audioButton);

expect(getByTestId('audio-player')).toBeInTheDocument();
});

test('updates audioState based on AudioPlayer callbacks', () => {
test('updates audioState via AudioPlayer callbacks', () => {
const { getByTestId, getByText, container } = render(
<ArticleAudio audioSrc="https://www.kozco.com/tech/LRMonoPhase4.mp3" />
);

// Trigger the 'loadedmetadata' event to set the duration
// Trigger the 'loadedmetadata' event
const audio = container.querySelector('audio') as HTMLAudioElement;
act(() => {
fireEvent.loadedMetadata(audio);
});

const audioButton = getByTestId('audio-button');
fireEvent.click(audioButton); // Start playing

expect(getByText('Playing')).toBeInTheDocument();
fireEvent.click(audioButton); // Play

const pauseButton = getByText('Pause');
fireEvent.click(pauseButton);

fireEvent.click(pauseButton); // Pause
expect(getByText('Paused')).toBeInTheDocument();

const playButton = getByText('Play');
fireEvent.click(playButton);

fireEvent.click(playButton); // Play again
expect(getByText('Playing')).toBeInTheDocument();

const endedButton = getByText('Ended');
fireEvent.click(endedButton);

fireEvent.click(endedButton); // Simulate end of playback
expect(getByText('Listen')).toBeInTheDocument();
});
});
test('hides AudioPlayer when close button is clicked', () => {
const { getByTestId, getByText, container } = render(
<ArticleAudio audioSrc="https://www.kozco.com/tech/LRMonoPhase4.mp3" />
);

// Trigger 'loadedmetadata' event to initialize duration
const audio = container.querySelector('audio') as HTMLAudioElement;
act(() => {
fireEvent.loadedMetadata(audio);
});

// Click the audio button to show the AudioPlayer
const audioButton = getByTestId('audio-button');
fireEvent.click(audioButton);

// Verify that the AudioPlayer is now visible
const audioPlayer = getByTestId('audioPlayerWrapper');
expect(audioPlayer).toHaveStyle('display: block');


// Simulate clicking the close button inside the AudioPlayer
const closeButton = getByText('Close');
fireEvent.click(closeButton);

// Verify that the AudioPlayer is hidden again
expect(audioPlayer).toHaveStyle('display: none');
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('AudioButton', () => {

expect(button).toHaveStyleRule('background-color', 'unset');
expect(button).toHaveStyleRule('border-radius', '0');
expect(button).toHaveStyleRule('padding', '7px 11px');
expect(button).toHaveStyleRule('padding', '6px 11px');
expect(button).toHaveStyleRule('border', '1px solid #333333');
expect(button).toHaveStyleRule('display', 'flex');
expect(button).toHaveStyleRule('align-items', 'center');
Expand Down
12 changes: 10 additions & 2 deletions packages/ts-components/src/components/article-audio/styles.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import styled from 'styled-components';
import { colours } from '@times-components/ts-styleguide';
import { colours, breakpoints } from '@times-components/ts-styleguide';

export const AudioDuration = styled.span`
display: none;

@media (min-width: ${breakpoints.small}px) {
display: block
}

`;
export const AudioButton = styled.button`
background-color: unset;
border-radius: 0;
padding: 7px 11px;
padding: 6px 11px;
border: 1px solid ${colours.functional.primary};
display: flex;
align-items: center;
Expand Down