Skip to content

Commit 2ec0fca

Browse files
committed
Add: onHover optionPopup button
1 parent 94f1a70 commit 2ec0fca

4 files changed

Lines changed: 96 additions & 84 deletions

File tree

app/components/Header.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useNavigation } from '@react-navigation/native'
44

55
import { ThemeContext } from '~/contexts/theme'
66
import IconButton from '~/components/button/IconButton'
7-
import size from '~/styles/size';
7+
import size from '~/styles/size'
88

99
const Header = ({ title, marginBottom=30 }) => {
1010
const navigation = useNavigation()
@@ -49,4 +49,4 @@ const styles = StyleSheet.create({
4949
}
5050
})
5151

52-
export default Header;
52+
export default Header

app/components/player/BoxDesktopPlayer.js

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import React from 'react';
2-
import { Pressable, Text, View, StyleSheet, Platform } from 'react-native';
3-
import Icon from 'react-native-vector-icons/FontAwesome';
1+
import React from 'react'
2+
import { Pressable, Text, View, StyleSheet, Platform } from 'react-native'
3+
import Icon from 'react-native-vector-icons/FontAwesome'
44

5-
import { ConfigContext } from '~/contexts/config';
6-
import { SongContext, SongDispatchContext } from '~/contexts/song';
7-
import { ThemeContext } from '~/contexts/theme';
8-
import { urlCover } from '~/utils/url';
9-
import Player from '~/utils/player';
10-
import IconButton from '~/components/button/IconButton';
11-
import ImageError from '~/components/ImageError';
12-
import SlideBar from '~/components/button/SlideBar';
13-
import FavoritedButton from '~/components/button/FavoritedButton';
14-
import size from '~/styles/size';
15-
import PlayButton from '~/components/button/PlayButton';
5+
import { ConfigContext } from '~/contexts/config'
6+
import { SongContext, SongDispatchContext } from '~/contexts/song'
7+
import { ThemeContext } from '~/contexts/theme'
8+
import { urlCover } from '~/utils/url'
9+
import Player from '~/utils/player'
10+
import IconButton from '~/components/button/IconButton'
11+
import ImageError from '~/components/ImageError'
12+
import SlideBar from '~/components/button/SlideBar'
13+
import FavoritedButton from '~/components/button/FavoritedButton'
14+
import size from '~/styles/size'
15+
import PlayButton from '~/components/button/PlayButton'
1616

1717
const BoxDesktopPlayer = ({ setFullScreen }) => {
1818
const song = React.useContext(SongContext)
@@ -161,4 +161,4 @@ const styles = StyleSheet.create({
161161
},
162162
})
163163

164-
export default BoxDesktopPlayer;
164+
export default BoxDesktopPlayer

app/components/popup/OptionsPopup.js

Lines changed: 78 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,91 @@
1-
import React from 'react';
2-
import { View, Text, Modal, ScrollView, Animated, Pressable, Platform } from 'react-native';
3-
import { useSafeAreaInsets } from 'react-native-safe-area-context';
4-
import { useNavigation } from '@react-navigation/native';
5-
import { useTranslation } from 'react-i18next';
6-
import Icon from 'react-native-vector-icons/FontAwesome';
1+
import React from 'react'
2+
import { View, Text, Modal, ScrollView, Animated, Pressable, Platform } from 'react-native'
3+
import { useSafeAreaInsets } from 'react-native-safe-area-context'
4+
import { useNavigation } from '@react-navigation/native'
5+
import { useTranslation } from 'react-i18next'
6+
import Icon from 'react-native-vector-icons/FontAwesome'
77

