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

Add Music Player UI for Mobile Devices #2940

Open
wants to merge 74 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
c66c7aa
feat: Init Music Player
anshg1214 Jun 29, 2024
0d4a95b
feat: Replace dummy props with actual props
anshg1214 Jun 29, 2024
5412803
feat: Pass toggleRepeatMode as props
anshg1214 Jun 29, 2024
6cdd9dd
feat: Add Feedback buttons
anshg1214 Jul 6, 2024
f42d78d
feat: Add Animation for text-overflow
anshg1214 Jul 7, 2024
b5f61b4
feat: wait for image to load before calculating average color
anshg1214 Jul 14, 2024
51c3e01
feat: Change Background Color based on cover art
anshg1214 Jul 14, 2024
aa06b10
fix: Overflowed text not scrolling
anshg1214 Jul 14, 2024
3a1cff8
feat: Open MusicPlayer only if track playing
anshg1214 Jul 14, 2024
012e4da
style: Improve layout
anshg1214 Jul 18, 2024
7dee8ae
feat: Change Progress Bar text color based on background
anshg1214 Jul 18, 2024
e39d017
style: Improve spacing
anshg1214 Jul 18, 2024
9ce5688
feat: Add Cover Art Scrolling
anshg1214 Jul 18, 2024
a6a303d
refactor: cleanup
anshg1214 Jul 19, 2024
0434adb
feat: Add Fallback CoverArt
anshg1214 Jul 20, 2024
2b5bde7
fix: Progress Bar not working on mobile
anshg1214 Jul 20, 2024
37ef7fe
fix: landscape view
anshg1214 Jul 20, 2024
d860c00
fix: queue landscape view
anshg1214 Jul 20, 2024
e2e95d5
chore: Install framer-motion
anshg1214 Jul 21, 2024
cfea4fd
feat: Replace React Scrollable by Framer Motion
anshg1214 Jul 21, 2024
cae763b
fix: Listen being submitted multiple times
anshg1214 Jul 21, 2024
1c2b794
Merge branch 'brainzplayer-spa' of https://github.com/metabrainz/list…
anshg1214 Jul 29, 2024
1e9510b
fix: queue-list css
anshg1214 Jul 29, 2024
cbb50aa
Merge branch 'brainzplayer-spa' into add-music-player-ui
anshg1214 Aug 2, 2024
8f0838c
style: fix z-index
anshg1214 Aug 2, 2024
94f6c5b
refactor: cleanup
anshg1214 Aug 2, 2024
aad2433
style: Update MusicPlayer transition
anshg1214 Aug 9, 2024
3d2a4cd
Revert "chore: Install framer-motion"
anshg1214 Aug 9, 2024
2b004f1
Revert "feat: Replace React Scrollable by Framer Motion"
anshg1214 Aug 9, 2024
9207a07
format: Lint CSS
anshg1214 Aug 9, 2024
3dcaec6
fix: MusicPlayer Cover Art Scroll
anshg1214 Aug 9, 2024
c7765b4
Merge branch 'brainzplayer-spa' into add-music-player-ui
anshg1214 Aug 9, 2024
d99a68b
fix: Tests
anshg1214 Aug 12, 2024
209d82c
fix: Mock IntersectionObserver to global
anshg1214 Aug 12, 2024
741c84f
fix: Intersection Observer mock
anshg1214 Aug 12, 2024
afa50cf
test: Add Intersection Observer mock
anshg1214 Aug 12, 2024
a80c5ca
Merge branch 'master' into add-music-player-ui
MonkeyDo Aug 13, 2024
f8ef5c1
Merge branch 'master' of https://github.com/metabrainz/listenbrainz-s…
anshg1214 Aug 27, 2024
e46d4ca
fix: Throttle playing next track
anshg1214 Aug 27, 2024
d385eda
test: mock scrollIntoView
anshg1214 Aug 27, 2024
7528b89
feat: Update comments
anshg1214 Aug 27, 2024
7927d07
feat: Add ENUM for FeedbackValue
anshg1214 Aug 27, 2024
80874c5
refactor: Cleanup
anshg1214 Aug 27, 2024
5e6dc4c
fix: Music Player Bottom overflowing
anshg1214 Aug 27, 2024
b4e7089
test: Add tests for music player
anshg1214 Aug 28, 2024
c30c585
Merge branch 'master' of https://github.com/metabrainz/listenbrainz-s…
anshg1214 Sep 4, 2024
fff1056
Merge branch 'master' of https://github.com/metabrainz/listenbrainz-s…
anshg1214 Oct 19, 2024
5623c27
Merge branch 'master' of https://github.com/metabrainz/listenbrainz-s…
anshg1214 Jan 30, 2025
5371844
refactor: Simplify MusicPlayer cover art rendering
anshg1214 Feb 6, 2025
b26c5f3
refactor: Improve mobile UI and responsiveness for BrainzPlayer
anshg1214 Feb 6, 2025
3dd0db5
refactor: lint
anshg1214 Feb 6, 2025
c01b966
Merge branch 'master' into add-music-player-ui
MonkeyDo Feb 19, 2025
c07dd90
Mobile player UI: Fix colors, small css tweaks
MonkeyDo Feb 19, 2025
099e21f
Move hook out of component
MonkeyDo Feb 19, 2025
618aff7
Add volume button and reorganize player buttons
MonkeyDo Feb 20, 2025
9bcd077
Keep like/dislike buttons the same size
MonkeyDo Feb 20, 2025
70d84c7
Fix test
MonkeyDo Feb 20, 2025
638f9c8
More player mobile UI tweaks
MonkeyDo Feb 21, 2025
116bac8
Refactor ProgressBar component
MonkeyDo Feb 21, 2025
d83a167
Move menuoptions to header of mobile player UI
MonkeyDo Feb 21, 2025
0303150
Fix progress bar stale closures
MonkeyDo Feb 21, 2025
da30d12
Improve mobile player UI flex layout
MonkeyDo Feb 21, 2025
8a32b4b
Merge branch 'master' into add-music-player-ui
MonkeyDo Feb 21, 2025
5c8b491
Mobile UI: change expand icon
MonkeyDo Feb 24, 2025
67775fd
Mobile UI: CSS tweaks
MonkeyDo Feb 24, 2025
32af458
Mobile UI: Improve color detection
MonkeyDo Feb 24, 2025
62ea8ea
Mobile UI: Show queue above player UI
MonkeyDo Feb 24, 2025
2c0132d
Mobile UI: More tweaks
MonkeyDo Feb 24, 2025
b1d452b
Mobile UI: Improve colors and animation
MonkeyDo Feb 24, 2025
8b3c161
Mobile UI: more colour work
MonkeyDo Feb 25, 2025
81eca75
Mobile UI: Fix colour hex string
MonkeyDo Feb 25, 2025
4f1ffd1
Mobile UI: Add custom color for progress bar
MonkeyDo Feb 25, 2025
dba1f9e
Mobile UI: Don't center progress/duration numbers
MonkeyDo Feb 25, 2025
96433c9
Mobile UI: Minimum animation duration + short delay
MonkeyDo Feb 25, 2025
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
224 changes: 189 additions & 35 deletions frontend/css/brainzplayer.less
Original file line number Diff line number Diff line change
Expand Up @@ -247,40 +247,6 @@
}
}

