mirror of
https://github.com/anultravioletaurora/Jellify.git
synced 2026-01-07 22:29:52 -06:00
Merge branch 'main' of github.com:Jellify-Music/App into maintenance/artist-screen
This commit is contained in:
@@ -186,7 +186,7 @@ function AlbumTrackListHeader(): React.JSX.Element {
|
||||
<XStack justify='center' marginVertical={'$2'}>
|
||||
<YStack flex={1}>
|
||||
{album.ProductionYear ? (
|
||||
<Text display='block' textAlign='right'>
|
||||
<Text textAlign='right'>
|
||||
{album.ProductionYear?.toString() ?? 'Unknown Year'}
|
||||
</Text>
|
||||
) : null}
|
||||
|
||||
@@ -137,7 +137,6 @@ function Image({
|
||||
|
||||
return (
|
||||
<ZStack style={imageViewStyle.view} justifyContent='center' alignContent='center'>
|
||||
{!isLoaded && <ItemBlurhash item={item} />}
|
||||
<AnimatedTamaguiImage
|
||||
objectFit='cover'
|
||||
// recyclingKey={imageUrl}
|
||||
@@ -151,6 +150,7 @@ function Image({
|
||||
exiting={FadeOut}
|
||||
style={Styles.blurhash}
|
||||
/>
|
||||
{!isLoaded && <ItemBlurhash item={item} />}
|
||||
</ZStack>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -13,13 +13,7 @@ export function RunTimeSeconds({
|
||||
alignment?: 'center' | 'left' | 'right'
|
||||
}): React.JSX.Element {
|
||||
return (
|
||||
<Text
|
||||
bold
|
||||
color={color}
|
||||
display='block'
|
||||
textAlign={alignment}
|
||||
fontVariant={['tabular-nums']}
|
||||
>
|
||||
<Text bold color={color} textAlign={alignment} fontVariant={['tabular-nums']}>
|
||||
{calculateRunTimeFromSeconds(children)}
|
||||
</Text>
|
||||
)
|
||||
@@ -37,7 +31,7 @@ export function RunTimeTicks({
|
||||
const time = calculateRunTimeFromTicks(children)
|
||||
|
||||
return (
|
||||
<Text {...props} display='block' color='$borderColor' fontVariant={['tabular-nums']}>
|
||||
<Text {...props} color='$borderColor' fontVariant={['tabular-nums']}>
|
||||
{time}
|
||||
</Text>
|
||||
)
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { XStack, YStack, Spacer, useTheme } from 'tamagui'
|
||||
import { Text } from '../../Global/helpers/text'
|
||||
import React, { useCallback, useMemo, useRef } from 'react'
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import ItemImage from '../../Global/components/image'
|
||||
import Animated, {
|
||||
FadeIn,
|
||||
FadeOut,
|
||||
useAnimatedStyle,
|
||||
useSharedValue,
|
||||
withSpring,
|
||||
withTiming,
|
||||
} from 'react-native-reanimated'
|
||||
import { LayoutChangeEvent, Platform, View } from 'react-native'
|
||||
import { LayoutChangeEvent, Platform } from 'react-native'
|
||||
import MaterialDesignIcons from '@react-native-vector-icons/material-design-icons'
|
||||
import navigationRef from '../../../../navigation'
|
||||
import { useCurrentTrack, useQueueRef } from '../../../stores/player/queue'
|
||||
@@ -62,37 +62,37 @@ export default function PlayerHeader(): React.JSX.Element {
|
||||
function PlayerArtwork(): React.JSX.Element {
|
||||
const nowPlaying = useCurrentTrack()
|
||||
|
||||
const artworkMaxHeight = '65%'
|
||||
|
||||
const artworkMaxWidth = useSharedValue<number>(300)
|
||||
|
||||
const artworkContainerRef = useRef<View>(null)
|
||||
const artworkMaxHeight = useSharedValue<number>(200)
|
||||
const artworkMaxWidth = useSharedValue<number>(200)
|
||||
|
||||
const animatedStyle = useAnimatedStyle(() => ({
|
||||
width: artworkMaxWidth.get(),
|
||||
width: withSpring(artworkMaxWidth.get()),
|
||||
height: withSpring(artworkMaxWidth.get()),
|
||||
opacity: withTiming(nowPlaying ? 1 : 0),
|
||||
}))
|
||||
|
||||
const handleLayout = useCallback((event: LayoutChangeEvent) => {
|
||||
artworkMaxHeight.set(event.nativeEvent.layout.height)
|
||||
artworkMaxWidth.set(event.nativeEvent.layout.height)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<YStack
|
||||
ref={artworkContainerRef}
|
||||
flex={1}
|
||||
alignItems='center'
|
||||
justifyContent='center'
|
||||
paddingHorizontal={'$2'}
|
||||
maxHeight={artworkMaxHeight}
|
||||
maxHeight={'65%'}
|
||||
marginHorizontal={'$4'}
|
||||
marginVertical={'auto'}
|
||||
onLayout={handleLayout}
|
||||
>
|
||||
{nowPlaying && (
|
||||
<Animated.View
|
||||
entering={FadeIn}
|
||||
exiting={FadeOut}
|
||||
key={`${nowPlaying!.item.AlbumId}-item-image`}
|
||||
style={{ flex: 1, ...animatedStyle }}
|
||||
style={{
|
||||
...animatedStyle,
|
||||
}}
|
||||
>
|
||||
<ItemImage item={nowPlaying!.item} testID='player-image-test-id' />
|
||||
</Animated.View>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Square } from 'tamagui'
|
||||
import { Spacer, Square } from 'tamagui'
|
||||
import { Text } from '../../Global/helpers/text'
|
||||
import navigationRef from '../../../../navigation'
|
||||
import { parseBitrateFromTranscodingUrl } from '../../../utils/url-parsers'
|
||||
@@ -25,11 +25,13 @@ export default function QualityBadge({
|
||||
|
||||
return bitrate && container ? (
|
||||
<Square
|
||||
enterStyle={{ opacity: 1 }}
|
||||
exitStyle={{ opacity: 0 }}
|
||||
animation={'bouncy'}
|
||||
justifyContent='center'
|
||||
borderWidth={'$1'}
|
||||
backgroundColor={'$primary'}
|
||||
paddingHorizontal={'$1'}
|
||||
paddingVertical={'$0.5'}
|
||||
paddingHorizontal={'$2'}
|
||||
borderRadius={'$2'}
|
||||
pressStyle={{ scale: 0.875 }}
|
||||
onPress={() => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState, useRef } from 'react'
|
||||
import { HorizontalSlider } from '../../../components/Global/helpers/slider'
|
||||
import { Gesture, GestureDetector } from 'react-native-gesture-handler'
|
||||
import { XStack, YStack } from 'tamagui'
|
||||
import { Spacer, XStack, YStack } from 'tamagui'
|
||||
import { useSafeAreaFrame } from 'react-native-safe-area-context'
|
||||
import { useSeekTo } from '../../../providers/Player/hooks/mutations'
|
||||
import { RunTimeSeconds } from '../../../components/Global/helpers/time-codes'
|
||||
@@ -157,21 +157,33 @@ export default function Scrubber(): React.JSX.Element {
|
||||
/>
|
||||
|
||||
<XStack alignItems='center' paddingTop={'$2'}>
|
||||
<YStack alignItems='flex-start' flexShrink={1}>
|
||||
<YStack
|
||||
alignItems='flex-start'
|
||||
justifyContent='center'
|
||||
flexShrink={1}
|
||||
height={'$2'}
|
||||
>
|
||||
<RunTimeSeconds alignment='left'>{currentSeconds}</RunTimeSeconds>
|
||||
</YStack>
|
||||
|
||||
<YStack alignItems='center' flexGrow={1}>
|
||||
{nowPlaying?.mediaSourceInfo && displayAudioQualityBadge && (
|
||||
<YStack alignItems='center' justifyContent='center' flexGrow={1} height={'$2'}>
|
||||
{nowPlaying?.mediaSourceInfo && displayAudioQualityBadge ? (
|
||||
<QualityBadge
|
||||
item={nowPlaying.item}
|
||||
sourceType={nowPlaying.sourceType}
|
||||
mediaSourceInfo={nowPlaying.mediaSourceInfo}
|
||||
/>
|
||||
) : (
|
||||
<Spacer />
|
||||
)}
|
||||
</YStack>
|
||||
|
||||
<YStack alignItems='flex-end' flexShrink={1}>
|
||||
<YStack
|
||||
alignItems='flex-end'
|
||||
justifyContent='center'
|
||||
flexShrink={1}
|
||||
height={'$2'}
|
||||
>
|
||||
<RunTimeSeconds alignment='right'>{totalSeconds}</RunTimeSeconds>
|
||||
</YStack>
|
||||
</XStack>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useMemo, useCallback } from 'react'
|
||||
import { getToken, Progress, View, XStack, YStack } from 'tamagui'
|
||||
import { getToken, Progress, XStack, YStack } from 'tamagui'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
import { Text } from '../Global/helpers/text'
|
||||
import TextTicker from 'react-native-text-ticker'
|
||||
@@ -11,7 +11,14 @@ import { Progress as TrackPlayerProgress } from 'react-native-track-player'
|
||||
import { useProgress } from '../../providers/Player/hooks/queries'
|
||||
|
||||
import { Gesture, GestureDetector } from 'react-native-gesture-handler'
|
||||
import Animated, { FadeIn, FadeOut, useSharedValue, withSpring } from 'react-native-reanimated'
|
||||
import Animated, {
|
||||
FadeIn,
|
||||
FadeInDown,
|
||||
FadeOut,
|
||||
FadeOutDown,
|
||||
useSharedValue,
|
||||
withSpring,
|
||||
} from 'react-native-reanimated'
|
||||
import { runOnJS } from 'react-native-worklets'
|
||||
import { RootStackParamList } from '../../screens/types'
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
||||
@@ -79,10 +86,22 @@ export const Miniplayer = React.memo(function Miniplayer(): React.JSX.Element {
|
||||
|
||||
return (
|
||||
<GestureDetector gesture={gesture}>
|
||||
<Animated.View testID='miniplayer-test-id' entering={FadeIn} exiting={FadeOut}>
|
||||
<Animated.View
|
||||
testID='miniplayer-test-id'
|
||||
entering={FadeInDown.springify()}
|
||||
exiting={FadeOutDown.springify()}
|
||||
>
|
||||
<YStack>
|
||||
<MiniPlayerProgress />
|
||||
<XStack paddingBottom={'$1'} alignItems='center' onPress={openPlayer}>
|
||||
<XStack
|
||||
alignItems='center'
|
||||
pressStyle={{
|
||||
opacity: 0.6,
|
||||
}}
|
||||
animation={'quick'}
|
||||
onPress={openPlayer}
|
||||
paddingBottom={'$1'}
|
||||
>
|
||||
<YStack justify='center' alignItems='center' marginLeft={'$2'}>
|
||||
<Animated.View
|
||||
entering={FadeIn}
|
||||
|
||||
@@ -79,7 +79,7 @@ export default function PlaybackTab(): React.JSX.Element {
|
||||
onCheckedChange={setDisplayAudioQualityBadge}
|
||||
size={'$2'}
|
||||
checked={displayAudioQualityBadge}
|
||||
label={displayAudioQualityBadge ? 'Enabled' : 'Disabled'}
|
||||
label={displayAudioQualityBadge ? 'Displaying' : 'Disabled'}
|
||||
/>
|
||||
),
|
||||
},
|
||||
|
||||
@@ -32,14 +32,14 @@ export default function StorageTab(): React.JSX.Element {
|
||||
onPress: () => navigation.navigate('StorageManagement'),
|
||||
},
|
||||
{
|
||||
title: 'Automatically Cache Tracks',
|
||||
title: 'Auto-Download Tracks',
|
||||
subTitle: 'Download tracks as they are played',
|
||||
iconName: autoDownload ? 'cloud-download' : 'cloud-off-outline',
|
||||
iconColor: autoDownload ? '$success' : '$borderColor',
|
||||
children: (
|
||||
<SwitchWithLabel
|
||||
size={'$2'}
|
||||
label={autoDownload ? 'Enabled' : 'Disabled'}
|
||||
label={autoDownload ? 'Downloading' : 'Disabled'}
|
||||
checked={autoDownload}
|
||||
onCheckedChange={() => setAutoDownload(!autoDownload)}
|
||||
/>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { create } from 'zustand'
|
||||
import { createJSONStorage, devtools, persist } from 'zustand/middleware'
|
||||
import { Platform } from 'react-native'
|
||||
import { mmkvStateStorage } from '../../constants/storage'
|
||||
import StreamingQuality from '../../enums/audio-quality'
|
||||
|
||||
@@ -21,7 +20,7 @@ export const useUsageSettingsStore = create<UsageSettingsStore>()(
|
||||
downloadQuality: StreamingQuality.Original,
|
||||
setDownloadQuality: (downloadQuality: DownloadQuality) => set({ downloadQuality }),
|
||||
|
||||
autoDownload: Platform.OS === 'android' || Platform.OS === 'ios',
|
||||
autoDownload: false,
|
||||
setAutoDownload: (autoDownload) => set({ autoDownload }),
|
||||
}),
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user