xref: /MusicFree/src/pages/musicDetail/components/content/lyric/index.tsx (revision 819a9075ec97c73412fbf94430d3065e57d52b4e)
163c74e8eSmaotoumaoimport React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
263c74e8eSmaotoumaoimport { LayoutRectangle, StyleSheet, Text, View } from "react-native";
363c74e8eSmaotoumaoimport rpx from "@/utils/rpx";
463c74e8eSmaotoumaoimport useDelayFalsy from "@/hooks/useDelayFalsy";
563c74e8eSmaotoumaoimport { FlatList, Gesture, GestureDetector, TapGestureHandler } from "react-native-gesture-handler";
663c74e8eSmaotoumaoimport { fontSizeConst } from "@/constants/uiConst";
763c74e8eSmaotoumaoimport Loading from "@/components/base/loading";
863c74e8eSmaotoumaoimport globalStyle from "@/constants/globalStyle";
963c74e8eSmaotoumaoimport { showPanel } from "@/components/panels/usePanel";
1063c74e8eSmaotoumaoimport LyricManager from "@/core/lyricManager";
1163c74e8eSmaotoumaoimport TrackPlayer from "@/core/trackPlayer";
1263c74e8eSmaotoumaoimport { musicIsPaused } from "@/utils/trackUtils";
1363c74e8eSmaotoumaoimport delay from "@/utils/delay";
1463c74e8eSmaotoumaoimport DraggingTime from "./draggingTime";
1563c74e8eSmaotoumaoimport LyricItemComponent from "./lyricItem";
16*819a9075Smaotoumaoimport PersistStatus from "@/core/persistStatus.ts";
1763c74e8eSmaotoumaoimport LyricOperations from "./lyricOperations";
1863c74e8eSmaotoumaoimport MediaExtra from "@/core/mediaExtra";
1963c74e8eSmaotoumaoimport { IParsedLrcItem } from "@/utils/lrcParser";
2063c74e8eSmaotoumaoimport { IconButtonWithGesture } from "@/components/base/iconButton.tsx";
218d82ecd9S猫头猫
228d82ecd9S猫头猫const ITEM_HEIGHT = rpx(92);
238d82ecd9S猫头猫
248d82ecd9S猫头猫interface IItemHeights {
258d82ecd9S猫头猫    blankHeight?: number;
268d82ecd9S猫头猫    [k: number]: number;
278d82ecd9S猫头猫}
288d82ecd9S猫头猫
2913cebe63S猫头猫interface IProps {
3013cebe63S猫头猫    onTurnPageClick?: () => void;
3113cebe63S猫头猫}
3213cebe63S猫头猫
333a5e0c00S猫头猫const fontSizeMap = {
343a5e0c00S猫头猫    0: rpx(24),
353a5e0c00S猫头猫    1: rpx(30),
363a5e0c00S猫头猫    2: rpx(36),
373a5e0c00S猫头猫    3: rpx(42),
383a5e0c00S猫头猫} as Record<number, number>;
393a5e0c00S猫头猫
4013cebe63S猫头猫export default function Lyric(props: IProps) {
4113cebe63S猫头猫    const {onTurnPageClick} = props;
4213cebe63S猫头猫
4343733013S猫头猫    const {loading, meta, lyrics, hasTranslation} =
447e883dbbS猫头猫        LyricManager.useLyricState();
458d82ecd9S猫头猫    const currentLrcItem = LyricManager.useCurrentLyric();
46*819a9075Smaotoumao    const showTranslation = PersistStatus.useValue(
4713cebe63S猫头猫        'lyric.showTranslation',
4813cebe63S猫头猫        false,
4913cebe63S猫头猫    );
50*819a9075Smaotoumao    const fontSizeKey = PersistStatus.useValue('lyric.detailFontSize', 1);
513a5e0c00S猫头猫    const fontSizeStyle = useMemo(
523a5e0c00S猫头猫        () => ({
533a5e0c00S猫头猫            fontSize: fontSizeMap[fontSizeKey!],
543a5e0c00S猫头猫        }),
553a5e0c00S猫头猫        [fontSizeKey],
563a5e0c00S猫头猫    );
578d82ecd9S猫头猫
588d82ecd9S猫头猫    const [draggingIndex, setDraggingIndex, setDraggingIndexImmi] =
598d82ecd9S猫头猫        useDelayFalsy<number | undefined>(undefined, 2000);
608d82ecd9S猫头猫    const musicState = TrackPlayer.useMusicState();
618d82ecd9S猫头猫
628d82ecd9S猫头猫    const [layout, setLayout] = useState<LayoutRectangle>();
63f01fe338S猫头猫
6443733013S猫头猫    const listRef = useRef<FlatList<IParsedLrcItem> | null>();
65f01fe338S猫头猫
66f01fe338S猫头猫    const currentMusicItem = TrackPlayer.useCurrentMusic();
67f01fe338S猫头猫    const associateMusicItem = currentMusicItem
68f01fe338S猫头猫        ? MediaExtra.get(currentMusicItem)?.associatedLrc
69f01fe338S猫头猫        : null;
70f01fe338S猫头猫    // 是否展示拖拽
71f01fe338S猫头猫    const dragShownRef = useRef(false);
72f01fe338S猫头猫
73f01fe338S猫头猫    // 组件是否挂载
7413cebe63S猫头猫    const isMountedRef = useRef(true);
758d82ecd9S猫头猫
768d82ecd9S猫头猫    // 用来缓存高度
778d82ecd9S猫头猫    const itemHeightsRef = useRef<IItemHeights>({});
788d82ecd9S猫头猫
798d82ecd9S猫头猫    // 设置空白组件,获取组件高度
808d82ecd9S猫头猫    const blankComponent = useMemo(() => {
818d82ecd9S猫头猫        return (
828d82ecd9S猫头猫            <View
837aed04d4S猫头猫                style={styles.empty}
848d82ecd9S猫头猫                onLayout={evt => {
858d82ecd9S猫头猫                    itemHeightsRef.current.blankHeight =
868d82ecd9S猫头猫                        evt.nativeEvent.layout.height;
878d82ecd9S猫头猫                }}
888d82ecd9S猫头猫            />
898d82ecd9S猫头猫        );
908d82ecd9S猫头猫    }, []);
918d82ecd9S猫头猫
928d82ecd9S猫头猫    const handleLyricItemLayout = useCallback(
938d82ecd9S猫头猫        (index: number, height: number) => {
948d82ecd9S猫头猫            itemHeightsRef.current[index] = height;
958d82ecd9S猫头猫        },
968d82ecd9S猫头猫        [],
978d82ecd9S猫头猫    );
988d82ecd9S猫头猫
9913cebe63S猫头猫    // 滚到当前item
10013cebe63S猫头猫    const scrollToCurrentLrcItem = useCallback(() => {
10113cebe63S猫头猫        if (!listRef.current) {
10213cebe63S猫头猫            return;
10313cebe63S猫头猫        }
10413cebe63S猫头猫        const currentLrcItem = LyricManager.getCurrentLyric();
10513cebe63S猫头猫        const lyrics = LyricManager.getLyricState().lyrics;
10613cebe63S猫头猫        if (currentLrcItem?.index === -1 || !currentLrcItem) {
10713cebe63S猫头猫            listRef.current?.scrollToIndex({
10813cebe63S猫头猫                index: 0,
10913cebe63S猫头猫                viewPosition: 0.5,
11013cebe63S猫头猫            });
11113cebe63S猫头猫        } else {
11213cebe63S猫头猫            listRef.current?.scrollToIndex({
11313cebe63S猫头猫                index: Math.min(currentLrcItem.index ?? 0, lyrics.length - 1),
11413cebe63S猫头猫                viewPosition: 0.5,
11513cebe63S猫头猫            });
11613cebe63S猫头猫        }
11713cebe63S猫头猫    }, []);
11813cebe63S猫头猫
11913cebe63S猫头猫    const delayedScrollToCurrentLrcItem = useMemo(() => {
12013cebe63S猫头猫        let sto: number;
12113cebe63S猫头猫
12213cebe63S猫头猫        return () => {
12313cebe63S猫头猫            if (sto) {
12413cebe63S猫头猫                clearTimeout(sto);
12513cebe63S猫头猫            }
12613cebe63S猫头猫            sto = setTimeout(() => {
12713cebe63S猫头猫                if (isMountedRef.current) {
12813cebe63S猫头猫                    scrollToCurrentLrcItem();
12913cebe63S猫头猫                }
13013cebe63S猫头猫            }, 200) as any;
13113cebe63S猫头猫        };
13213cebe63S猫头猫    }, []);
13313cebe63S猫头猫
1348d82ecd9S猫头猫    useEffect(() => {
1358d82ecd9S猫头猫        // 暂停且拖拽才返回
1368d82ecd9S猫头猫        if (
1377e883dbbS猫头猫            lyrics.length === 0 ||
1388d82ecd9S猫头猫            draggingIndex !== undefined ||
1398d82ecd9S猫头猫            (draggingIndex === undefined && musicIsPaused(musicState)) ||
1407e883dbbS猫头猫            lyrics[lyrics.length - 1].time < 1
1418d82ecd9S猫头猫        ) {
1428d82ecd9S猫头猫            return;
1438d82ecd9S猫头猫        }
1448d82ecd9S猫头猫        if (currentLrcItem?.index === -1 || !currentLrcItem) {
1458d82ecd9S猫头猫            listRef.current?.scrollToIndex({
1468d82ecd9S猫头猫                index: 0,
1478d82ecd9S猫头猫                viewPosition: 0.5,
1488d82ecd9S猫头猫            });
1498d82ecd9S猫头猫        } else {
1508d82ecd9S猫头猫            listRef.current?.scrollToIndex({
1517e883dbbS猫头猫                index: Math.min(currentLrcItem.index ?? 0, lyrics.length - 1),
1528d82ecd9S猫头猫                viewPosition: 0.5,
1538d82ecd9S猫头猫            });
1548d82ecd9S猫头猫        }
1558d82ecd9S猫头猫        // 音乐暂停状态不应该影响到滑动,所以不放在依赖里,但是这样写不好。。
1567e883dbbS猫头猫    }, [currentLrcItem, lyrics, draggingIndex]);
1578d82ecd9S猫头猫
158a48a4bb0S猫头猫    useEffect(() => {
15913cebe63S猫头猫        scrollToCurrentLrcItem();
16013cebe63S猫头猫        return () => {
16113cebe63S猫头猫            isMountedRef.current = false;
16213cebe63S猫头猫        };
163a48a4bb0S猫头猫    }, []);
164a48a4bb0S猫头猫
1658d82ecd9S猫头猫    // 开始滚动时拖拽生效
1668d82ecd9S猫头猫    const onScrollBeginDrag = () => {
1678d82ecd9S猫头猫        dragShownRef.current = true;
1688d82ecd9S猫头猫    };
1698d82ecd9S猫头猫
1708d82ecd9S猫头猫    const onScrollEndDrag = async () => {
1718d82ecd9S猫头猫        if (draggingIndex !== undefined) {
1728d82ecd9S猫头猫            setDraggingIndex(undefined);
1738d82ecd9S猫头猫        }
1748d82ecd9S猫头猫        dragShownRef.current = false;
1758d82ecd9S猫头猫    };
1768d82ecd9S猫头猫
1778d82ecd9S猫头猫    const onScroll = (e: any) => {
1788d82ecd9S猫头猫        if (dragShownRef.current) {
1798d82ecd9S猫头猫            const offset =
1808d82ecd9S猫头猫                e.nativeEvent.contentOffset.y +
1818d82ecd9S猫头猫                e.nativeEvent.layoutMeasurement.height / 2;
1828d82ecd9S猫头猫
1838d82ecd9S猫头猫            const itemHeights = itemHeightsRef.current;
1848d82ecd9S猫头猫            let height = itemHeights.blankHeight!;
1858d82ecd9S猫头猫            if (offset <= height) {
1868d82ecd9S猫头猫                setDraggingIndex(0);
1878d82ecd9S猫头猫                return;
1888d82ecd9S猫头猫            }
1897e883dbbS猫头猫            for (let i = 0; i < lyrics.length; ++i) {
1908d82ecd9S猫头猫                height += itemHeights[i] ?? 0;
1918d82ecd9S猫头猫                if (height > offset) {
1928d82ecd9S猫头猫                    setDraggingIndex(i);
1938d82ecd9S猫头猫                    return;
1948d82ecd9S猫头猫                }
1958d82ecd9S猫头猫            }
1968d82ecd9S猫头猫        }
1978d82ecd9S猫头猫    };
1988d82ecd9S猫头猫
1998d82ecd9S猫头猫    const onLyricSeekPress = async () => {
2008d82ecd9S猫头猫        if (draggingIndex !== undefined) {
2017e883dbbS猫头猫            const time = lyrics[draggingIndex].time + +(meta?.offset ?? 0);
2028d82ecd9S猫头猫            if (time !== undefined && !isNaN(time)) {
2038d82ecd9S猫头猫                await TrackPlayer.seekTo(time);
2048d82ecd9S猫头猫                await TrackPlayer.play();
2058d82ecd9S猫头猫                setDraggingIndexImmi(undefined);
2068d82ecd9S猫头猫            }
2078d82ecd9S猫头猫        }
2088d82ecd9S猫头猫    };
2098d82ecd9S猫头猫
210f01fe338S猫头猫    const tapGesture = Gesture.Tap()
21113cebe63S猫头猫        .onStart(() => {
21213cebe63S猫头猫            onTurnPageClick?.();
21313cebe63S猫头猫        })
21413cebe63S猫头猫        .runOnJS(true);
21513cebe63S猫头猫
216f01fe338S猫头猫    const unlinkTapGesture = Gesture.Tap()
217f01fe338S猫头猫        .onStart(() => {
218f01fe338S猫头猫            if (currentMusicItem) {
219f01fe338S猫头猫                MediaExtra.update(currentMusicItem, {
220f01fe338S猫头猫                    associatedLrc: undefined,
221f01fe338S猫头猫                });
222f01fe338S猫头猫                LyricManager.refreshLyric(false, true);
223f01fe338S猫头猫            }
224f01fe338S猫头猫        })
225f01fe338S猫头猫        .runOnJS(true);
226f01fe338S猫头猫
2278d82ecd9S猫头猫    return (
22813cebe63S猫头猫        <>
229f01fe338S猫头猫            <GestureDetector gesture={tapGesture}>
2308d82ecd9S猫头猫                <View style={globalStyle.fwflex1}>
2318d82ecd9S猫头猫                    {loading ? (
2328d82ecd9S猫头猫                        <Loading color="white" />
2337e883dbbS猫头猫                    ) : lyrics?.length ? (
2348d82ecd9S猫头猫                        <FlatList
2358d82ecd9S猫头猫                            ref={_ => {
2368d82ecd9S猫头猫                                listRef.current = _;
2378d82ecd9S猫头猫                            }}
2388d82ecd9S猫头猫                            onLayout={e => {
2398d82ecd9S猫头猫                                setLayout(e.nativeEvent.layout);
2408d82ecd9S猫头猫                            }}
2418d82ecd9S猫头猫                            viewabilityConfig={{
2428d82ecd9S猫头猫                                itemVisiblePercentThreshold: 100,
2438d82ecd9S猫头猫                            }}
2448d82ecd9S猫头猫                            onScrollToIndexFailed={({index}) => {
2458d82ecd9S猫头猫                                delay(120).then(() => {
2468d82ecd9S猫头猫                                    listRef.current?.scrollToIndex({
24713cebe63S猫头猫                                        index: Math.min(
24813cebe63S猫头猫                                            index ?? 0,
24913cebe63S猫头猫                                            lyrics.length - 1,
25013cebe63S猫头猫                                        ),
2518d82ecd9S猫头猫                                        viewPosition: 0.5,
2528d82ecd9S猫头猫                                    });
2538d82ecd9S猫头猫                                });
2548d82ecd9S猫头猫                            }}
2558d82ecd9S猫头猫                            fadingEdgeLength={120}
256f01fe338S猫头猫                            ListHeaderComponent={
257f01fe338S猫头猫                                <>
258f01fe338S猫头猫                                    {blankComponent}
259f01fe338S猫头猫                                    <View style={styles.lyricMeta}>
260f01fe338S猫头猫                                        {associateMusicItem ? (
261f01fe338S猫头猫                                            <>
262f01fe338S猫头猫                                                <Text
2633a5e0c00S猫头猫                                                    style={[
2643a5e0c00S猫头猫                                                        styles.lyricMetaText,
2653a5e0c00S猫头猫                                                        fontSizeStyle,
2663a5e0c00S猫头猫                                                    ]}
267f01fe338S猫头猫                                                    ellipsizeMode="middle"
268f01fe338S猫头猫                                                    numberOfLines={1}>
269f01fe338S猫头猫                                                    歌词关联自「
270f01fe338S猫头猫                                                    {
271f01fe338S猫头猫                                                        associateMusicItem.platform
272f01fe338S猫头猫                                                    }{' '}
273f01fe338S猫头猫                                                    -{' '}
274f01fe338S猫头猫                                                    {associateMusicItem.title ||
275f01fe338S猫头猫                                                        ''}
276f01fe338S猫头猫277f01fe338S猫头猫                                                </Text>
278f01fe338S猫头猫
279f01fe338S猫头猫                                                <GestureDetector
280f01fe338S猫头猫                                                    gesture={unlinkTapGesture}>
281f01fe338S猫头猫                                                    <Text
2823a5e0c00S猫头猫                                                        style={[
2833a5e0c00S猫头猫                                                            styles.linkText,
2843a5e0c00S猫头猫                                                            fontSizeStyle,
2853a5e0c00S猫头猫                                                        ]}>
286f01fe338S猫头猫                                                        解除关联
287f01fe338S猫头猫                                                    </Text>
288f01fe338S猫头猫                                                </GestureDetector>
289f01fe338S猫头猫                                            </>
290f01fe338S猫头猫                                        ) : null}
291f01fe338S猫头猫                                    </View>
292f01fe338S猫头猫                                </>
293f01fe338S猫头猫                            }
2948d82ecd9S猫头猫                            ListFooterComponent={blankComponent}
2958d82ecd9S猫头猫                            onScrollBeginDrag={onScrollBeginDrag}
2968d82ecd9S猫头猫                            onMomentumScrollEnd={onScrollEndDrag}
2978d82ecd9S猫头猫                            onScroll={onScroll}
2988d82ecd9S猫头猫                            scrollEventThrottle={32}
2997aed04d4S猫头猫                            style={styles.wrapper}
3007e883dbbS猫头猫                            data={lyrics}
3018d82ecd9S猫头猫                            initialNumToRender={30}
3028d82ecd9S猫头猫                            overScrollMode="never"
3038d82ecd9S猫头猫                            extraData={currentLrcItem}
3047e883dbbS猫头猫                            renderItem={({item, index}) => {
3057e883dbbS猫头猫                                let text = item.lrc;
3067e883dbbS猫头猫                                if (showTranslation && hasTranslation) {
30743733013S猫头猫                                    text += `\n${item?.translation ?? ''}`;
3087e883dbbS猫头猫                                }
3097e883dbbS猫头猫
3107e883dbbS猫头猫                                return (
3118d82ecd9S猫头猫                                    <LyricItemComponent
3128d82ecd9S猫头猫                                        index={index}
3137e883dbbS猫头猫                                        text={text}
3143a5e0c00S猫头猫                                        fontSize={fontSizeStyle.fontSize}
3158d82ecd9S猫头猫                                        onLayout={handleLyricItemLayout}
3168d82ecd9S猫头猫                                        light={draggingIndex === index}
31713cebe63S猫头猫                                        highlight={
31813cebe63S猫头猫                                            currentLrcItem?.index === index
31913cebe63S猫头猫                                        }
3208d82ecd9S猫头猫                                    />
3217e883dbbS猫头猫                                );
3227e883dbbS猫头猫                            }}
3238d82ecd9S猫头猫                        />
3248d82ecd9S猫头猫                    ) : (
3258d82ecd9S猫头猫                        <View style={globalStyle.fullCenter}>
3263a5e0c00S猫头猫                            <Text style={[styles.white, fontSizeStyle]}>
3273a5e0c00S猫头猫                                暂无歌词
3283a5e0c00S猫头猫                            </Text>
3298d82ecd9S猫头猫                            <TapGestureHandler
3308d82ecd9S猫头猫                                onActivated={() => {
3318d82ecd9S猫头猫                                    showPanel('SearchLrc', {
33213cebe63S猫头猫                                        musicItem:
33313cebe63S猫头猫                                            TrackPlayer.getCurrentMusic(),
3348d82ecd9S猫头猫                                    });
3358d82ecd9S猫头猫                                }}>
3363a5e0c00S猫头猫                                <Text
3373a5e0c00S猫头猫                                    style={[styles.searchLyric, fontSizeStyle]}>
3383a5e0c00S猫头猫                                    搜索歌词
3393a5e0c00S猫头猫                                </Text>
3408d82ecd9S猫头猫                            </TapGestureHandler>
3418d82ecd9S猫头猫                        </View>
3428d82ecd9S猫头猫                    )}
3438d82ecd9S猫头猫                    {draggingIndex !== undefined && (
3448d82ecd9S猫头猫                        <View
3458d82ecd9S猫头猫                            style={[
3467aed04d4S猫头猫                                styles.draggingTime,
3478d82ecd9S猫头猫                                layout?.height
3488d82ecd9S猫头猫                                    ? {
34913cebe63S猫头猫                                          top:
35013cebe63S猫头猫                                              (layout.height - ITEM_HEIGHT) / 2,
3518d82ecd9S猫头猫                                      }
3528d82ecd9S猫头猫                                    : null,
3538d82ecd9S猫头猫                            ]}>
3548d82ecd9S猫头猫                            <DraggingTime
3558d82ecd9S猫头猫                                time={
3567e883dbbS猫头猫                                    (lyrics[draggingIndex]?.time ?? 0) +
3578d82ecd9S猫头猫                                    +(meta?.offset ?? 0)
3588d82ecd9S猫头猫                                }
3598d82ecd9S猫头猫                            />
3607aed04d4S猫头猫                            <View style={styles.singleLine} />
3618d82ecd9S猫头猫
3628d82ecd9S猫头猫                            <IconButtonWithGesture
3637aed04d4S猫头猫                                style={styles.playIcon}
3648d82ecd9S猫头猫                                sizeType="small"
3658d82ecd9S猫头猫                                name="play"
3668d82ecd9S猫头猫                                onPress={onLyricSeekPress}
3678d82ecd9S猫头猫                            />
3688d82ecd9S猫头猫                        </View>
3698d82ecd9S猫头猫                    )}
3708d82ecd9S猫头猫                </View>
37113cebe63S猫头猫            </GestureDetector>
37213cebe63S猫头猫            <LyricOperations
37313cebe63S猫头猫                scrollToCurrentLrcItem={delayedScrollToCurrentLrcItem}
37413cebe63S猫头猫            />
37513cebe63S猫头猫        </>
3768d82ecd9S猫头猫    );
3778d82ecd9S猫头猫}
3788d82ecd9S猫头猫
3797aed04d4S猫头猫const styles = StyleSheet.create({
3808d82ecd9S猫头猫    wrapper: {
3818d82ecd9S猫头猫        width: '100%',
3828d82ecd9S猫头猫        marginVertical: rpx(48),
3838d82ecd9S猫头猫        flex: 1,
3848d82ecd9S猫头猫    },
3858d82ecd9S猫头猫    empty: {
3868d82ecd9S猫头猫        paddingTop: '70%',
3878d82ecd9S猫头猫    },
3888d82ecd9S猫头猫    white: {
3898d82ecd9S猫头猫        color: 'white',
3908d82ecd9S猫头猫    },
391f01fe338S猫头猫    lyricMeta: {
392f01fe338S猫头猫        position: 'absolute',
393f01fe338S猫头猫        width: '100%',
394f01fe338S猫头猫        flexDirection: 'row',
395f01fe338S猫头猫        justifyContent: 'center',
396f01fe338S猫头猫        alignItems: 'center',
397f01fe338S猫头猫        left: 0,
398f01fe338S猫头猫        paddingHorizontal: rpx(48),
399f01fe338S猫头猫        bottom: rpx(48),
400f01fe338S猫头猫    },
401f01fe338S猫头猫    lyricMetaText: {
402f01fe338S猫头猫        color: 'white',
403f01fe338S猫头猫        opacity: 0.8,
404f01fe338S猫头猫        maxWidth: '80%',
405f01fe338S猫头猫    },
406f01fe338S猫头猫    linkText: {
407f01fe338S猫头猫        color: '#66ccff',
408f01fe338S猫头猫        textDecorationLine: 'underline',
409f01fe338S猫头猫    },
4108d82ecd9S猫头猫    draggingTime: {
4118d82ecd9S猫头猫        position: 'absolute',
4128d82ecd9S猫头猫        width: '100%',
4138d82ecd9S猫头猫        height: ITEM_HEIGHT,
4148d82ecd9S猫头猫        top: '40%',
4158d82ecd9S猫头猫        marginTop: rpx(48),
4168d82ecd9S猫头猫        paddingHorizontal: rpx(18),
4178d82ecd9S猫头猫        right: 0,
4188d82ecd9S猫头猫        flexDirection: 'row',
4198d82ecd9S猫头猫        alignItems: 'center',
4208d82ecd9S猫头猫        justifyContent: 'space-between',
4218d82ecd9S猫头猫    },
4228d82ecd9S猫头猫    draggingTimeText: {
4238d82ecd9S猫头猫        color: '#dddddd',
4248d82ecd9S猫头猫        fontSize: fontSizeConst.description,
4258d82ecd9S猫头猫        width: rpx(90),
4268d82ecd9S猫头猫    },
4278d82ecd9S猫头猫    singleLine: {
4288d82ecd9S猫头猫        width: '67%',
4298d82ecd9S猫头猫        height: 1,
4308d82ecd9S猫头猫        backgroundColor: '#cccccc',
4318d82ecd9S猫头猫        opacity: 0.4,
4328d82ecd9S猫头猫    },
4338d82ecd9S猫头猫    playIcon: {
4348d82ecd9S猫头猫        width: rpx(90),
4358d82ecd9S猫头猫        textAlign: 'right',
4368d82ecd9S猫头猫        color: 'white',
4378d82ecd9S猫头猫    },
4388d82ecd9S猫头猫    searchLyric: {
4398d82ecd9S猫头猫        width: rpx(180),
4408d82ecd9S猫头猫        marginTop: rpx(14),
4418d82ecd9S猫头猫        paddingVertical: rpx(10),
4428d82ecd9S猫头猫        textAlign: 'center',
4438d82ecd9S猫头猫        alignSelf: 'center',
4448d82ecd9S猫头猫        color: '#66eeff',
4458d82ecd9S猫头猫        textDecorationLine: 'underline',
4468d82ecd9S猫头猫    },
4478d82ecd9S猫头猫});
448