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

🔨 Debug and opti #43

Merged
merged 23 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
5 changes: 4 additions & 1 deletion public/locales/en/common.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
{
"ADD_TO_FAV_TOOLTIP": "Add to favorites",
"CANCEL": "Cancel",
"CARD_ALBUM_TRACK_NUMBER": "Track(s)",
"CARD_SONG_DURATION": "Duration",
"CARD_SONG_TITLE": "Title",
"CLOSE": "Close",
"CONNECT_TOAST_MESSAGE": "You have to be connected to access this feature",
"CREATE": "Create",
"DELETE": "Delete",
"LISTEN": "Listen",
"LOGOUT_TOAST_MESSAGE": "You have been disconnected",
"MENU_APP_NAME": "Soundy",
"MENU_CREATE": "Create",
"MENU_FAVORITES": "Favorites",
"MENU_HOME": "Home",
"MENU_LANGUAGE": "Language",
"MENU_LANGUAGE_1": "French",
"MENU_LANGUAGE_2": "English",
"MENU_LANGUAGE": "Language",
"MENU_LISTEN": "Listen",
"MENU_LOGIN": "Login",
"MENU_LOGOUT": "Logout",
Expand All @@ -30,6 +32,7 @@
"ORDER_SELECT_OLDEST": "Oldest",
"ORDER_SELECT_PLACEHOLDER": "Pick an order",
"ORDER_SELECT_TEXT": "Order by :",
"SAVE": "Save",
"SEARCH_BAR_BTN": "Search",
"SEARCH_BAR_FILTER_ALBUM": "Albums",
"SEARCH_BAR_FILTER_DURATION_TEXT": "Duration :",
Expand Down
3 changes: 2 additions & 1 deletion public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"COOKIE_BANNER_BTN_DECLINE": "Decline",
"COOKIE_BANNER_TITLE": "This site uses cookies",
"COOKIE_BANNER_TXT": "By continuing to browse this site, you accept the use of cookies to provide you with a better browsing experience. By clicking on \"Accept\", you allow us to store optional cookies on your device, in order to give you the best possible experience. By clicking on \"Decline\", you refuse the use of optionnal cookies. No personal data is stored and cookies are not used for advertising content.",
"COVER_URL": "Cover URL",
"CREATE_ALBUM_HEADER": "Create an album",
"CREATE_ALBUM_MISSING_TITLE_ERROR": "Enter an album title.",
"CREATE_ALBUM_NO_TRACKS_ADDED": "You haven't added any songs yet. To create your first album you need to upload at least one song.",
Expand All @@ -20,7 +21,6 @@
"CREATE_PAGE_BTN_SONG": "Upload a song",
"CREATE_PAGE_REQUIRED_FIELDS": "Fields with * are required",
"CREATE_PAGE_TITLE": "Create and upload your music.",
"CREATE_SONG_BTN": "Save",
"CREATE_SONG_COVER_INPUT": "Upload the cover :",
"CREATE_SONG_COVER_PLACEHOLDER": "Type the link to the cover here...",
"CREATE_SONG_FILE_INPUT": "Upload your file :",
Expand Down Expand Up @@ -62,6 +62,7 @@
"PASSWORDS_DO_NOT_MATCH": "Passwords do not match",
"PROFILE_MY_ALBUMS": "My albums",
"PROFILE_MY_SONGS": "My songs",
"RELEASE_YEAR": "Release year",
"SERVER_AWAKEN": "The server is starting, we are using Render.com so it may take up to 2 min to start...",
"SERVICES_TITLE_CREATE": "Create your own sounds !",
"SERVICES_TITLE_LISTEN": "Listen to a wide variety of sounds !",
Expand Down
5 changes: 4 additions & 1 deletion public/locales/fr/common.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
{
"ADD_TO_FAV_TOOLTIP": "Ajouter aux favoris",
"CANCEL": "Annuler",
"CARD_ALBUM_TRACK_NUMBER": "Piste(s)",
"CARD_SONG_DURATION": "Durée",
"CARD_SONG_TITLE": "Titre",
"CLOSE": "Fermer",
"CONNECT_TOAST_MESSAGE": "Vous devez vous connecter pour accéder à cette section",
"CREATE": "Créer",
"DELETE": "Supprimer",
"LISTEN": "Écouter",
"MENU_APP_NAME": "Soundy",
"MENU_CREATE": "Créer",
"MENU_FAVORITES": "Favoris",
"MENU_HOME": "Accueil",
"MENU_LANGUAGE": "Langue",
"MENU_LANGUAGE_1": "Français",
"MENU_LANGUAGE_2": "Anglais",
"MENU_LANGUAGE": "Langue",
"MENU_LISTEN": "Écouter",
"MENU_LOGIN": "Connexion",
"MENU_LOGOUT": "Déconnexion",
Expand All @@ -29,6 +31,7 @@
"ORDER_SELECT_OLDEST": "Plus ancien",
"ORDER_SELECT_PLACEHOLDER": "Choisissez un ordre",
"ORDER_SELECT_TEXT": "Trier par :",
"SAVE": "Enregistrer",
"SEARCH_BAR_BTN": "Chercher",
"SEARCH_BAR_FILTER_ALBUM": "Albums",
"SEARCH_BAR_FILTER_DURATION_TEXT": "Durée :",
Expand Down
3 changes: 2 additions & 1 deletion public/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"COOKIE_BANNER_BTN_DECLINE": "Refuser",
"COOKIE_BANNER_TITLE": "Ce site utilise des cookies",
"COOKIE_BANNER_TXT": "Nous utilisons des cookies pour vous offrir la meilleure expérience possible lors de votre visite sur notre site Internet. En cliquant sur \"Accepter\", vous nous autorisez à stocker des cookies supplémentaires sur votre navigateur afin de rendre votre expérience plus agréable. En cliquant sur \"Refuser\", vous n'utiliserez pas de cookies optionnels. Aucune données personnelles n'est stockées et ces cookies ne sont pas utilisés à des fins publicitaires",
"COVER_URL": "Lien de l'illustration",
"CREATE_ALBUM_HEADER": "Créer un album",
"CREATE_ALBUM_MISSING_TITLE_ERROR": "Titre d'album requis.",
"CREATE_ALBUM_NO_TRACKS_ADDED": "Vous n'avez pas encore ajouté de chansons. Veuillez en ajouter une au minimum pour pouvoir créer votre premier album.",
Expand All @@ -20,7 +21,6 @@
"CREATE_PAGE_BTN_SONG": "Ajouter un titre",
"CREATE_PAGE_REQUIRED_FIELDS": "Les champs avec * sont obligatoires",
"CREATE_PAGE_TITLE": "Créer et partager votre musique",
"CREATE_SONG_BTN": "Enregistrer",
"CREATE_SONG_COVER_INPUT": "Télécharger une illustration :",
"CREATE_SONG_COVER_PLACEHOLDER": "Entrer le lien de l'illustration ici...",
"CREATE_SONG_FILE_INPUT": "Télécharger le fichier :",
Expand Down Expand Up @@ -61,6 +61,7 @@
"PASSWORDS_DO_NOT_MATCH": "Les mots de passe ne correspondent pas",
"PROFILE_MY_ALBUMS": "Mes albums",
"PROFILE_MY_SONGS": "Mes musiques",
"RELEASE_YEAR": "Année de sortie",
"SERVER_AWAKEN": "Le serveur est en train de démarrer, nous utilisons Render.com, il peut donc prendre jusqu'à 2 minutes pour se réveiller....",
"SERVICES_TITLE_CREATE": "Créez vos propres sons !",
"SERVICES_TITLE_LISTEN": "Écoutez une grande variété de sons !",
Expand Down
43 changes: 16 additions & 27 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React, {
Suspense, useEffect, useState, useMemo,
} from 'react';
import { Routes, Route, Navigate } from 'react-router-dom';
import {
Routes, Route, Navigate, useLocation,
} from 'react-router-dom';
import { useCookies } from 'react-cookie';
import { useLazyQuery } from '@apollo/client';
import { useTranslation } from 'react-i18next';

import { useTranslation } from 'react-i18next';
import Home from './components/homePage/Home';
import Listen from './components/listenPage/Listen';
import Background from './components/Background';
Expand All @@ -32,35 +34,20 @@ export default function App() {
const token = useAppSelector((state) => state.user.token);
const [cookies, setCookies] = useCookies(['acceptCookies']);
const dispatch = useAppDispatch();
const [profileAction, { data: profileData, error: profileError }] = useLazyQuery(ProfileQuery);
const [profileAction, { data: profileData }] = useLazyQuery(ProfileQuery);
const location = useLocation();
const { t } = useTranslation('common');
const newToast = useNewToast();
const { t } = useTranslation('translation');

useEffect(() => {
if (profileError) {
newToast(
'warning',
t('TROUBLE_TO_CONNECT_TO_SERVER'),
);
}
}, [profileError, profileAction, newToast, t]);

useEffect(() => {
let timeoutId: ReturnType<typeof setTimeout>;

if (token == null) {
setIsLogin(false);
}
if (token) {
setIsLogin(true);
profileAction();

timeoutId = setTimeout(() => {
newToast('info', t('SERVER_AWAKEN'));
}, 5000);

if (profileData?.profile != null) {
clearTimeout(timeoutId);
dispatch(setCountry(profileData.profile.country));
dispatch(setEmail(profileData.profile.email));
dispatch(setName(profileData.profile.name));
Expand All @@ -73,11 +60,13 @@ export default function App() {
if (cookies.acceptCookies === true) {
setCookieVisibility(false);
}
}, [profileData, dispatch, token, cookies, setCookies, profileAction]);

return () => {
clearTimeout(timeoutId);
};
}, [profileData, dispatch, token, cookies, setCookies, profileAction, newToast, t]);
useEffect(() => {
if (!isLogin && location.state && location.state.fromProtected) {
newToast('warning', t('CONNECT_TOAST_MESSAGE'));
}
}, [isLogin, location.state, newToast, t]);

const acceptCookie = useMemo(() => cookieVisibility && (
<CookiePopup setCookieVisibility={setCookieVisibility} />
Expand All @@ -95,21 +84,21 @@ export default function App() {
element={
isLogin
? <Favorites isLogin={isLogin} />
: <Home isLogin={isLogin} isRedirected />
: <Navigate to="/" state={{ fromProtected: true }} />
}
/>
<Route
path="create"
element={isLogin
? <Create isLogin={isLogin} />
: <Home isLogin={isLogin} isRedirected />}
: <Navigate to="/" state={{ fromProtected: true }} />}
/>
<Route
path="/profile"
element={
isLogin
? <Profile isLogin={isLogin} />
: <Home isLogin={isLogin} isRedirected />
: <Navigate to="/" state={{ fromProtected: true }} />
}
/>
{/* // TODO Add the 404 error page */}
Expand Down
12 changes: 12 additions & 0 deletions src/components/ScrollToTop.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

export default function ScrollToTop() {
const { pathname } = useLocation();

useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);

return null;
}
4 changes: 2 additions & 2 deletions src/components/createPage/CreateAlbums.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface Props {
}

function CreateAlbums({ setSelectedType }: Props) {
const { t } = useTranslation('translation');
const { t } = useTranslation(['translation', 'common']);
const newToast = useNewToast();

const { data, loading } = useQuery<UserSongsQueryQuery, UserSongsQueryQueryVariables>(
Expand Down Expand Up @@ -170,7 +170,7 @@ function CreateAlbums({ setSelectedType }: Props) {
type="submit"
className="btn btn-primary self-center py-3 mt-4 text-lg"
>
{t('CREATE_SONG_BTN')}
{t('SAVE', { ns: 'common' })}
<UploadIcon />
</button>
);
Expand Down
12 changes: 9 additions & 3 deletions src/components/createPage/CreateSong.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// File input is disabled because it is not supported by the current version of the library
// Some random data (same .mp3 link) will be sent to the server
import { ApolloError, useMutation } from '@apollo/client';
import { ApolloError, useApolloClient, useMutation } from '@apollo/client';
import React, {
useState, useCallback, useMemo, FormEvent,
} from 'react';
Expand All @@ -10,10 +10,12 @@ import { CreateSongMutation } from '../../requests/mutations';
import { Cover, Spinner } from '../customElements';
import { UploadIcon } from '../../svg';
import { SongCreateInput } from '../../types/__generated_schemas__/graphql';
import { resetQueryCache } from '../../utils';

function CreateSong() {
const { t } = useTranslation('translation');
const { t } = useTranslation(['translation', 'common']);
const newToast = useNewToast();
const client = useApolloClient();

/** The initial formData is stored in a state
* @param {string} title - The title of the album
Expand Down Expand Up @@ -69,6 +71,10 @@ function CreateSong() {
});

if (response) {
resetQueryCache({
client,
queryNames: ['songs'],
});
newToast('success', t('CREATE_SONG_SUCCESS'));
}
} catch (error: unknown) {
Expand All @@ -92,7 +98,7 @@ function CreateSong() {
type="submit"
className="btn btn-primary self-center py-3 mt-4 text-lg"
>
{t('CREATE_SONG_BTN')}
{t('SAVE', { ns: 'common' })}
<UploadIcon />
</button>
);
Expand Down
8 changes: 4 additions & 4 deletions src/components/customElements/AlbumCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ function AlbumCard({
)), [artist, cover, dispatch, isPlaying, songs, title]);

return (
<div className="card w-full p-2 sm:w-[70%] lg:pl-[240px] lg:p-4 gap-2 bg-base-200 shadow-xl border border-1 border-stone-700">
<figure className="aspect-[1/1] max-w-[90px] max-h-[90px] lg:max-w-[200px] lg:max-h-[200px] absolute left-4 top-4">
<div className="card flex flex-row w-full p-2 sm:w-[70%] lg:p-4 gap-2 bg-base-200 shadow-xl border border-1 border-stone-700">
<figure className="aspect-[1/1] max-w-[90px] max-h-[90px] lg:max-w-[200px] lg:max-h-[200px] left-4 top-4">
<img
src={cover}
alt={`cover of ${title}`}
Expand All @@ -72,8 +72,8 @@ function AlbumCard({
<FavCheckBox />
</div>
)} */}
<div>
<div className="pl-[120px] pt-2 lg:px-4 lg:py-2 lg:text-xl">
<div className="flex flex-col flex-1">
<div className="pt-2 lg:px-4 lg:py-2 lg:text-xl">
<p className="font-bold">{capitalizeFirstLetter(title)}</p>
<p className="font-semibold">{artist || '?'}</p>
<div className="w-full flex flex-col min-[425px]:flex-row min-[425px]:items-center min-[425px]:justify-between min-[425px]:pr-4 lg:pr-0">
Expand Down
2 changes: 1 addition & 1 deletion src/components/customElements/CustomButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ interface Props {
link: string;
title: string;
onClick?: () => void;
buttonStyle: (props: ButtonStyleProps) => string;
buttonStyle?: (props: ButtonStyleProps) => string;
}

function CustomButton(props: Props) {
Expand Down
3 changes: 2 additions & 1 deletion src/components/customElements/FavCheckBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ function FavCheckBox(props: Props): JSX.Element {
// Initial the state from all songs request, if we like or unlike after that
// it will be only updated in local
const [likeSongState, setLikeSongState] = useState(isLiked);

const { t } = useTranslation('common');

const [likeSong, { loading: likeSongLoading }] = useMutation(
LikeSongMutation,
{
variables: { songId },
},

);

const [unlikeSong, { loading: unlikeSongLoading }] = useMutation(
Expand Down
21 changes: 19 additions & 2 deletions src/components/customElements/FilterRadio.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,39 @@
import React from 'react';
import React, { useMemo } from 'react';
import { ReleaseYear, DurationRange } from '../../types/__generated_schemas__/graphql';

interface Props {
inputId: string;
labelText: string;
value?: ReleaseYear | DurationRange;
setFilter: React.Dispatch<React.SetStateAction<any>>;
yearFilter?: ReleaseYear;
durationFilter?: DurationRange;
}

function FilterRadio({
inputId, labelText, value, setFilter,
inputId, labelText, value, setFilter, yearFilter, durationFilter,
}: Props): JSX.Element {
const checkedStatus = useMemo(() => {
if (yearFilter) {
if (yearFilter === value) {
return true;
}
}
if (durationFilter) {
if (durationFilter === value) {
return true;
}
}
return false;
}, [yearFilter, durationFilter, value]);

return (
<div className="form-control">
<label htmlFor={inputId} className="label cursor-pointer">
<span className="label-text px-2 font-semibold text-xs min-[860px]:text-sm">{labelText}</span>
<input
id={inputId}
checked={checkedStatus}
type="radio"
name="radio-10"
value={value}
Expand Down
20 changes: 20 additions & 0 deletions src/components/customElements/HeaderLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { Logo } from '../../svg';

function HeaderLogo() {
const { t } = useTranslation();
return (
<div className="navbar-start flex items-center gap-4">
<div className="w-12 h-12 rounded-full flex items-center justify-center">
<Logo />
</div>
<Link to="/">
<div className="text-2xl font-bold">{t('MENU_APP_NAME', { ns: 'common' })}</div>
</Link>
</div>
);
}

export default HeaderLogo;
Loading