Skip to content

Commit

Permalink
feat(fullstack) : get track from playlist.
Browse files Browse the repository at this point in the history
  • Loading branch information
drmolixcool committed Apr 6, 2024
1 parent e6f02cd commit da62dfb
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 4 deletions.
39 changes: 39 additions & 0 deletions backend/src/socketio/RoomIO.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { JSONTrack } from "commons/backend-types";
import { Response } from "commons/socket.io-types";
import RoomStorage from "../RoomStorage";
import Room, { TypedSocket } from "./Room";
import { spotify } from "../server";
import Spotify from "../musicplatform/Spotify";

const roomStorage = RoomStorage.getRoomStorage();

Expand Down Expand Up @@ -187,6 +189,43 @@ export default function onRoomWSConnection(socket: TypedSocket) {
resultCallback(data);
}
);

socket.on("user:playlists", async (userId, callback) => {
const playlists = await spotify.playlists.getUsersPlaylists(userId);

const result = playlists.items.map((playlist) => {
return { name: playlist.name, playlistId: playlist.id };
});

callback(result);

// const result = playlists.items.forEach((rawPlaylist) => {
// const tracks: JSONTrack[] = [];
//
// const playlist = await spotify.playlists.getPlaylist(rawPlaylist.id);
// playlist.tracks.items.forEach((audioElement) => {
// const data = audioElement.track;
// if (data as Track) {
// const track = new Spotify().toJSON(data as Track);
// if (track !== null) tracks.push(track);
// }
// });
//
// const result = {
// name: playlist.name,
// tracks: tracks,
// };
// });
// const newVar = result.;
});

socket.on("user:playlistTrack", async (playlistId, callback) => {
const playlist = await spotify.playlists.getPlaylist(playlistId);
const result = playlist.tracks.items
.map((playlistTrack) => new Spotify().toJSON(playlistTrack.track))
.filter((value) => value !== null) as JSONTrack[];
callback(result);
});
}

registerHandlers();
Expand Down
5 changes: 5 additions & 0 deletions commons/backend-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,8 @@ export interface RoomJSON {
queue: RoomJSONTrack[];
voteSkipActualTrack: string[];
}

export interface Playlist {
name: string;
playlistId: string;
}
15 changes: 14 additions & 1 deletion commons/socket.io-types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { JSONTrack, PlayingJSONTrack, RoomJSON } from "./backend-types";
import {
JSONTrack,
PlayingJSONTrack,
Playlist,
RoomJSON,
} from "./backend-types";

export type Response<T> =
| { data: T; error: null }
Expand Down Expand Up @@ -92,6 +97,14 @@ export interface ClientToServerEvents
text: string,
resultCallback: (args: JSONTrack[]) => void
) => void;
"user:playlists": (
userId: string,
callback: (playlists: Playlist[]) => void
) => void;
"user:playlistTrack": (
playlistId: string,
callback: (tracks: JSONTrack[]) => void
) => void;
}