8-
import { ConfigContext } from '~/contexts/config';
9-
import { ThemeContext } from '~/contexts/theme';
10-
import { urlCover } from '~/utils/url';
11-
import ImageError from '~/components/ImageError';
12-
import mainStyles from '~/styles/main';
13-
import size from '~/styles/size';
8+
import { ConfigContext } from '~/contexts/config'
9+
import { SettingsContext } from '~/contexts/settings'
10+
import { ThemeContext } from '~/contexts/theme'
11+
import { urlCover } from '~/utils/url'
12+
import ImageError from '~/components/ImageError'
13+
import mainStyles from '~/styles/main'
14+
import size from '~/styles/size'
15+
16+
const OptionItem = ({ option }) => {
17+
const theme = React.useContext(ThemeContext)
18+
const [isHover, setIsHover] = React.useState(false)
19+
const settings = React.useContext(SettingsContext)
20+
21+
if (!option) return null
22+
if (option.hidden) return null
23+
return (
24+
<Pressable
25+
onHoverIn={() => settings.isDesktop && setIsHover(true)}
26+
onHoverOut={() => setIsHover(false)}
27+
style={({ pressed }) => ([mainStyles.opacity({ pressed }), {
28+
flexDirection: 'row',
29+
alignItems: 'center',
30+
paddingHorizontal: 20,
31+
paddingStart: 20 + 15 * (option.indent || 0),
32+
height: 45,
33+
justifyContent: 'flex-start',
34+
alignContent: 'center',
35+
gap: 10,
36+
backgroundColor: isHover ? 'rgba(0,0,0,0.1)' : theme.secondaryBack,
37+
}])}
38+
onPress={option.onPress}
39+
>
40+
{
41+
option.icon && (
42+
<Icon name={option.icon} size={size.icon.tiny} color={theme.secondaryText} style={{
43+
width: 25,
44+
textAlign: 'center'
45+
}} />
46+
)
47+
}
48+
{
49+
option.image && (
50+
<ImageError
51+
style={{
52+
width: 35,
53+
height: 35,
54+
borderRadius: option.borderRadius || 5,
55+
}}
56+
source={{ uri: option.image }}
57+
/>
58+
)
59+
}
60+
<Text
61+
style={{ color: theme.primaryText, fontSize: size.text.large }}
62+
numberOfLines={1}
63+
>{option.name}</Text>
64+
</Pressable>
65+
)
66+
}
1467

1568
const OptionsPopup = ({ ref, visible, close, options, item = null }) => {
16-
const { t } = useTranslation();
17-
const insets = useSafeAreaInsets();
69+
const { t } = useTranslation()
70+
const insets = useSafeAreaInsets()
1871
const theme = React.useContext(ThemeContext)
1972
const slide = React.useRef(new Animated.Value(-1000)).current
2073
const isAnim = React.useRef(false)
2174
const config = React.useContext(ConfigContext)
22-
const navigation = useNavigation();
23-
const [virtualOptions, setVirtualOptions] = React.useState();
75+
const navigation = useNavigation()
76+
const [virtualOptions, setVirtualOptions] = React.useState()
2477

2578
React.useImperativeHandle(ref, () => ({
2679
close: close,
2780
showInfo: (info) => {
28-
navigation.navigate('Info', { info });
29-
close();
81+
navigation.navigate('Info', { info })
82+
close()
3083
},
3184
setVirtualOptions: (opt) => {
32-
setVirtualOptions(opt);
85+
setVirtualOptions(opt)
3386
},
3487
clearVirtualOptions: () => {
35-
setVirtualOptions(null);
88+
setVirtualOptions(null)
3689
}
3790
}), [close])
3891

@@ -52,7 +105,7 @@ const OptionsPopup = ({ ref, visible, close, options, item = null }) => {
52105
}).start()
53106
}
54107

55-
if (!visible) return null;
108+
if (!visible) return null
56109
return (
57110
<Modal
58111
transparent={true}
@@ -132,55 +185,13 @@ const OptionsPopup = ({ ref, visible, close, options, item = null }) => {
132185
name: t('Cancel'),
133186
icon: 'close',
134187
onPress: close
135-
}].map((option, index) => {
136-
if (!option) return null
137-
if (option.hidden) return null;
138-
return (
139-
<Pressable
140-
style={({ pressed }) => ([mainStyles.opacity({ pressed }), {
141-
flexDirection: 'row',
142-
alignItems: 'center',
143-
paddingHorizontal: 20,
144-
paddingStart: 20 + 15 * (option.indent || 0),
145-
height: 45,
146-
justifyContent: 'flex-start',
147-
alignContent: 'center',
148-
gap: 10,
149-
}])}
150-
key={index}
151-
onPress={option.onPress}
152-
>
153-
{
154-
option.icon && (
155-
<Icon name={option.icon} size={size.icon.tiny} color={theme.secondaryText} style={{
156-
width: 25,
157-
textAlign: 'center'
158-
}} />
159-
)
160-
}
161-
{
162-
option.image && (
163-
<ImageError
164-
style={{
165-
width: 35,
166-
height: 35,
167-
borderRadius: option.borderRadius || 5,
168-
}}
169-
source={{ uri: option.image }}
170-
/>
171-
)
172-
}
173-
<Text
174-
style={{ color: theme.primaryText, fontSize: size.text.large }}
175-
numberOfLines={1}
176-
>{option.name}</Text>
177-
</Pressable>
178-
)
179-
})}
188+
}].map((option, index) => (
189+
<OptionItem key={index} option={option} />
190+
))}
180191
</Animated.View>
181192
</ScrollView>
182193
</Modal>
183194
)
184195
}
185196

186-
export default OptionsPopup;
197+
export default OptionsPopup

eslint.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default [
2626
"react/prop-types": "off",
2727
// "react/react-in-jsx-scope": "off",
2828
"no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
29+
"semi": ["error", "never"]
2930
},
3031
}
3132
];

0 commit comments

Comments
 (0)