Merge branch 'main' into feat/adc/search-view-v2
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { useBreakpointValue } from 'native-base';
|
||||
import HomeMainSongCard from './HomeMainSongCard';
|
||||
import GoldenRatioPanel from './GoldenRatioPanel';
|
||||
|
||||
type HomeCardProps = {
|
||||
image: string;
|
||||
title: string;
|
||||
artist: string;
|
||||
fontSize: number;
|
||||
onPress?: () => void;
|
||||
};
|
||||
|
||||
const cards = [
|
||||
{
|
||||
image: 'https://media.discordapp.net/attachments/717080637038788731/1153688155292180560/image_homeview1.png',
|
||||
title: 'Beethoven',
|
||||
artist: 'Synphony No. 9',
|
||||
fontSize: 46,
|
||||
},
|
||||
{
|
||||
image: 'https://media.discordapp.net/attachments/717080637038788731/1153688154923090093/image_homeview2.png',
|
||||
title: 'Mozart',
|
||||
artist: 'Lieder Kantate KV 619',
|
||||
fontSize: 36,
|
||||
},
|
||||
{
|
||||
image: 'https://media.discordapp.net/attachments/717080637038788731/1153688154499457096/image_homeview3.png',
|
||||
title: 'Back',
|
||||
artist: 'Truc Truc',
|
||||
fontSize: 26,
|
||||
},
|
||||
{
|
||||
image: 'https://media.discordapp.net/attachments/717080637038788731/1153688154109394985/image_homeview4.png',
|
||||
title: 'Mozart',
|
||||
artist: 'Machin Machin',
|
||||
fontSize: 22,
|
||||
},
|
||||
] as [HomeCardProps, HomeCardProps, HomeCardProps, HomeCardProps];
|
||||
|
||||
const GoldenRatio = () => {
|
||||
const screenSize = useBreakpointValue({ base: 'small', md: 'big' });
|
||||
const isPhone = screenSize === 'small';
|
||||
|
||||
return (
|
||||
<GoldenRatioPanel
|
||||
direction={isPhone ? 'column' : 'row'}
|
||||
header={<HomeMainSongCard {...cards[0]} />}
|
||||
>
|
||||
<GoldenRatioPanel
|
||||
direction={isPhone ? 'row' : 'column'}
|
||||
header={<HomeMainSongCard {...cards[1]} />}
|
||||
>
|
||||
<GoldenRatioPanel
|
||||
direction={isPhone ? 'column-reverse' : 'row-reverse'}
|
||||
header={<HomeMainSongCard {...cards[2]} />}
|
||||
>
|
||||
<GoldenRatioPanel
|
||||
direction={isPhone ? 'row-reverse' : 'column-reverse'}
|
||||
header={<HomeMainSongCard {...cards[3]} />}
|
||||
>
|
||||
<View style={{ display: 'flex', width: '100%', height: '100%' }}></View>
|
||||
</GoldenRatioPanel>
|
||||
</GoldenRatioPanel>
|
||||
</GoldenRatioPanel>
|
||||
</GoldenRatioPanel>
|
||||
);
|
||||
};
|
||||
|
||||
export default GoldenRatio;
|
||||
@@ -0,0 +1,57 @@
|
||||
import { View, ViewStyle } from 'react-native';
|
||||
|
||||
const bigSizePercent = '61.8%';
|
||||
const smallSizePercent = '38.2%';
|
||||
|
||||
type GoldenRatioPanelProps = {
|
||||
direction: 'row' | 'column' | 'row-reverse' | 'column-reverse';
|
||||
header: React.ReactNode;
|
||||
children: React.ReactNode;
|
||||
style?: ViewStyle;
|
||||
};
|
||||
|
||||
const isVerticalDir = (direction: GoldenRatioPanelProps['direction']) => {
|
||||
return direction === 'column' || direction === 'column-reverse';
|
||||
};
|
||||
|
||||
const GoldenRatioPanel = ({ direction, header, children, style }: GoldenRatioPanelProps) => {
|
||||
const firstSizePercent = bigSizePercent;
|
||||
const secondSizePercent = smallSizePercent;
|
||||
const isVertical = isVerticalDir(direction);
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
{
|
||||
width: !isVertical ? '100%' : undefined,
|
||||
height: isVertical ? '100%' : undefined,
|
||||
display: 'flex',
|
||||
flexDirection: direction,
|
||||
},
|
||||
style,
|
||||
]}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
height: isVertical ? firstSizePercent : undefined,
|
||||
width: !isVertical ? firstSizePercent : undefined,
|
||||
}}
|
||||
>
|
||||
{header}
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
height: isVertical ? secondSizePercent : undefined,
|
||||
width: !isVertical ? secondSizePercent : undefined,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
GoldenRatioPanel.defaultProps = {
|
||||
direction: 'row',
|
||||
};
|
||||
|
||||
export default GoldenRatioPanel;
|
||||
@@ -16,11 +16,12 @@ const HomeMainSongCard = (props: HomeMainSongCardProps) => {
|
||||
{({ isHovered }) => (
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
maxWidth: '100%',
|
||||
maxHeight: '100%',
|
||||
borderRadius: 12,
|
||||
overflow: 'hidden',
|
||||
position: 'relative',
|
||||
aspectRatio: 1,
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
@@ -29,8 +30,8 @@ const HomeMainSongCard = (props: HomeMainSongCardProps) => {
|
||||
}}
|
||||
style={{
|
||||
aspectRatio: 1,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
maxWidth: '100%',
|
||||
maxHeight: '100%',
|
||||
flexShrink: 1,
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Song from '../../models/Song';
|
||||
import React from 'react';
|
||||
import { Image, View } from 'react-native';
|
||||
import { Pressable, Text, PresenceTransition, Icon } from 'native-base';
|
||||
import { Pressable, Text, PresenceTransition, Icon, useBreakpointValue } from 'native-base';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
|
||||
type SongCardInfoProps = {
|
||||
@@ -10,11 +10,6 @@ type SongCardInfoProps = {
|
||||
onPlay: () => void;
|
||||
};
|
||||
|
||||
const CardDims = {
|
||||
height: 200,
|
||||
width: 200,
|
||||
};
|
||||
|
||||
const Scores = [
|
||||
{
|
||||
icon: 'warning',
|
||||
@@ -31,10 +26,17 @@ const Scores = [
|
||||
];
|
||||
|
||||
const SongCardInfo = (props: SongCardInfoProps) => {
|
||||
const screenSize = useBreakpointValue({ base: 'small', md: 'big' });
|
||||
const isPhone = screenSize === 'small';
|
||||
const [isPlayHovered, setIsPlayHovered] = React.useState(false);
|
||||
const [isHovered, setIsHovered] = React.useState(false);
|
||||
const [isSlided, setIsSlided] = React.useState(false);
|
||||
|
||||
const CardDims = {
|
||||
height: isPhone ? 160 : 200,
|
||||
width: isPhone ? 160 : 200,
|
||||
};
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
import { useBreakpointValue } from 'native-base';
|
||||
import { View } from 'react-native';
|
||||
import TabNavigationDesktop from './TabNavigationDesktop';
|
||||
import TabNavigationPhone from './TabNavigationPhone';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import React, { useState } from 'react';
|
||||
import useColorScheme from '../../hooks/colorScheme';
|
||||
import HomeView from '../../views/V2/HomeView';
|
||||
import React from 'react';
|
||||
|
||||
export type NaviTab = {
|
||||
id: string;
|
||||
@@ -17,132 +10,3 @@ export type NaviTab = {
|
||||
isCollapsed?: boolean;
|
||||
iconName?: string;
|
||||
};
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
id: 'home',
|
||||
label: 'Discovery',
|
||||
icon: <Ionicons name="search" size={24} color="black" />,
|
||||
iconName: 'search',
|
||||
},
|
||||
{
|
||||
id: 'profile',
|
||||
label: 'Profile',
|
||||
icon: <Ionicons name="person" size={24} color="black" />,
|
||||
iconName: 'person',
|
||||
},
|
||||
{
|
||||
id: 'music',
|
||||
label: 'Music',
|
||||
icon: <Ionicons name="musical-notes" size={24} color="black" />,
|
||||
iconName: 'musical-notes',
|
||||
},
|
||||
{
|
||||
id: 'search',
|
||||
label: 'Search',
|
||||
icon: <Ionicons name="search" size={24} color="black" />,
|
||||
iconName: 'search',
|
||||
},
|
||||
{
|
||||
id: 'leaderboard',
|
||||
label: 'Leaderboard',
|
||||
icon: <Ionicons name="medal" size={24} color="black" />,
|
||||
iconName: 'medal',
|
||||
},
|
||||
{
|
||||
id: 'notifications',
|
||||
label: 'Notifications',
|
||||
icon: <Ionicons name="notifications" size={24} color="black" />,
|
||||
iconName: 'notifications',
|
||||
},
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Settings',
|
||||
icon: <Ionicons name="settings" size={24} color="white" />,
|
||||
iconName: 'settings',
|
||||
},
|
||||
] as NaviTab[];
|
||||
|
||||
const TabNavigation = () => {
|
||||
const screenSize = useBreakpointValue({ base: 'small', md: 'big' });
|
||||
const [isDesktopCollapsed, setIsDesktopCollapsed] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState(tabs[0]?.id ?? 'home');
|
||||
const colorScheme = useColorScheme();
|
||||
|
||||
const child = <HomeView />;
|
||||
|
||||
const appTabs = tabs.map((t) => {
|
||||
// use the same instance of a component between desktop and mobile
|
||||
return {
|
||||
...t,
|
||||
onPress: () => setActiveTab(t.id),
|
||||
icon: (
|
||||
<Ionicons
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
name={t.iconName as any}
|
||||
size={24}
|
||||
color={colorScheme === 'dark' ? 'white' : 'black'}
|
||||
/>
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: 'rgb(26, 36, 74)',
|
||||
}}
|
||||
>
|
||||
{screenSize === 'small' ? (
|
||||
<TabNavigationPhone
|
||||
tabs={appTabs}
|
||||
activeTabID={activeTab}
|
||||
setActiveTabID={setActiveTab}
|
||||
>
|
||||
<View
|
||||
// @ts-expect-error Raw CSS
|
||||
style={{
|
||||
width: 'calc(100% - 5)',
|
||||
height: '100%',
|
||||
backgroundColor: 'rgba(16, 16, 20, 0.50)',
|
||||
borderRadius: 12,
|
||||
margin: 5,
|
||||
backDropFilter: 'blur(2px)',
|
||||
padding: 15,
|
||||
}}
|
||||
>
|
||||
{child}
|
||||
</View>
|
||||
</TabNavigationPhone>
|
||||
) : (
|
||||
<TabNavigationDesktop
|
||||
tabs={appTabs}
|
||||
activeTabID={activeTab}
|
||||
setActiveTabID={setActiveTab}
|
||||
isCollapsed={isDesktopCollapsed}
|
||||
setIsCollapsed={setIsDesktopCollapsed}
|
||||
>
|
||||
<View
|
||||
// @ts-expect-error Raw CSS
|
||||
style={{
|
||||
width: 'calc(100% - 10)',
|
||||
height: '100%',
|
||||
backgroundColor: 'rgba(16, 16, 20, 0.50)',
|
||||
borderRadius: 12,
|
||||
marginVertical: 10,
|
||||
marginRight: 10,
|
||||
backDropFilter: 'blur(2px)',
|
||||
padding: 20,
|
||||
}}
|
||||
>
|
||||
{child}
|
||||
</View>
|
||||
</TabNavigationDesktop>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default TabNavigation;
|
||||
|
||||
Reference in New Issue
Block a user