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 45 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 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
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
219 changes: 183 additions & 36 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 @@ -371,7 +372,6 @@
background: #dadada;
margin-top: 0;
}

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

.music-player {
position: fixed;
z-index: 108;
height: 100vh;
width: 100%;
display: flex;
flex-direction: column;
right: 0;
bottom: -100vh;
transition: bottom 0.6s cubic-bezier(0.46, 0.75, 0.55, 0.97);
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
3 changes: 3 additions & 0 deletions frontend/js/src/common/brainzplayer/BrainzPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ export default function BrainzPlayer() {
queue,
ambientQueue,
queueRepeatMode,
currentTrackCoverURL,
} = useBrainzPlayerContext();

const dispatch = useBrainzPlayerDispatch();
Expand Down Expand Up @@ -790,6 +791,7 @@ export default function BrainzPlayer() {
currentTrackArtist: artist!,
currentTrackAlbum: album,
currentTrackURL: trackURL,
currentTrackCoverURL: artwork?.[0]?.src,
},
() => {
updateWindowTitleWithTrackName();
Expand Down Expand Up @@ -996,6 +998,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 @@ -38,6 +38,7 @@ export type BrainzPlayerContextT = {
currentTrackArtist?: string;
currentTrackAlbum?: string;
currentTrackURL?: string;
currentTrackCoverURL?: string;
playerPaused: boolean;
isActivated: boolean;
durationMs: number;
Expand Down
Loading