xref: /MusicFree/src/components/musicBar/index.tsx (revision b882a19d884fffa32f7c8cef31652b909dceaa0f)
1import React, {Fragment, useEffect, useState} from 'react';
2import {Keyboard, Pressable, StyleSheet, Text, View} from 'react-native';
3import rpx from '@/utils/rpx';
4import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
5import MusicQueue from '@/core/musicQueue';
6import {Avatar, IconButton, useTheme} from 'react-native-paper';
7import {CircularProgressBase} from 'react-native-circular-progress-indicator';
8import {useNavigation} from '@react-navigation/native';
9import {ROUTE_PATH} from '@/entry/router';
10
11import musicIsPaused from '@/utils/musicIsPaused';
12import usePanel from '../panels/usePanel';
13import Color from 'color';
14import ThemeText from '../base/themeText';
15import {ImgAsset} from '@/constants/assetsConst';
16
17export default function () {
18    // const currentMusicState = useAtomValue(loadableCurrentMusicStateAtom);
19    const musicItem = MusicQueue.useCurrentMusicItem();
20    const musicState = MusicQueue.usePlaybackState();
21    const [showKeyboard, setKeyboardStatus] = useState(false);
22    const {showPanel} = usePanel();
23    const navigation = useNavigation<any>();
24    const progress = MusicQueue.useProgress();
25    const {colors} = useTheme();
26
27    useEffect(() => {
28        const showSubscription = Keyboard.addListener('keyboardDidShow', () => {
29            setKeyboardStatus(true);
30        });
31        const hideSubscription = Keyboard.addListener('keyboardDidHide', () => {
32            setKeyboardStatus(false);
33        });
34
35        return () => {
36            showSubscription.remove();
37            hideSubscription.remove();
38        };
39    }, []);
40
41    return (
42        <Fragment>
43            {musicItem && !showKeyboard && (
44                <Pressable
45                    style={[
46                        style.wrapper,
47                        {
48                            backgroundColor: Color(colors.primary)
49                                .alpha(0.66)
50                                .toString(),
51                        },
52                    ]}
53                    onPress={() => {
54                        navigation.navigate(ROUTE_PATH.MUSIC_DETAIL);
55                    }}>
56                    <View style={style.artworkWrapper}>
57                        <Avatar.Image
58                            size={rpx(96)}
59                            source={
60                                musicItem.artwork
61                                    ? {
62                                          uri: musicItem.artwork,
63                                      }
64                                    : ImgAsset.albumDefault
65                            }
66                        />
67                    </View>
68                    <Text
69                        ellipsizeMode="tail"
70                        style={style.textWrapper}
71                        numberOfLines={1}>
72                        <ThemeText fontSize="content">
73                            {musicItem.title}
74                        </ThemeText>
75                        {musicItem?.artist && (
76                            <ThemeText
77                                fontSize="description"
78                                fontColor="secondary">
79                                {' '}
80                                -{musicItem.artist}
81                            </ThemeText>
82                        )}
83                    </Text>
84                    <View style={style.actionGroup}>
85                        <CircularProgressBase
86                            activeStrokeWidth={rpx(4)}
87                            inActiveStrokeWidth={rpx(2)}
88                            inActiveStrokeOpacity={0.2}
89                            value={
90                                progress?.duration
91                                    ? (100 * progress.position) /
92                                      progress.duration
93                                    : 0
94                            }
95                            duration={100}
96                            radius={rpx(36)}
97                            activeStrokeColor={colors.text}
98                            inActiveStrokeColor={Color(colors.text)
99                                .alpha(0.5)
100                                .toString()}>
101                            {musicIsPaused(musicState) ? (
102                                <IconButton
103                                    icon="play"
104                                    size={rpx(48)}
105                                    onPress={async () => {
106                                        await MusicQueue.play();
107                                    }}
108                                />
109                            ) : (
110                                <IconButton
111                                    icon="pause"
112                                    size={rpx(48)}
113                                    onPress={async () => {
114                                        await MusicQueue.pause();
115                                    }}
116                                />
117                            )}
118                        </CircularProgressBase>
119
120                        <Icon
121                            name="playlist-music"
122                            size={rpx(56)}
123                            onPress={() => {
124                                showPanel('PlayList');
125                            }}
126                            style={[style.actionIcon, {color: colors.text}]}
127                        />
128                    </View>
129                </Pressable>
130            )}
131        </Fragment>
132    );
133}
134
135const style = StyleSheet.create({
136    wrapper: {
137        width: rpx(750),
138        height: rpx(120),
139        flexDirection: 'row',
140        alignItems: 'center',
141        paddingHorizontal: rpx(24),
142    },
143    artworkWrapper: {
144        height: rpx(120),
145        width: rpx(120),
146    },
147    textWrapper: {
148        flexGrow: 1,
149        maxWidth: rpx(382),
150    },
151    actionGroup: {
152        width: rpx(200),
153        justifyContent: 'flex-end',
154        flexDirection: 'row',
155        alignItems: 'center',
156    },
157    actionIcon: {
158        marginLeft: rpx(36),
159    },
160});
161