Skip to content

Commit

Permalink
Merge pull request #211 from lovegaoshi/dev
Browse files Browse the repository at this point in the history
feat: bottom tab
  • Loading branch information
lovegaoshi authored Oct 19, 2023
2 parents cf63c46 + 56411ba commit 68317dd
Show file tree
Hide file tree
Showing 15 changed files with 2,104 additions and 3,510 deletions.
2 changes: 1 addition & 1 deletion MusicFreePlugins
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,36 @@ class NoxAndroidAutoModule(reactContext: ReactApplicationContext) : ReactContext
override fun getName() = "NoxAndroidAutoModule"
@RequiresApi(Build.VERSION_CODES.O_MR1)
@ReactMethod fun disableShowWhenLocked() {
val activity = reactApplicationContext.currentActivity;
activity?.setShowWhenLocked(false);
activity?.setTurnScreenOn(false);
val activity = reactApplicationContext.currentActivity
activity?.setShowWhenLocked(false)
activity?.setTurnScreenOn(false)
}
@ReactMethod fun getDrawOverAppsPermission(callback: Promise) {
val context = reactApplicationContext;
val activity = context.currentActivity;
callback.resolve(Settings.canDrawOverlays(activity));
val context = reactApplicationContext
val activity = context.currentActivity
callback.resolve(Settings.canDrawOverlays(activity))
}

@ReactMethod fun askDrawOverAppsPermission() {
val context = reactApplicationContext;
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:com.noxplay.noxplayer"));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
val context = reactApplicationContext
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:com.noxplay.noxplayer"))
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}

@ReactMethod fun keepScreenOn(screenOn: Boolean = true) {
val context = reactApplicationContext;
val activity = context.currentActivity;
val window = activity?.window;
val context = reactApplicationContext
val activity = context.currentActivity
val window = activity?.window
if (screenOn) {
window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
window?.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
} else {
window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
window?.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
}

@ReactMethod fun isGestureNavigationMode(callback: Promise) {
val context = reactApplicationContext
callback.resolve(Settings.Secure.getInt(context.contentResolver, "navigation_mode", 0) == 2)
}
}
2 changes: 0 additions & 2 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const path = require('path');

