mirror of
https://github.com/antebudimir/feishin.git
synced 2025-12-31 18:13:31 +00:00
feat: add semantic selectors for now-playing media (#1138)
* feat: add semantic selectors for now-playing media This change adds unique class names to the elements that display the currently playing media information. This makes it easier for extension developers to parse the DOM and understand what media is playing. The following classes have been added: - `media-player`: The main player container. - `player-cover-art`: The cover art of the playing track. - `song-title`: The title of the playing track. - `song-artist`: The artist of the playing track. - `song-album`: The album of the playing track. - `player-state-playing`/`player-state-paused`: The state of the player. - `elapsed-time`: The elapsed time of the playing track. - `total-duration`: The total duration of the playing track. --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit is contained in:
parent
55e35e9b24
commit
8a3edb71df
5 changed files with 54 additions and 7 deletions
|
|
@ -28,6 +28,7 @@ import {
|
|||
} from '/@/renderer/store/settings.store';
|
||||
import { Icon } from '/@/shared/components/icon/icon';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
import { PlaybackSelectors } from '/@/shared/constants/playback-selectors';
|
||||
import { PlaybackType, PlayerRepeat, PlayerShuffle, PlayerStatus } from '/@/shared/types/types';
|
||||
|
||||
interface CenterControlsProps {
|
||||
|
|
@ -253,7 +254,13 @@ export const CenterControls = ({ playersRef }: CenterControlsProps) => {
|
|||
</div>
|
||||
<div className={styles.sliderContainer}>
|
||||
<div className={styles.sliderValueWrapper}>
|
||||
<Text fw={600} isMuted isNoSelect size="xs">
|
||||
<Text
|
||||
className={PlaybackSelectors.elapsedTime}
|
||||
fw={600}
|
||||
isMuted
|
||||
isNoSelect
|
||||
size="xs"
|
||||
>
|
||||
{formattedTime}
|
||||
</Text>
|
||||
</div>
|
||||
|
|
@ -281,7 +288,13 @@ export const CenterControls = ({ playersRef }: CenterControlsProps) => {
|
|||
/>
|
||||
</div>
|
||||
<div className={styles.sliderValueWrapper}>
|
||||
<Text fw={600} isMuted isNoSelect size="xs">
|
||||
<Text
|
||||
className={PlaybackSelectors.totalDuration}
|
||||
fw={600}
|
||||
isMuted
|
||||
isNoSelect
|
||||
size="xs"
|
||||
>
|
||||
{duration}
|
||||
</Text>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import { Image } from '/@/shared/components/image/image';
|
|||
import { Separator } from '/@/shared/components/separator/separator';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
import { Tooltip } from '/@/shared/components/tooltip/tooltip';
|
||||
import { PlaybackSelectors } from '/@/shared/constants/playback-selectors';
|
||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
||||
|
||||
export const LeftControls = () => {
|
||||
|
|
@ -104,7 +105,10 @@ export const LeftControls = () => {
|
|||
openDelay={500}
|
||||
>
|
||||
<Image
|
||||
className={styles.playerbarImage}
|
||||
className={clsx(
|
||||
styles.playerbarImage,
|
||||
PlaybackSelectors.playerCoverArt,
|
||||
)}
|
||||
loading="eager"
|
||||
src={currentSong?.imageUrl ?? ''}
|
||||
/>
|
||||
|
|
@ -139,6 +143,7 @@ export const LeftControls = () => {
|
|||
<div className={styles.lineItem} onClick={stopPropagation}>
|
||||
<Group align="center" gap="xs" wrap="nowrap">
|
||||
<Text
|
||||
className={PlaybackSelectors.songTitle}
|
||||
component={Link}
|
||||
fw={500}
|
||||
isLink
|
||||
|
|
@ -164,7 +169,11 @@ export const LeftControls = () => {
|
|||
</Group>
|
||||
</div>
|
||||
<div
|
||||
className={clsx(styles.lineItem, styles.secondary)}
|
||||
className={clsx(
|
||||
styles.lineItem,
|
||||
styles.secondary,
|
||||
PlaybackSelectors.songArtist,
|
||||
)}
|
||||
onClick={stopPropagation}
|
||||
>
|
||||
{artists?.map((artist, index) => (
|
||||
|
|
@ -190,7 +199,11 @@ export const LeftControls = () => {
|
|||
))}
|
||||
</div>
|
||||
<div
|
||||
className={clsx(styles.lineItem, styles.secondary)}
|
||||
className={clsx(
|
||||
styles.lineItem,
|
||||
styles.secondary,
|
||||
PlaybackSelectors.songAlbum,
|
||||
)}
|
||||
onClick={stopPropagation}
|
||||
>
|
||||
<Text
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import styles from './player-button.module.css';
|
|||
|
||||
import { ActionIcon, ActionIconProps } from '/@/shared/components/action-icon/action-icon';
|
||||
import { Tooltip, TooltipProps } from '/@/shared/components/tooltip/tooltip';
|
||||
import { PlaybackSelectors } from '/@/shared/constants/playback-selectors';
|
||||
|
||||
interface PlayerButtonProps extends Omit<ActionIconProps, 'icon' | 'variant'> {
|
||||
icon: ReactNode;
|
||||
|
|
@ -62,9 +63,13 @@ interface PlayButtonProps extends Omit<ActionIconProps, 'icon' | 'variant'> {
|
|||
|
||||
export const PlayButton = forwardRef<HTMLButtonElement, PlayButtonProps>(
|
||||
({ isPaused, onClick, ...props }: PlayButtonProps, ref) => {
|
||||
const playerStateClass = isPaused
|
||||
? PlaybackSelectors.playerStatePaused
|
||||
: PlaybackSelectors.playerStatePlaying;
|
||||
|
||||
return (
|
||||
<ActionIcon
|
||||
className={styles.main}
|
||||
className={clsx(styles.main, playerStateClass)}
|
||||
icon={isPaused ? 'mediaPlay' : 'mediaPause'}
|
||||
iconProps={{
|
||||
size: 'lg',
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import clsx from 'clsx';
|
||||
import { MouseEvent, useCallback } from 'react';
|
||||
|
||||
import styles from './playerbar.module.css';
|
||||
|
|
@ -25,6 +26,7 @@ import {
|
|||
usePlaybackType,
|
||||
useSettingsStore,
|
||||
} from '/@/renderer/store/settings.store';
|
||||
import { PlaybackSelectors } from '/@/shared/constants/playback-selectors';
|
||||
import { PlaybackType } from '/@/shared/types/types';
|
||||
|
||||
export const Playerbar = () => {
|
||||
|
|
@ -56,7 +58,7 @@ export const Playerbar = () => {
|
|||
|
||||
return (
|
||||
<div
|
||||
className={styles.container}
|
||||
className={clsx(styles.container, PlaybackSelectors.mediaPlayer)}
|
||||
onClick={playerbarOpenDrawer ? handleToggleFullScreenPlayer : undefined}
|
||||
>
|
||||
<div className={styles.controlsGrid}>
|
||||
|
|
|
|||
14
src/shared/constants/playback-selectors.ts
Normal file
14
src/shared/constants/playback-selectors.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Defines the selectors used to identify playback-related elements in the UI.
|
||||
// Can be used by browser extensions for accessing meta data around currently playing media.
|
||||
|
||||
export const PlaybackSelectors = {
|
||||
elapsedTime: 'elapsed-time',
|
||||
mediaPlayer: 'media-player',
|
||||
playerCoverArt: 'player-cover-art',
|
||||
playerStatePaused: 'player-state-paused',
|
||||
playerStatePlaying: 'player-state-playing',
|
||||
songAlbum: 'song-album',
|
||||
songArtist: 'song-artist',
|
||||
songTitle: 'song-title',
|
||||
totalDuration: 'total-duration',
|
||||
} as const;
|
||||
Loading…
Add table
Add a link
Reference in a new issue