/**
Expand Down
1 change: 1 addition & 0 deletions expo/app/(tabs)/rooms/[id]/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export default function RoomTabLayout() {
}}
/>
<Stack.Screen name="add" options={{ title: "Ajouter une musique" }} />
<Stack.Screen name="library" options={{ title: "Tes playlists : " }} />
<Stack.Screen name="settings" options={{ title: "Paramètres" }} />
</Stack>
</WebSocketProvider>
Expand Down
93 changes: 93 additions & 0 deletions expo/app/(tabs)/rooms/[id]/library.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import FontAwesome from "@expo/vector-icons/FontAwesome";
import { JSONTrack, Playlist } from "commons/backend-types";
import { router } from "expo-router";
import { useEffect, useState } from "react";
import { FlatList, Pressable, StyleSheet } from "react-native";

import { useWebSocket } from "./_layout";
import { Text, View } from "../../../../components/Tamed";
import SearchedTrackItem from "../../../../components/room/SearchedTrackItem";
import { useSupabaseUserHook } from "../../../../lib/useSupabaseUser";

export default function Library() {
const [playlists, setPlaylists] = useState<Playlist[]>([]);

const user = useSupabaseUserHook();
const socket = useWebSocket();
useEffect(() => {
console.log(user);
const spotifyUser = user?.identities?.filter(
(ptf) => ptf.provider === "spotify"
)[0];
socket?.emit("user:playlists", spotifyUser?.id, setPlaylists);
}, [socket, user]);

return (
<FlatList
data={playlists}
renderItem={({ item }) => <Item playlist={item} />}
/>
);
}

function Item(props: { playlist: Playlist }) {
const playlist = props.playlist;

const [showTracks, setShowTracks] = useState(false);
const [tracks, setTracks] = useState<JSONTrack[]>([]);

const socket = useWebSocket();

useEffect(() => {
if (showTracks)
socket?.emit("user:playlistTrack", playlist.playlistId, setTracks);
}, [socket, showTracks]);

return (
<View>
<Pressable
onPress={() => setShowTracks(!showTracks)}
style={styles.playlistHeader}
>
<FontAwesome
name={`arrow-${showTracks ? "down" : "up"}`}
style={styles.playlistHeaderInner}
/>
<Text style={styles.playlistHeaderInner}>{playlist.name}</Text>
</Pressable>
{showTracks && (
<FlatList
data={tracks}
renderItem={({ item }) => {
return (
<View style={{ paddingLeft: 50 }}>
<SearchedTrackItem
track={item}
handleAddMusic={() => {
socket?.emit("queue:add", new URL(item.url).toString());

router.back();
router.back();
}}
/>
</View>
);
}}
/>
)}
</View>
);
}

const styles = StyleSheet.create({
playlistHeader: {
flexDirection: "row",
alignItems: "center",
paddingVertical: 15,
},
playlistHeaderInner: {
fontFamily: "Outfit-Bold",
paddingLeft: 10,
fontSize: 15,
},
});
25 changes: 25 additions & 0 deletions expo/app/(tabs)/rooms/[id]/playlist.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React, { useEffect, useState } from "react";
import { FlatList, Pressable } from "react-native";

import { useWebSocket } from "./_layout";
import { Text } from "../../../../components/Tamed";

export default function Playlist(props: { playlistId: string }) {
const [tracks, setTracks] = useState([]);

const socket = useWebSocket();
useEffect(() => {
socket?.emit("user:playlists", props.playlistId, setTracks);
}, [socket]);

return (
<FlatList
data={tracks}
renderItem={({ item }) => (
<Pressable onPress={() => alert(item)}>
<Text>{item}</Text>
</Pressable>
)}
/>
);
}
2 changes: 2 additions & 0 deletions expo/components/room/Library.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ClockCounterClockwise from "phosphor-react-native/src/icons/ClockCounterClockwise";
import Heart from "phosphor-react-native/src/icons/Heart";
import MusicNote from "phosphor-react-native/src/icons/MusicNote";
import { router } from "expo-router";
import { StyleSheet, View, Text } from "react-native";

import LibraryComponent from "./LibraryComponent";
Expand All @@ -18,6 +19,7 @@ const Library = () => {
title="Mes playlists"
subtitle="Ajoute une musique à partir de tes playlists"
icon={<MusicNote />}
onPress={() => router.push("./library")}
/>
<LibraryComponent
title="Mes titres likés"
Expand Down
9 changes: 6 additions & 3 deletions expo/components/room/LibraryComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import { MaterialIcons } from "@expo/vector-icons";
import React from "react";
import { StyleSheet, Text, View } from "react-native";
import { Pressable, StyleSheet, Text, View } from "react-native";

const LibraryComponent = ({
title,
subtitle,
icon,
onPress,
}: {
title: string;
subtitle: string;
icon: React.ReactElement;
onPress: () => void;
}) => {
icon = React.cloneElement(icon, { size: 24, color: "white" });
return (
<View style={styles.component}>
<Pressable style={styles.component} onPress={onPress}>
<View style={styles.header}>
<Text style={styles.title}>{title}</Text>
{icon}
</View>
<Text style={styles.text}>{subtitle}</Text>
</View>
</Pressable>
);
};

Expand Down

0 comments on commit da62dfb

Please sign in to comment.