module.exports = api => {
const isTest = api.env('test');
if (isTest) {
Expand Down
17 changes: 11 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@react-native-async-storage/async-storage": "^1.18.1",
"@react-native-community/netinfo": "^9.3.10",
"@react-native-cookies/cookies": "git+https://github.com/alexhernandez/cookies.git#patch-1",
"@react-native/metro-config": "0.72.9",
"@react-native/metro-config": "^0.74.0",
"@react-navigation/drawer": "^6.6.2",
"@react-navigation/material-top-tabs": "^6.6.2",
"@react-navigation/native": "^6.1.6",
Expand Down Expand Up @@ -55,10 +55,11 @@
"lottie-react-native": "^6.2.0",
"lru-cache": "7.14.0",
"md5": "^2.3.0",
"metro": "^0.79.1",
"qs": "^6.11.2",
"react": "18.2.0",
"react-i18next": "^12.2.2",
"react-native": "0.72.4",
"react-native": "0.72.6",
"react-native-app-auth": "^7.0.0",
"react-native-background-timer": "git+https://github.com/lovegaoshi/react-native-background-timer.git",
"react-native-blob-jsi-helper": "git+https://github.com/lovegaoshi/react-native-blob-jsi-helper.git",
Expand All @@ -85,17 +86,21 @@
"react-native-vector-icons": "^9.2.0",
"react-native-video": "^5.2.1",
"react-native-webview": "^13.3.0",
"react-native-windows": "^0.65.0-0",
"react-native-windows": "^0.72.14",
"react-use": "^17.4.0",
"use-debounce": "^9.0.4",
"uuid": "^9.0.0",
"ytdl-core": "git+https://[email protected]/lovegaoshi/node-ytdl-core.git",
"zustand": "^4.3.7"
},
"resolutions": {
"metro": "^0.79.1"
},
"devDependencies": {
"@babel/core": "^7.22.11",
"@babel/preset-env": "^7.22.10",
"@babel/runtime": "^7.20.0",
"@babel/core": "^7.23.2",
"@babel/preset-env": "^7.23.2",
"@babel/preset-typescript": "^7.23.2",
"@babel/runtime": "^7.23.2",
"@react-native-community/eslint-config": "^3.2.0",
"@tsconfig/react-native": "^2.0.2",
"@types/jest": "^29.2.1",
Expand Down
27 changes: 23 additions & 4 deletions src/AzusaPlayer.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import React from 'react';
import React, { useEffect } from 'react';
import { View } from 'react-native';
import {
NavigationContainer,
DarkTheme as NavigationDarkTheme,
DefaultTheme as NavigationDefaultTheme,
ParamListBase,
} from '@react-navigation/native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import {
createDrawerNavigator,
DrawerNavigationProp,
} from '@react-navigation/drawer';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
import {
IconButton,
Expand All @@ -16,6 +20,7 @@ import {
} from 'react-native-paper';
import merge from 'deepmerge';
import { useTranslation } from 'react-i18next';

import { Player } from './components/player/View';
import Playlist from './components/playlist/View';
import PlayerBottomPanel from './components/player/PlayerProgressControls';
Expand All @@ -27,6 +32,7 @@ import DummySettings from './components/setting/DummySettings';
import './localization/i18n';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { ICONS } from '@enums/Icons';
import NoxAndroidBottomTab from './components/bottomtab/NoxBottomTab';

const { LightTheme, DarkTheme } = adaptNavigationTheme({
reactNavigationLight: NavigationDefaultTheme,
Expand All @@ -37,9 +43,15 @@ const CombinedDefaultTheme = merge(MD3LightTheme, LightTheme);
const CombinedDarkTheme = merge(MD3DarkTheme, DarkTheme);
const PlayerStyle = { backgroundColor: 'transparent' };

const NoxPlayer = () => {
interface Props {
navigation: DrawerNavigationProp<ParamListBase>;
setNavigation?: (val: DrawerNavigationProp<ParamListBase>) => void;
}
const NoxPlayer = ({ navigation, setNavigation = () => undefined }: Props) => {
const Tab = createMaterialTopTabNavigator();

useEffect(() => setNavigation(navigation), []);

return (
<View style={{ flex: 1, justifyContent: 'flex-end' }}>
<Tab.Navigator style={PlayerStyle}>
Expand Down Expand Up @@ -67,6 +79,12 @@ const AzusaPlayer = () => {
? CombinedDarkTheme
: CombinedDefaultTheme;
const insets = useSafeAreaInsets();
const [navigation, setNavigation] = React.useState<
DrawerNavigationProp<ParamListBase> | undefined
>(undefined);

const NoxPlayer2 = ({ navigation }: Props) =>
NoxPlayer({ navigation, setNavigation });

return (
<PaperProvider
Expand Down Expand Up @@ -107,7 +125,7 @@ const AzusaPlayer = () => {
title: String(t('appDrawer.homeScreenName')),
header: () => null,
}}
component={NoxPlayer}
component={NoxPlayer2}
/>
<Drawer.Screen
name={ViewEnum.EXPORE}
Expand All @@ -127,6 +145,7 @@ const AzusaPlayer = () => {
component={Settings}
/>
</Drawer.Navigator>
<NoxAndroidBottomTab navigation={navigation} />
</View>
</NavigationContainer>
</PaperProvider>
Expand Down
121 changes: 121 additions & 0 deletions src/components/bottomtab/NoxBottomTab.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import React, { useEffect } from 'react';
import { NativeModules, Platform, StyleSheet, View } from 'react-native';
import { IconButton } from 'react-native-paper';
import { useNavigation, ParamListBase } from '@react-navigation/native';
import {
DrawerNavigationProp,
getDrawerStatusFromState,
} from '@react-navigation/drawer';

import { ViewEnum } from '@enums/View';
import { useNoxSetting } from '@hooks/useSetting';

const { NoxAndroidAutoModule } = NativeModules;

interface IconProps {
icon: string;
onPress: () => void;
}
const BottomIconButton = ({ icon, onPress }: IconProps) => {
return (
<IconButton
icon={icon}
style={styles.iconButton}
size={40}
onPress={onPress}
/>
);
};

enum Routes {
playlist = 'playlist-music',
music = 'music-note',
explore = 'compass',
setting = 'cog',
}

interface Props {
navigation?: DrawerNavigationProp<ParamListBase>;
}
const NoxAndroidBottomTab = ({ navigation }: Props) => {
const [gestureMode, setGestureMode] = React.useState(false);
const navigationGlobal = useNavigation();
const playerStyle = useNoxSetting(state => state.playerStyle);
const [route, setRoute] = React.useState('music');

useEffect(() => {
// TODO: how to use await instead of states and useEffect?
if (Platform.OS === 'android') {
NoxAndroidAutoModule.isGestureNavigationMode().then(setGestureMode);
}
}, []);

const isDrawerOpen = () => {
if (navigation === undefined) return false;
return getDrawerStatusFromState(navigation.getState()) === 'open';
};

const onDrawerPress = () => {
if (navigation === undefined) return;
setRoute(Routes.playlist);
if (isDrawerOpen()) {
navigation.closeDrawer();
return;
}
navigation.openDrawer();
};

const renderIcon = (icon: Routes) =>
route === icon ? icon : `${icon}-outline`;

if (gestureMode) {
return (
<View
style={[
styles.panel,
{ backgroundColor: playerStyle.colors.background },
]}
>
<BottomIconButton
icon={renderIcon(Routes.playlist)}
onPress={onDrawerPress}
/>
<BottomIconButton
icon={renderIcon(Routes.music)}
onPress={() => {
navigationGlobal.navigate(ViewEnum.PLAYER_HOME as never);
setRoute(Routes.music);
}}
/>
<BottomIconButton
icon={renderIcon(Routes.explore)}
onPress={() => {
navigationGlobal.navigate(ViewEnum.EXPORE as never);
setRoute(Routes.explore);
}}
/>
<BottomIconButton
icon={renderIcon(Routes.setting)}
onPress={() => {
navigationGlobal.navigate(ViewEnum.SETTINGS as never);
setRoute(Routes.setting);
}}
/>
</View>
);
}
return <></>;
};

const styles = StyleSheet.create({
panel: {
flexDirection: 'row',
},
iconButton: {
flex: 1,
borderRadius: 30,
marginVertical: 3,
},
});

export default NoxAndroidBottomTab;
1 change: 1 addition & 0 deletions src/components/player/Lyric.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export const LyricView = ({
if (hasLrcFromLocal()) {
logger.log('Loading Lrc from localStorage...');
const lrcDetail = lyricMapping.get(track?.song.id);
if (lrcDetail === undefined) return;
searchLyric(lrcDetail?.lyricKey, setLrc);
setLrcOption({ key: lrcDetail?.lyricKey });
setCurrentTimeOffset(lrcDetail!.lyricOffset);
Expand Down
2 changes: 1 addition & 1 deletion src/components/player/PlayerControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,5 @@ const styles = StyleSheet.create({
justifyContent: 'center',
alignItems: 'center',
},
btnSpacer: { width: 6 },
btnSpacer: { width: 8 },
});
7 changes: 1 addition & 6 deletions src/components/player/TrackInfo/SongMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,15 +182,10 @@ export default ({
title={t('SongOperations.songR128gain')}
/>
<ABSliderMenu song={song} closeMenu={closeMenu} />
<Menu.Item
leadingIcon={ICONS.REMOVE}
onPress={() => removeSongs()}
title={t('SongOperations.songRemoveTitle')}
/>
<Menu.Item
leadingIcon={ICONS.REMOVE_AND_BAN_BVID}
onPress={() => removeSongs(true)}
title={t('SongOperations.songRemoveNBanTitle')}
title={t('SongOperations.songRemoveTitle')}
/>
</Menu>
);
Expand Down
27 changes: 4 additions & 23 deletions src/components/playlist/PlaylistInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ export default ({
const searchBkgrdWidth = useRef(new Animated.Value(0)).current;
const searchBkgrdHeight = useRef(new Animated.Value(0)).current;
const [searchVisible, setSearchVisible] = useState(search);
// TODO: a more elegant way to signal content update
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const playlistInfoUpdate = useNoxSetting(state => state.playlistInfoUpdate);
const playlistSearchAutoFocus: boolean = useNoxSetting(
state => state.playlistSearchAutoFocus
);
Expand Down Expand Up @@ -155,27 +158,7 @@ export default ({
]).start(() => setSearchVisible(false));
}
}, [search]);

/**
* pull down menu:
<Animated.View
style={[
{
position: 'absolute',
backgroundColor: 'grey',
width: searchBkgrdWidth.interpolate({
inputRange: [0, 100],
outputRange: ['0%', '100%'],
}),
height: searchBkgrdHeight.interpolate({
inputRange: [0, 100],
outputRange: [50, 100],
}),
},
]}
></Animated.View>
*/


return (
<View style={styles.container}>
<Animated.View
Expand All @@ -199,7 +182,6 @@ export default ({
style={styles.textInput}
inputStyle={styles.searchInput}
ref={searchContainerRef}
// autoFocus={playlistSearchAutoFocus}
selectTextOnFocus
selectionColor={playerStyle.customColors.textInputSelectionColor}
icon={search ? 'format-list-checkbox' : () => undefined}
Expand Down Expand Up @@ -240,6 +222,5 @@ const styles = StyleSheet.create({
position: 'absolute',
paddingLeft: 15,
zIndex: -1,
// Add any additional styles for the Pressable component here
},
});
Loading

1 comment on commit 68317dd

@vercel
Copy link

@vercel vercel bot commented on 68317dd Oct 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.