/** Progress **/
.progress {
position: absolute;
height: @progress-bar-height;
top: -@progress-bar-height;
margin-bottom: 0;
left: 0;
width: 100%;
cursor: pointer;
z-index: 5;
transition: height, 0.2s;

.progress-bar {
height: 100%;
background-color: @primary-color;
border-right: 2px solid @dark-color;
}
&:hover {
height: @progress-bar-hover-height;
top: -@progress-bar-hover-height;
}

.progress-tooltip {
background: @primary-color;
margin-top: -4px;
border-radius: 24px;
font-size: 1em;
padding: 6px 12px;
}
& > ::after {
border-color: transparent;
}
}

.no-album-art {
height: 100%;
background-image: url(../img/logo_big.svg);
Expand Down Expand Up @@ -341,14 +307,49 @@
}
}

#brainz-player .progress,
.music-player .progress {
position: absolute;
height: @progress-bar-height;
top: -@progress-bar-height;
margin-bottom: 0;
left: 0;
width: 100%;
cursor: pointer;
z-index: 5;
transition: height, 0.2s;

.progress-bar {
height: 100%;
background-color: @primary-color;
border-right: 2px solid @dark-color;
}
&:hover {
height: @progress-bar-hover-height;
top: -@progress-bar-hover-height;
}

.progress-tooltip {
background: @primary-color;
margin-top: -4px;
border-radius: 24px;
font-size: 1em;
padding: 6px 12px;
}
& > ::after {
border-color: transparent;
}
}

.queue {
position: fixed;
padding: 1em;
bottom: -100%;
bottom: calc(-100% - @brainzplayer-height - @progress-bar-height);
transition: bottom 1s ease-in-out;
width: 100%;
max-width: 550px;
height: 500px;
max-height: calc(100vh - @brainzplayer-height);
background-color: #f8f8f8;
border-top: 1px solid #ccc;
box-shadow: -6px -1px 10px rgba(0, 0, 0, 0.2);
Expand All @@ -372,6 +373,12 @@
margin-top: 0;
}

.queue-list > ul, li {
list-style: none;
padding: 0;
margin: 0;
}

