From 0daafc8fcdea0b75044f0f852889c1ca2b6756d0 Mon Sep 17 00:00:00 2001 From: Ali Haghighatkhah Date: Fri, 18 Nov 2022 15:39:09 +0100 Subject: [PATCH 1/8] Add PR template --- pull_request_template.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 pull_request_template.md diff --git a/pull_request_template.md b/pull_request_template.md new file mode 100644 index 0000000..011687f --- /dev/null +++ b/pull_request_template.md @@ -0,0 +1,5 @@ +### Which issues does this PR address? + + + +### how did you resolve? From 023ecd0c065ee2a85264f77705b4858397f8a589 Mon Sep 17 00:00:00 2001 From: Ali Haghighatkhah Date: Fri, 18 Nov 2022 15:42:07 +0100 Subject: [PATCH 2/8] Split context modules --- app/components/Entity/EntityRow/Wrapper.tsx | 6 +- app/components/MainMenu/index.tsx | 2 +- app/components/Player/type.ts | 3 +- .../playerContext/playerContextProvider.tsx | 42 ++++++++++ app/context/playerContext/types.ts | 20 +++++ app/context/playerContextProvider.tsx | 76 ------------------- .../profileContextProvider.tsx | 0 app/context/profileContext/types.ts | 17 +++++ .../settingsContextProvider.tsx | 2 +- app/context/settingsContext/types.ts | 13 ++++ app/context/types.ts | 53 ------------- app/routes/__main.tsx | 6 +- app/routes/__main/agreement/index.tsx | 2 +- app/routes/__main/login/index.tsx | 4 +- 14 files changed, 105 insertions(+), 141 deletions(-) create mode 100644 app/context/playerContext/playerContextProvider.tsx create mode 100644 app/context/playerContext/types.ts delete mode 100644 app/context/playerContextProvider.tsx rename app/context/{ => profileContext}/profileContextProvider.tsx (100%) create mode 100644 app/context/profileContext/types.ts rename app/context/{ => settingsContext}/settingsContextProvider.tsx (98%) create mode 100644 app/context/settingsContext/types.ts delete mode 100644 app/context/types.ts diff --git a/app/components/Entity/EntityRow/Wrapper.tsx b/app/components/Entity/EntityRow/Wrapper.tsx index 6922292..979588b 100644 --- a/app/components/Entity/EntityRow/Wrapper.tsx +++ b/app/components/Entity/EntityRow/Wrapper.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { memo, ReactNode, MouseEvent, useContext } from 'react'; -import { PlayerContext } from '~/context/playerContextProvider'; +import { PlayerContext } from '~/context/playerContext/playerContextProvider'; import { Link } from '@remix-run/react'; import { Entity, TrackType } from '../types'; @@ -14,7 +14,7 @@ interface WrapperProps { const Wrapper = ({ entity, data, children, className, }: WrapperProps) => { - const { setCurrent, current } = useContext(PlayerContext); + const { setCurrent } = useContext(PlayerContext); if (entity === 'track') { const play = (e: MouseEvent) => { @@ -27,7 +27,7 @@ const Wrapper = ({ return (
{children}
diff --git a/app/components/MainMenu/index.tsx b/app/components/MainMenu/index.tsx index 79304ad..f7f18d5 100644 --- a/app/components/MainMenu/index.tsx +++ b/app/components/MainMenu/index.tsx @@ -2,7 +2,7 @@ import React, { useState, useContext } from 'react'; import { IconLink } from '~/components/common/Link'; import { IconButton } from '~/components/common/Button'; -import { ProfileContext } from '~/context/profileContextProvider'; +import { ProfileContext } from '~/context/profileContext/profileContextProvider'; const MainMenu = () => { const [isActive, setIsActive] = useState(false); diff --git a/app/components/Player/type.ts b/app/components/Player/type.ts index df6dd8c..30716a8 100644 --- a/app/components/Player/type.ts +++ b/app/components/Player/type.ts @@ -1,4 +1,5 @@ export type ProgressBarProps = { duration: number; - currentTime: number; + progress: number; + setProgress: (progress: number) => void; }; diff --git a/app/context/playerContext/playerContextProvider.tsx b/app/context/playerContext/playerContextProvider.tsx new file mode 100644 index 0000000..d5b7a34 --- /dev/null +++ b/app/context/playerContext/playerContextProvider.tsx @@ -0,0 +1,42 @@ +import React, { useState, createContext, useEffect } from 'react'; +import { PlayerContextType, PlayerProviderProps, PlayerState, Current } from './types'; +import useLocalStorage from '~/hooks/useLocalStorage'; +import { TrackType } from '~/components/Entity/types'; + +export const PlayerContext = createContext({ + current: null, + isPlaying: false, + setIsPlaying: (state: boolean) => { console.log('Methods are not ready.', state); }, + setCurrent: (data: Current) => { console.log('Methods are not ready.', data); }, +}); + +const PlayerProvider = ({ children }: PlayerProviderProps) => { + const [storedState, setStoredState] = useLocalStorage('playerState', { + current: null, + isPlaying: false, + }); + const [current, setCurrent] = useState(storedState.current); + const [isPlaying, setIsPlaying] = useState(storedState.isPlaying); + + useEffect(() => { + setStoredState({ + current, + isPlaying: false, + }); + }, [current]); + + const value = { + current, + isPlaying, + setIsPlaying, + setCurrent, + }; + + return ( + + {children} + + ); +}; + +export default PlayerProvider; diff --git a/app/context/playerContext/types.ts b/app/context/playerContext/types.ts new file mode 100644 index 0000000..3c1405b --- /dev/null +++ b/app/context/playerContext/types.ts @@ -0,0 +1,20 @@ +import { ReactElement } from 'react'; +import { TrackType } from '../../components/Entity/types'; + +export type Current = TrackType|null; + +export interface PlayerContextType { + current:Current; + isPlaying: boolean; + setIsPlaying: (state: boolean) => void; + setCurrent: (track: Current) => void; +} + +export interface PlayerProviderProps { + children: ReactElement; +} + +export interface PlayerState { + current: Current; + isPlaying: boolean; +} diff --git a/app/context/playerContextProvider.tsx b/app/context/playerContextProvider.tsx deleted file mode 100644 index 17d2549..0000000 --- a/app/context/playerContextProvider.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import React, { useState, createContext, MouseEvent, useEffect } from 'react'; -import { PlayerContextType, PlayerProviderProps, PlayerState, Current } from './types'; -import useLocalStorage from '~/hooks/useLocalStorage'; -import { TrackType } from '~/components/Entity/types'; - -export const PlayerContext = createContext({ - current: null, - queue: [], - isPlaying: false, - setIsPlaying: (state: boolean) => { console.log('Methods are not ready.', state); }, - setCurrent: (data: Current) => { console.log('Methods are not ready.', data); }, - addToQueue: (track: TrackType) => { console.log('Methods are not ready.', track); }, - removeFromQueue: (track: TrackType) => { console.log('Methods are not ready.', track); }, - prevTrack: (e: MouseEvent) => { console.log('Methods are not ready.', e); }, - nextTrack: (e: MouseEvent) => { console.log('Methods are not ready.', e); }, -}); - -const PlayerProvider = ({ children }: PlayerProviderProps) => { - const [storedQueue, setStoredQueue] = useLocalStorage('playerState', { - current: null, - queue: [], - }); - const [current, setCurrent] = useState(); - const [queue, setQueue] = useState([]); - const [isPlaying, setIsPlaying] = useState(false); - - const addToQueue = (track: TrackType) => { - setQueue([...queue, track]); - }; - - const removeFromQueue = (track: TrackType) => { - const newQueue = queue.filter((t) => t.id !== track.id); - setQueue(newQueue); - }; - - const nextTrack = (e: MouseEvent) => { - e.preventDefault(); - const next = queue[0]; - setCurrent(next); - removeFromQueue(next); - }; - - const prevTrack = (e: MouseEvent) => { - e.preventDefault(); - const prev = queue[queue.length - 1]; - setCurrent(prev); - removeFromQueue(prev); - }; - - useEffect(() => { - setStoredQueue({ - current, - queue, - }); - }, [current, queue]); - - const value = { - current, - queue, - isPlaying, - setIsPlaying, - setCurrent, - addToQueue, - removeFromQueue, - prevTrack, - nextTrack, - }; - - return ( - - {children} - - ); -}; - -export default PlayerProvider; diff --git a/app/context/profileContextProvider.tsx b/app/context/profileContext/profileContextProvider.tsx similarity index 100% rename from app/context/profileContextProvider.tsx rename to app/context/profileContext/profileContextProvider.tsx diff --git a/app/context/profileContext/types.ts b/app/context/profileContext/types.ts new file mode 100644 index 0000000..a43d76e --- /dev/null +++ b/app/context/profileContext/types.ts @@ -0,0 +1,17 @@ +import { ReactElement } from 'react'; + +export interface ProfileInfoType { + address: string; + publicKey: string; +} + +export interface ProfileContextType { + info: ProfileInfoType; + secretKey: string; + setProfileInfo: (data: ProfileInfoType) => void; + setSecretKey: (data: string) => void; +} + +export interface ProfileProviderProps { + children: ReactElement; +} diff --git a/app/context/settingsContextProvider.tsx b/app/context/settingsContext/settingsContextProvider.tsx similarity index 98% rename from app/context/settingsContextProvider.tsx rename to app/context/settingsContext/settingsContextProvider.tsx index 1b0188b..ad36f38 100644 --- a/app/context/settingsContextProvider.tsx +++ b/app/context/settingsContext/settingsContextProvider.tsx @@ -3,7 +3,7 @@ import React, { useState, createContext } from 'react'; /* Internal dependencies */ import { useStorage } from '~/hooks/useStorage'; -import { SettingsType, SettingsContextType, SettingsProviderProps } from './types'; +import { SettingsType, SettingsContextType, SettingsProviderProps } from '../types'; export const SettingsContext = createContext({ settings: { diff --git a/app/context/settingsContext/types.ts b/app/context/settingsContext/types.ts new file mode 100644 index 0000000..a32a113 --- /dev/null +++ b/app/context/settingsContext/types.ts @@ -0,0 +1,13 @@ +import { ReactElement } from 'react'; + +export interface SettingsType { + theme: string; + agreement: boolean; +} +export interface SettingsContextType { + settings: SettingsType; + updateSettings: (data: SettingsType) => void; +} +export interface SettingsProviderProps { + children: ReactElement; +} diff --git a/app/context/types.ts b/app/context/types.ts deleted file mode 100644 index 6e11481..0000000 --- a/app/context/types.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { ReactElement, MouseEvent } from 'react'; -import { TrackType } from '../components/Entity/types'; - -export interface PlayerContextType { - current: TrackType|null; - queue: TrackType[]; - isPlaying: boolean; - setIsPlaying: (state: boolean) => void; - setCurrent: (track: TrackType|null) => void; - addToQueue: (track: TrackType) => void; - removeFromQueue: (track: TrackType) => void; - prevTrack: (e: MouseEvent) => void; - nextTrack: (e: MouseEvent) => void; -} - -export interface PlayerProviderProps { - children: ReactElement; -} - -export interface PlayerState { - current: TrackType|null; - queue: TrackType[]; -} - -export interface ProfileInfoType { - address: string; - publicKey: string; -} - -export interface ProfileContextType { - info: ProfileInfoType; - secretKey: string; - setProfileInfo: (data: ProfileInfoType) => void; - setSecretKey: (data: string) => void; -} - -export interface ProfileProviderProps { - children: ReactElement; -} - -export interface SettingsType { - theme: string; - agreement: boolean; -} - -export interface SettingsContextType { - settings: SettingsType; - updateSettings: (data: SettingsType) => void; -} - -export interface SettingsProviderProps { - children: ReactElement; -} diff --git a/app/routes/__main.tsx b/app/routes/__main.tsx index f95bdcb..8ca74dd 100644 --- a/app/routes/__main.tsx +++ b/app/routes/__main.tsx @@ -3,9 +3,9 @@ import React from 'react'; import { Outlet } from '@remix-run/react'; /* Internal dependencies */ -import PlayerProvider from '~/context/playerContextProvider'; -import ProfileProvider from '~/context/profileContextProvider'; -import SettingsProvider from '~/context/settingsContextProvider'; +import PlayerProvider from '~/context/playerContext/playerContextProvider'; +import ProfileProvider from '~/context/profileContext/profileContextProvider'; +import SettingsProvider from '~/context/settingsContext/settingsContextProvider'; import MainMenu from '~/components/MainMenu'; import Player from '~/components/Player'; import styles from '~/styles/routes/__main.css'; diff --git a/app/routes/__main/agreement/index.tsx b/app/routes/__main/agreement/index.tsx index 2d52211..b65a628 100644 --- a/app/routes/__main/agreement/index.tsx +++ b/app/routes/__main/agreement/index.tsx @@ -3,7 +3,7 @@ import React, { useState, ChangeEvent, useContext } from 'react'; import { useNavigate } from 'react-router-dom'; /* Internal dependencies */ -import { SettingsContext } from '~/context/settingsContextProvider'; +import { SettingsContext } from '~/context/settingsContext/settingsContextProvider'; import { PrimaryButton } from '~/components/common/Button'; import { Checkbox } from '~/components/common/Checkbox'; import { PartialView } from '~/components/PartialView'; diff --git a/app/routes/__main/login/index.tsx b/app/routes/__main/login/index.tsx index 939b9d8..45df200 100644 --- a/app/routes/__main/login/index.tsx +++ b/app/routes/__main/login/index.tsx @@ -5,8 +5,8 @@ import { useNavigate } from 'react-router-dom'; /* Internal dependencies */ import { defaultDerivationPath } from '~/constants/app'; -import { ProfileContext } from '~/context/profileContextProvider'; -import { SettingsContext } from '~/context/settingsContextProvider'; +import { ProfileContext } from '~/context/profileContext/profileContextProvider'; +import { SettingsContext } from '~/context/settingsContext/settingsContextProvider'; import { PrimaryButton } from '~/components/common/Button'; import { PartialView } from '~/components/PartialView'; import SecretKeyInput from '~/components/SecretKeyInput'; From e199ce1e750e401ea685eb52a68ad9d0f80967be Mon Sep 17 00:00:00 2001 From: Ali Haghighatkhah Date: Fri, 18 Nov 2022 15:44:01 +0100 Subject: [PATCH 3/8] Simplify the player --- app/components/Player/ProgressBar.tsx | 31 +++++++--- app/components/Player/index.tsx | 88 ++++++++++----------------- app/components/Player/player.css | 49 ++++++--------- app/constants/api.ts | 2 +- styles/variables.css | 1 + 5 files changed, 76 insertions(+), 95 deletions(-) diff --git a/app/components/Player/ProgressBar.tsx b/app/components/Player/ProgressBar.tsx index 3ff2e99..1a80af3 100644 --- a/app/components/Player/ProgressBar.tsx +++ b/app/components/Player/ProgressBar.tsx @@ -1,6 +1,11 @@ -import React from 'react'; +import React, { ChangeEvent } from 'react'; import { ProgressBarProps } from './type'; +const range = { + max: 100, + min: 0, +}; + const zeroPad = (num: number) => num.toString().padStart(2, '0'); const formatCurrentTime = (currentTime: number) => { @@ -14,18 +19,26 @@ const formatCurrentTime = (currentTime: number) => { }; const updateProgress = (currentTime: number, duration: number) => - duration > 0 ? `${(currentTime / duration) * 100}%` : '0%'; + duration > 0 ? 100 * currentTime / duration : 0; + +const ProgressBar = ({ progress, duration, setProgress }: ProgressBarProps) => { + const percentage = updateProgress(progress, duration); + + const onSeek = (e: ChangeEvent) => { + setProgress(e.target.value * duration / range.max); + }; -const ProgressBar = ({ currentTime, duration }: ProgressBarProps) => { - const percentage = updateProgress(currentTime, duration); return (
-
- - -
+
); diff --git a/app/components/Player/index.tsx b/app/components/Player/index.tsx index f9930af..7a9ba4e 100644 --- a/app/components/Player/index.tsx +++ b/app/components/Player/index.tsx @@ -1,7 +1,12 @@ -import React, { useEffect, useRef, useState } from 'react'; -import { useContext, MouseEvent } from 'react'; +import React, { + useEffect, + useRef, + useState, + useContext, + MutableRefObject, +} from 'react'; import { Link } from '@remix-run/react'; -import { PlayerContext } from '~/context/playerContextProvider'; +import { PlayerContext } from '~/context/playerContext/playerContextProvider'; import { IconButton } from '~/components/common/Button'; import EntityThumbnail from '~/components/Entity/EntityThumbnail'; import { API_URLS } from '~/constants/api'; @@ -10,93 +15,64 @@ import ProgressBar from './ProgressBar'; const Player = () => { const { current, - queue, isPlaying, setIsPlaying, - prevTrack, - nextTrack, } = useContext(PlayerContext); - const [init, setInit] = useState(false); - const [currentTime, setCurrentTime] = useState(0); - const audio = useRef(); + const audioRef = useRef() as MutableRefObject; + const [progress, setProgress] = useState(0); - const updateProgress = () => { - setCurrentTime(audio.current.currentTime); - }; - - const playPause = (e: MouseEvent) => { - e.preventDefault(); - if (!audio.current) { - console.log('No music is selected yet.'); + const playPause = () => { + if (isPlaying) { + audioRef.current.pause(); } else { - if (audio.current.paused) { - audio.current.play(); - } else { - audio.current.pause(); - } - setIsPlaying(!audio.current.paused); + audioRef.current.play(); } + setIsPlaying(!isPlaying); }; - useEffect(() => { - if (init) { - audio.current.play(); - setIsPlaying(true); - } - }, [current?.id]); + const onTimeUpdate = () => { + setProgress(audioRef.current.currentTime); + }; useEffect(() => { - audio.current.addEventListener('timeupdate', updateProgress); - setInit(true); - }, [audio.current]); - - useEffect(() => () => { - audio.current.removeEventListener('timeupdate', updateProgress); - }, []); + if (progress !== audioRef.current.currentTime) { + if (Math.abs(Math.round(progress) - Math.round(audioRef.current.currentTime)) > 2) { + audioRef.current.currentTime = progress; + } + } + }, [progress]); return (
{ - current && ( - + current?.id && ( + ) }
-
{ current?.name ?? '-' }
- { current?.artistName ?? '-' } +
{ current?.name ?? '...' }
+ { current?.artistName ?? '...' }
-
); diff --git a/app/components/Player/player.css b/app/components/Player/player.css index 0b092b7..ec66ae8 100644 --- a/app/components/Player/player.css +++ b/app/components/Player/player.css @@ -93,36 +93,30 @@ box-sizing: border-box; align-items: center; - & .bar { - display: block; + & input { flex-grow: 1; - background: #777; - height: 5px; - border-radius: var(--border-radius-s); - position: relative; - - & i, - & span { - content: ''; - display: block; - background: linear-gradient(90deg, rgba(179,189,253,1) 0%, rgba(238,180,205,1) 50%, rgba(232,135,251,1) 100%); - } - - & span { - height: 100%; - width: 0%; - border-radius: var(--border-radius-s); + -moz-appearance: none; + -webkit-appearance: none; + -ms-progress-appearance: none; + appearance: none; + background: var(--black); + height: 6px; + border-radius: 3px; + + &::focus { + outline: none; } - & i { - width: 14px; - height: 14px; - position: absolute; - left: 0%; - border-radius: var(--border-radius-r); - top: 3px; - transform: translateX(-50%) translateY(-50%); + &::-webkit-slider-thumb { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: 16px; + height: 16px; + border-radius: 4px; + background: var(--black); cursor: pointer; + box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.25); } } @@ -134,9 +128,6 @@ } } - - - @media (min-width: 680px) { .component.player { /* & .controls { diff --git a/app/constants/api.ts b/app/constants/api.ts index f4e9811..8e33712 100644 --- a/app/constants/api.ts +++ b/app/constants/api.ts @@ -1,5 +1,5 @@ export const API_URLS = { - STREAMER: 'http://localhost:4000/songs', + STREAMER: 'http://localhost:4000/audio', SERVICE: 'http://localhost:2621', }; diff --git a/styles/variables.css b/styles/variables.css index e4b6e8b..42e7bfb 100644 --- a/styles/variables.css +++ b/styles/variables.css @@ -6,6 +6,7 @@ --color-primary: #feeae3; --color-primary-light: #fef2ee; --color-secondary: #453248; + --black: #000000; --color-purple: #a755af; --color-primary-see-through: rgba(19, 14, 29, 0.7); --color-primary-shadow: rgba(19, 14, 29, 0.2); From 4e35107aec2b5b9a7e0eb56192556941f1c2c397 Mon Sep 17 00:00:00 2001 From: Ali Haghighatkhah Date: Sat, 19 Nov 2022 01:04:15 +0100 Subject: [PATCH 4/8] Move audio player logic to a hook --- app/components/Player/index.tsx | 54 +++++++++------------------------ app/hooks/useAudio.ts | 52 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 39 deletions(-) create mode 100644 app/hooks/useAudio.ts diff --git a/app/components/Player/index.tsx b/app/components/Player/index.tsx index 7a9ba4e..db109b4 100644 --- a/app/components/Player/index.tsx +++ b/app/components/Player/index.tsx @@ -1,57 +1,33 @@ -import React, { - useEffect, - useRef, - useState, - useContext, - MutableRefObject, -} from 'react'; +import React, { useContext } from 'react'; import { Link } from '@remix-run/react'; +import { useAudio } from '~/hooks/useAudio'; import { PlayerContext } from '~/context/playerContext/playerContextProvider'; +import { ProfileContext } from '~/context/profileContext/profileContextProvider'; import { IconButton } from '~/components/common/Button'; import EntityThumbnail from '~/components/Entity/EntityThumbnail'; import { API_URLS } from '~/constants/api'; import ProgressBar from './ProgressBar'; const Player = () => { + const { + audioRef, + playPause, + onTimeUpdate, + progress, + setProgress, + } = useAudio(); const { current, isPlaying, - setIsPlaying, } = useContext(PlayerContext); - const audioRef = useRef() as MutableRefObject; - const [progress, setProgress] = useState(0); - - const playPause = () => { - if (isPlaying) { - audioRef.current.pause(); - } else { - audioRef.current.play(); - } - setIsPlaying(!isPlaying); - }; - - const onTimeUpdate = () => { - setProgress(audioRef.current.currentTime); - }; - - useEffect(() => { - if (progress !== audioRef.current.currentTime) { - if (Math.abs(Math.round(progress) - Math.round(audioRef.current.currentTime)) > 2) { - audioRef.current.currentTime = progress; - } - } - }, [progress]); + const { info } = useContext(ProfileContext); return ( -
+
- { - current?.id && ( - - - - ) - } + + { current && } +
{ current?.name ?? '...' }
{ current?.artistName ?? '...' } diff --git a/app/hooks/useAudio.ts b/app/hooks/useAudio.ts new file mode 100644 index 0000000..51b1476 --- /dev/null +++ b/app/hooks/useAudio.ts @@ -0,0 +1,52 @@ +import { + useEffect, + useState, + useRef, + MutableRefObject, + useContext, +} from 'react'; +import { PlayerContext } from '~/context/playerContext/playerContextProvider'; + +export const useAudio = () => { + const { + isPlaying, + setIsPlaying, + } = useContext(PlayerContext); + const audioRef = useRef() as MutableRefObject; + const [progress, setProgress] = useState(0); + + const playPause = () => { + if (isPlaying) { + audioRef.current.pause(); + } else { + audioRef.current.play(); + } + setIsPlaying(!isPlaying); + }; + + const onTimeUpdate = () => { + setProgress(audioRef.current.currentTime); + }; + + useEffect(() => { + const timeDiff = Math.abs(Math.round(progress) - Math.round(audioRef.current.currentTime)); + if (progress !== audioRef.current.currentTime && timeDiff > 2) { + audioRef.current.currentTime = progress; + } + }, [progress]); + + useEffect(() => { + audioRef.current.addEventListener('ended', () => setIsPlaying(false)); + return () => { + audioRef.current.removeEventListener('ended', () => setIsPlaying(false)); + }; + }, []); + + return { + audioRef, + playPause, + onTimeUpdate, + progress, + setProgress, + }; +}; From 261855dc63de09059bb7991781ba9659dbd6531b Mon Sep 17 00:00:00 2001 From: Ali Haghighatkhah Date: Sat, 19 Nov 2022 01:04:40 +0100 Subject: [PATCH 5/8] Minor cleanups --- .../Entity/EntityThumbnail/entityThumbnail.css | 11 ++++++----- app/components/Entity/EntityThumbnail/index.tsx | 4 ++-- app/components/Summary/AlbumSummary/index.tsx | 1 - app/helpers/helpers.ts | 5 +++-- app/routes/__main/album/$id.tsx | 2 +- styles/variables.css | 1 + 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/app/components/Entity/EntityThumbnail/entityThumbnail.css b/app/components/Entity/EntityThumbnail/entityThumbnail.css index 0812a20..ba76ced 100644 --- a/app/components/Entity/EntityThumbnail/entityThumbnail.css +++ b/app/components/Entity/EntityThumbnail/entityThumbnail.css @@ -1,4 +1,5 @@ .component.entity.thumbnail { + --size-xs: 59px; --size-s: 62px; --size-m: 70px; --size-l: 80px; @@ -42,20 +43,20 @@ } } + &.empty, &.artist { & figure { border-radius: var(--border-radius-xs); } } -} -.circle { - &.component.entity.thumbnail { + &.track { & figure { - width: 59px; - height: 59px; + width: var(--size-xs); + height: var(--size-xs); border-radius: var(--border-radius-r); border: solid 2px var(--white); + box-shadow: 0 8px 8px 0 var(--color-primary-opaque); } } } diff --git a/app/components/Entity/EntityThumbnail/index.tsx b/app/components/Entity/EntityThumbnail/index.tsx index 2fc26ee..2634cf0 100644 --- a/app/components/Entity/EntityThumbnail/index.tsx +++ b/app/components/Entity/EntityThumbnail/index.tsx @@ -6,13 +6,13 @@ const EntityThumbnail = ({ data, className = '', theme = entityThemes.normal, }: EntityRowProps) => { - const entity = getEntity(data); + const entity = data ? getEntity(data) : 'empty'; const wrapper = `component entity thumbnail ${entity} ${theme} ${className}`; return (
- { + {data?.name
); diff --git a/app/components/Summary/AlbumSummary/index.tsx b/app/components/Summary/AlbumSummary/index.tsx index 2b2de5e..5645fd6 100644 --- a/app/components/Summary/AlbumSummary/index.tsx +++ b/app/components/Summary/AlbumSummary/index.tsx @@ -10,7 +10,6 @@ const AlbumSummary = ({ data }: EntityRowProps) => {

{ data.name }

- {/* @todo Removed a anchor from here. Are the styles ok? */}
{data.artistName}
diff --git a/app/helpers/helpers.ts b/app/helpers/helpers.ts index 80f730f..9babebc 100644 --- a/app/helpers/helpers.ts +++ b/app/helpers/helpers.ts @@ -1,5 +1,6 @@ -export const greet = (timestamp: number) => { - const hour = new Date(timestamp).getHours(); +export const greet = (timestamp = 0) => { + const date = timestamp ? new Date(timestamp) : new Date(); + const hour = date.getHours(); if (hour < 12) { return 'Good morning'; } diff --git a/app/routes/__main/album/$id.tsx b/app/routes/__main/album/$id.tsx index bac36a3..cf7bd3c 100644 --- a/app/routes/__main/album/$id.tsx +++ b/app/routes/__main/album/$id.tsx @@ -40,7 +40,7 @@ const Album = () => { return (
{ - + album && } Date: Sat, 19 Nov 2022 10:37:30 +0100 Subject: [PATCH 6/8] Fix header styles --- .../Entity/EntityThumbnail/index.tsx | 5 ++-- app/components/Logo/Extended.tsx | 2 +- app/components/MainHeader/index.tsx | 23 +++++++++++++++++++ app/components/MainHeader/mainHeader.css | 22 ++++++++++++++++++ app/components/MainMenu/mainMenu.css | 3 --- app/components/Player/PlaceHolderImage.tsx | 7 ++++++ app/components/Player/index.tsx | 9 +++++++- app/components/Player/player.css | 7 ++++++ app/routes/__main.tsx | 4 ++-- app/routes/__main/index/index.tsx | 6 ----- app/routes/__main/search/index.tsx | 4 ---- styles/routes/__main/search.css | 6 +---- 12 files changed, 74 insertions(+), 24 deletions(-) create mode 100644 app/components/MainHeader/index.tsx create mode 100644 app/components/MainHeader/mainHeader.css create mode 100644 app/components/Player/PlaceHolderImage.tsx diff --git a/app/components/Entity/EntityThumbnail/index.tsx b/app/components/Entity/EntityThumbnail/index.tsx index 2634cf0..934d840 100644 --- a/app/components/Entity/EntityThumbnail/index.tsx +++ b/app/components/Entity/EntityThumbnail/index.tsx @@ -1,4 +1,5 @@ import React from 'react'; + import { EntityRowProps, Entity, entityThemes } from '../types'; import { getEntity } from '../utils'; @@ -6,13 +7,13 @@ const EntityThumbnail = ({ data, className = '', theme = entityThemes.normal, }: EntityRowProps) => { - const entity = data ? getEntity(data) : 'empty'; + const entity = getEntity(data); const wrapper = `component entity thumbnail ${entity} ${theme} ${className}`; return (
- {data?.name + {data.name}
); diff --git a/app/components/Logo/Extended.tsx b/app/components/Logo/Extended.tsx index b1bb8f6..80bdc15 100644 --- a/app/components/Logo/Extended.tsx +++ b/app/components/Logo/Extended.tsx @@ -6,7 +6,7 @@ const ExtendedLogo = () => (
- Muzikie + Muzikie

Muzikie

Decentralized Music streaming diff --git a/app/components/MainHeader/index.tsx b/app/components/MainHeader/index.tsx new file mode 100644 index 0000000..d8b0d90 --- /dev/null +++ b/app/components/MainHeader/index.tsx @@ -0,0 +1,23 @@ +/* External dependencies */ +import React from 'react'; +import { useLocation } from 'react-router-dom'; + +/* Internal dependencies */ +import ExtendedLogo from '../Logo/Extended'; +import MainMenu from '../MainMenu'; + +const MainHeader = () => { + const { pathname } = useLocation(); + const pageType = pathname === '/login' || pathname === '/register' ? 'public' : 'private'; + + return ( +
+
+ + +
+
+ ); +}; + +export default MainHeader; diff --git a/app/components/MainHeader/mainHeader.css b/app/components/MainHeader/mainHeader.css new file mode 100644 index 0000000..86614cd --- /dev/null +++ b/app/components/MainHeader/mainHeader.css @@ -0,0 +1,22 @@ +.component.mainHeader { + width: 100vw; + height: 70px; + padding: 20px 28px 0; + box-sizing: border-box; + + & .container { + display: flex; + justify-content: space-between; + flex-flow: row nowrap; + align-items: center; + } + + &.public { + margin-bottom: -70px; + } + + & .component.logo.extended { + position: relative; + z-index: 9; + } +} diff --git a/app/components/MainMenu/mainMenu.css b/app/components/MainMenu/mainMenu.css index 3c739fd..1e6e9a2 100644 --- a/app/components/MainMenu/mainMenu.css +++ b/app/components/MainMenu/mainMenu.css @@ -5,9 +5,6 @@ height: var(--menu-button); height: var(--menu-button); - position: absolute; - top: 50px; - right: var(--padding-m); box-sizing: border-box; z-index: 5; diff --git a/app/components/Player/PlaceHolderImage.tsx b/app/components/Player/PlaceHolderImage.tsx new file mode 100644 index 0000000..8023316 --- /dev/null +++ b/app/components/Player/PlaceHolderImage.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +const PlaceHolderImage = () => ( + +); + +export default PlaceHolderImage; diff --git a/app/components/Player/index.tsx b/app/components/Player/index.tsx index db109b4..c3d5a2b 100644 --- a/app/components/Player/index.tsx +++ b/app/components/Player/index.tsx @@ -1,11 +1,15 @@ +/* External dependencies */ import React, { useContext } from 'react'; import { Link } from '@remix-run/react'; + +/* Internal dependencies */ import { useAudio } from '~/hooks/useAudio'; import { PlayerContext } from '~/context/playerContext/playerContextProvider'; import { ProfileContext } from '~/context/profileContext/profileContextProvider'; import { IconButton } from '~/components/common/Button'; import EntityThumbnail from '~/components/Entity/EntityThumbnail'; import { API_URLS } from '~/constants/api'; +import PlaceHolderImage from './PlaceHolderImage'; import ProgressBar from './ProgressBar'; const Player = () => { @@ -26,7 +30,10 @@ const Player = () => {
- { current && } + { current + ? + : + }
{ current?.name ?? '...' }
diff --git a/app/components/Player/player.css b/app/components/Player/player.css index ec66ae8..44b7fef 100644 --- a/app/components/Player/player.css +++ b/app/components/Player/player.css @@ -128,6 +128,13 @@ } } +.component.imagePlaceHolder { + display: block; + width: 59px; + height: 59xp; + border-radius: (--border-radius-r); +} + @media (min-width: 680px) { .component.player { /* & .controls { diff --git a/app/routes/__main.tsx b/app/routes/__main.tsx index 8ca74dd..ea47e81 100644 --- a/app/routes/__main.tsx +++ b/app/routes/__main.tsx @@ -6,7 +6,7 @@ import { Outlet } from '@remix-run/react'; import PlayerProvider from '~/context/playerContext/playerContextProvider'; import ProfileProvider from '~/context/profileContext/profileContextProvider'; import SettingsProvider from '~/context/settingsContext/settingsContextProvider'; -import MainMenu from '~/components/MainMenu'; +import MainHeader from '~/components/MainHeader'; import Player from '~/components/Player'; import styles from '~/styles/routes/__main.css'; @@ -19,7 +19,7 @@ const Main = () => (
- +
diff --git a/app/routes/__main/index/index.tsx b/app/routes/__main/index/index.tsx index 60125db..9521f10 100644 --- a/app/routes/__main/index/index.tsx +++ b/app/routes/__main/index/index.tsx @@ -11,8 +11,6 @@ import { getAlbums, } from '~/models/entity.server'; import Collection from '~/components/Collection'; -import Logo from '~/components/Logo'; -import { greet } from '~/helpers/helpers'; import { entityThemes } from '~/components/Entity/types'; import { collectionThemes } from '~/components/Collection/types'; import styles from '~/styles/routes/__main/index.css'; @@ -47,10 +45,6 @@ const Home = () => { return (
-
- -

{greet()}

-
{ return (
-
- -
Date: Sat, 19 Nov 2022 11:25:58 +0100 Subject: [PATCH 7/8] Fix onAudioEnd --- app/components/Player/index.tsx | 10 +++++----- app/hooks/useAudio/useAudio.test.ts | 26 ++++++++++++++++++++++++++ app/hooks/{ => useAudio}/useAudio.ts | 5 +---- 3 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 app/hooks/useAudio/useAudio.test.ts rename app/hooks/{ => useAudio}/useAudio.ts (89%) diff --git a/app/components/Player/index.tsx b/app/components/Player/index.tsx index c3d5a2b..569e719 100644 --- a/app/components/Player/index.tsx +++ b/app/components/Player/index.tsx @@ -1,9 +1,9 @@ /* External dependencies */ -import React, { useContext } from 'react'; +import React, { useContext, useRef, MutableRefObject } from 'react'; import { Link } from '@remix-run/react'; /* Internal dependencies */ -import { useAudio } from '~/hooks/useAudio'; +import { useAudio } from '~/hooks/useAudio/useAudio'; import { PlayerContext } from '~/context/playerContext/playerContextProvider'; import { ProfileContext } from '~/context/profileContext/profileContextProvider'; import { IconButton } from '~/components/common/Button'; @@ -13,13 +13,13 @@ import PlaceHolderImage from './PlaceHolderImage'; import ProgressBar from './ProgressBar'; const Player = () => { + const audioRef = useRef() as MutableRefObject; const { - audioRef, playPause, onTimeUpdate, progress, setProgress, - } = useAudio(); + } = useAudio(audioRef); const { current, isPlaying, @@ -41,7 +41,7 @@ const Player = () => {