.queue-item {
display: flex;
justify-content: space-between;
Expand Down Expand Up @@ -412,3 +419,150 @@
}
}
}

.music-player {
position: fixed;
z-index: 9997;
height: 100vh;
width: 100%;
display: flex;
flex-direction: column;
right: 0;
bottom: -100%;
transition: bottom 1s ease-in-out;
padding: 0 1.5em;
padding-bottom: @brainzplayer-height + @progress-bar-height;

&.open {
bottom: 0;
}

.cover-art-scroll-wrapper {
overflow-x: auto;
scroll-snap-stop: always;
scroll-snap-type: x mandatory;
scrollbar-width: none;
display: flex;
aspect-ratio: 1;
margin-top: auto;
margin-bottom: auto;

.cover-art-wrapper {
display: flex;
align-items: center;
justify-content: center;
scroll-snap-align: start;
scroll-snap-stop: always;
min-width: 100%;
margin: 0 0.5em;
}
}

.header,
.info {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 1em 0;
color: white;

.love,
.hate {
color: transparent;
stroke: white;
stroke-width: 1em;
}

.love {
&:hover {
stroke: @love-color;
}
&.loved {
stroke: transparent;
color: @love-color;
}
}

.hate {
&:hover {
stroke: @hate-color;
}
&.hated {
stroke: transparent;
color: @hate-color;
}
}

.info-text-wrapper {
flex: 1;
display: flex;
flex-direction: column;
overflow: auto;
}

.text-scroll-wrapper {
overflow: hidden;
white-space: nowrap;

span {
display: inline-block;
position: relative;

&.animate {
animation: leftright 6s infinite alternate ease-in-out;
}
}
}

span {
color: white;
}

.feedback-buttons-wrapper {
display: flex;
font-size: 2.3em;
gap: 0.75em;
padding-left: 0.25em;
}
}

.player-buttons {
display: flex;
align-items: center;
justify-content: space-between;
color: white;
margin-bottom: auto;

.play svg {
font-size: 4.25em !important;
}
}

.progress-bar-wrapper {
margin: 10px 0;

.progress {
position: inherit;
height: 10px;
background-color: rgba(255, 255, 255, 0.3);

.progress-bar {
background-color: white;
}
}
}
}

@keyframes leftright {
0%,
20% {
transform: translateX(0%);
left: 0%;
}
80%,
100% {
transform: translateX(-100%);
left: 100%;
}
}
5 changes: 3 additions & 2 deletions frontend/js/src/album/AlbumPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,9 @@ export default function AlbumPage(): JSX.Element {
});
React.useEffect(() => {
const setAverageColor = () => {
const averageColor = getAverageRGBOfImage(albumArtRef?.current);
setAlbumArtColor(averageColor);
getAverageRGBOfImage(albumArtRef?.current).then((averageColor) => {
setAlbumArtColor(averageColor);
});
};
const currentAlbumArtRef = albumArtRef.current;
if (currentAlbumArtRef) {
Expand Down
11 changes: 3 additions & 8 deletions frontend/js/src/common/brainzplayer/BrainzPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ export default function BrainzPlayer() {
queue,
ambientQueue,
queueRepeatMode,
currentTrackCoverURL,
} = useBrainzPlayerContext();

const dispatch = useBrainzPlayerDispatch();
Expand Down Expand Up @@ -679,14 +680,6 @@ export default function BrainzPlayer() {
}
}, [currentDataSourceIndex, dataSourceRefs, invalidateDataSource]);

const getCurrentTrackName = (): string => {
return getTrackName(currentListen);
};

const getCurrentTrackArtists = (): string | undefined => {
return getArtistName(currentListen);
};

const stopPlayerStateTimer = React.useCallback((): void => {
debouncedCheckProgressAndSubmitListen.flush();
if (playerStateTimerID.current) {
Expand Down Expand Up @@ -778,6 +771,7 @@ export default function BrainzPlayer() {
currentTrackArtist: artist!,
currentTrackAlbum: album,
currentTrackURL: trackURL,
currentTrackCoverURL: artwork?.[0]?.src,
},
() => {
updateWindowTitleWithTrackName();
Expand Down Expand Up @@ -963,6 +957,7 @@ export default function BrainzPlayer() {
dataSourceRefs[currentDataSourceIndex]?.current?.name
}
clearQueue={clearQueue}
currentTrackCoverURL={currentTrackCoverURL}
>
{userPreferences?.brainzplayer?.spotifyEnabled !== false && (
<SpotifyPlayer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export type BrainzPlayerContextT = {
currentTrackArtist?: string;
currentTrackAlbum?: string;
currentTrackURL?: string;
currentTrackCoverURL?: string;
playerPaused: boolean;
isActivated: boolean;
durationMs: number;
Expand Down
Loading