Skip to content

Commit

Permalink
Merge pull request #402 from lovegaoshi/dev
Browse files Browse the repository at this point in the history
feat: accent color
  • Loading branch information
lovegaoshi authored May 2, 2024
2 parents 001dfde + 686373c commit daf3d07
Show file tree
Hide file tree
Showing 20 changed files with 710 additions and 72 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"react-native-draggable-flatlist": "^4.0.1",
"react-native-gesture-handler": "2.16.0",
"react-native-get-random-values": "^1.11.0",
"react-native-image-colors": "^2.4.0",
"react-native-lyric": "git+https://github.com/lovegaoshi/react-native-lyric.git#dev",
"react-native-pager-view": "^6.3.1",
"react-native-paper": "^5.12.3",
Expand Down
10 changes: 10 additions & 0 deletions src/components/background/AccentColorBackground.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import { View } from 'react-native';

import useAccentColor from '@hooks/useAccentColor';

export default ({ children }: { children: React.JSX.Element }) => {
const { backgroundColor } = useAccentColor();

return <View style={{ backgroundColor, flex: 1 }}>{children}</View>;
};
16 changes: 16 additions & 0 deletions src/components/background/EmptyBackground.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { View } from 'react-native';

import { useNoxSetting } from '@stores/useApp';
import useAccentColor from '@hooks/useAccentColor';

export default ({ children }: { children: React.JSX.Element }) => {
const playerStyle = useNoxSetting(state => state.playerStyle);
const {} = useAccentColor(true);

return (
<View style={{ backgroundColor: playerStyle.colors.background, flex: 1 }}>
{children}
</View>
);
};
8 changes: 3 additions & 5 deletions src/components/background/MainBackground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import React, { useState } from 'react';
import { ImageBackground, Dimensions, View, StyleSheet } from 'react-native';
// import { Video, ResizeMode } from 'expo-av';
import Video from 'react-native-video';

import { useNoxSetting } from '@stores/useApp';
import { customReqHeader } from '@utils/BiliFetch';
import { logger } from '@utils/Logger';
import { useIsLandscape } from '@hooks/useOrientation';
import resolveBackgroundImage, {
RESOLVE_TYPE,
} from '@utils/mediafetch/mainbackgroundfetch';
import EmptyBackground from './AccentColorBackground';

const MainBackground = ({ children }: { children: React.JSX.Element }) => {
const playerStyle = useNoxSetting(state => state.playerStyle);
Expand Down Expand Up @@ -82,11 +84,7 @@ const MainBackground = ({ children }: { children: React.JSX.Element }) => {
</>
);
default:
return (
<View style={{ backgroundColor: playerStyle.colors.background }}>
{children}
</View>
);
return <EmptyBackground>{children}</EmptyBackground>;
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/dialogs/PortaledInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useNoxSetting } from '@stores/useApp';

interface InputProps {
defaultName: string;
handleSubmit: () => void;
handleSubmit?: () => void;
label: string;
autofocus?: boolean;
selectTextOnFocus?: boolean;
Expand Down
3 changes: 0 additions & 3 deletions src/components/playlist/Menu/PlaylistSettingsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,23 +57,20 @@ export default ({
<Dialog visible={visible} onDismiss={handleClose}>
<Dialog.Content>
<PortaledInput
handleSubmit={() => undefined}
ref={nameRef}
label={'RenameSongDialog.label'}
defaultName={playlist.title}
autofocus={false}
selectTextOnFocus={false}
/>
<PortaledInput
handleSubmit={() => undefined}
ref={subRef}
label={'PlaylistSettingsDialog.subscribeUrlLabel'}
defaultName={playlist.subscribeUrl.join(';')}
autofocus={false}
selectTextOnFocus={false}
/>
<PortaledInput
handleSubmit={() => undefined}
ref={blacklistRef}
label={'PlaylistSettingsDialog.blacklistedUrlLabel'}
defaultName={playlist.blacklistedUrl.join(';')}
Expand Down
39 changes: 26 additions & 13 deletions src/components/playlist/SongList/SongInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ interface Props {
networkCellular?: boolean;
}

const isItemSolid = (
item: NoxMedia.Song,
networkCellular = false,
dataSaver = false
) => {
if (item.liveStatus === false) return false;
if (!networkCellular) return true;
if (dataSaver && !NoxCache.noxMediaCache?.peekCache(item)) {
return false;
}
return true;
};

const SongInfo = ({
item,
index,
Expand Down Expand Up @@ -72,15 +85,6 @@ const SongInfo = ({
};
const checked = selected[getSongIndex()];

const isItemSolid = () => {
if (item.liveStatus === false) return false;
if (!networkCellular) return true;
if (playerSetting.dataSaver && !NoxCache.noxMediaCache?.peekCache(item)) {
return false;
}
return true;
};

return (
<View
style={[
Expand All @@ -89,7 +93,9 @@ const SongInfo = ({
backgroundColor: currentPlaying
? playerStyle.customColors.playlistDrawerBackgroundColorTransparent
: 'transparent',
opacity: isItemSolid() ? undefined : 0.5,
opacity: isItemSolid(item, networkCellular, playerSetting.dataSaver)
? undefined
: 0.5,
},
]}
>
Expand All @@ -98,17 +104,17 @@ const SongInfo = ({
onPress={checking ? toggleCheck : () => playSong(item)}
>
<View style={styles.row}>
<View style={{ flex: 5 }}>
<View style={styles.songDetails}>
<View style={styles.row}>
{checking && (
<View style={{ flex: 1 }}>
<View style={styles.checkBox}>
<Checkbox
status={checked ? 'checked' : 'unchecked'}
onPress={toggleCheck}
/>
</View>
)}
<View style={{ flex: 4.9 }}>
<View style={styles.songTitle}>
<Text variant="bodyLarge" numberOfLines={3}>{`${String(
index + 1
// ${' (' + item.source + ')' || ''}
Expand Down Expand Up @@ -159,6 +165,13 @@ const styles = StyleSheet.create({
time: {
top: 13,
},
songTitle: {
flex: 4.9,
},
checkBox: {
flex: 1,
},
songDetails: { flex: 5 },
});

export default SongInfo;
22 changes: 20 additions & 2 deletions src/components/setting/AboutSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { View, ScrollView } from 'react-native';
import { Text } from 'react-native-paper';
import { View, ScrollView, Linking } from 'react-native';
import { Text, Button } from 'react-native-paper';
import { useTranslation } from 'react-i18next';

import { useNoxSetting } from '@stores/useApp';
Expand Down Expand Up @@ -46,6 +46,24 @@ export default () => {
>
{t('About.About1')}
</Text>
<View style={{ flexDirection: 'row', justifyContent: 'center' }}>
<Button
onPress={() =>
Linking.openURL(
'https://github.com/lovegaoshi/azusa-player-mobile/releases/latest'
)
}
>
{'Gayhub'}
</Button>
<Button
onPress={() =>
Linking.openURL('https://space.bilibili.com/3493085134719196')
}
>
{'Bilibili'}
</Button>
</View>
</ScrollView>
</View>
);
Expand Down
35 changes: 11 additions & 24 deletions src/components/setting/appearances/NoWeebButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Text } from 'react-native-paper';
import GenericDialog from '@components/dialogs/GenericDialog';
import { useNoxSetting } from '@stores/useApp';
import { SettingListItem } from '../useRenderSetting';
import { replaceStyleColor } from '@components/style';

export default () => {
const { t } = useTranslation();
Expand All @@ -27,30 +28,16 @@ export default () => {

const onSubmit = () => {
setVisible(false);
setPlayerStyle({
...playerStyle,
gifs: [],
backgroundImages: [],
backgroundImagesLandscape: [],
customColors: {
...playerStyle.customColors,
playlistDrawerBackgroundColor: contrastColor,
textInputSelectionColor: contrastColor,
progressThumbTintColor: primaryColor,
progressMinimumTrackTintColor: primaryColor,
},
colors: {
...playerStyle.colors,
primary: primaryColor,
secondary: secondaryColor,
background: backgroundColor,
onSurface: primaryColor,
onSurfaceVariant: primaryColor,
text: primaryColor,
},
bkgrdImg: '',
bkgrdImgLandscape: '',
});
setPlayerStyle(
replaceStyleColor({
playerStyle,
primaryColor,
secondaryColor,
contrastColor,
backgroundColor,
noWeeb: true,
})
);
};

return (
Expand Down
6 changes: 6 additions & 0 deletions src/components/setting/appearances/View.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ const MainView = ({ navigation }: NoxComponent.NavigationProps) => {
settingCategory: 'AppearanceSettings',
}}
/>
<RenderSetting
item={{
settingName: 'accentColor',
settingCategory: 'AppearanceSettings',
}}
/>
<SelectDarkModeButton />
<NoWeebButton />
</ScrollView>
Expand Down
2 changes: 1 addition & 1 deletion src/components/setting/sync/PersonalCloudAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const noxRestore = async (cloudAddress: string, cloudID?: string) => {
// see https://github.com/facebook/react-native/commit/5b597b5ff94953accc635ed3090186baeecb3873
// and https://stackoverflow.com/questions/76056351/error-filereader-readasarraybuffer-is-not-implemented
const res = await axios.get(
`${await cloudAddress}download/${cloudID || (await getBiliUserKey())}`,
`${cloudAddress}download/${cloudID || (await getBiliUserKey())}`,
{
responseType: 'arraybuffer',
maxContentLength: Infinity,
Expand Down
47 changes: 47 additions & 0 deletions src/components/style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,53 @@ export const createStyle = (
});
};

interface ReplaceStyleColor {
playerStyle: NoxTheme.Style;
primaryColor?: string;
secondaryColor?: string;
contrastColor?: string;
backgroundColor?: string;
noWeeb?: boolean;
}
export const replaceStyleColor = ({
playerStyle,
primaryColor = playerStyle.colors.primary,
secondaryColor = playerStyle.colors.secondary,
contrastColor = playerStyle.customColors.playlistDrawerBackgroundColor,
backgroundColor = playerStyle.colors.background,
noWeeb = false,
}: ReplaceStyleColor) => {
const replacedStyle = {
...playerStyle,
customColors: {
...playerStyle.customColors,
playlistDrawerBackgroundColor: contrastColor,
textInputSelectionColor: contrastColor,
progressThumbTintColor: primaryColor,
progressMinimumTrackTintColor: primaryColor,
},
colors: {
...playerStyle.colors,
primary: primaryColor,
secondary: secondaryColor,
background: backgroundColor,
onSurface: primaryColor,
onSurfaceVariant: primaryColor,
text: primaryColor,
},
};
return noWeeb
? {
...replacedStyle,
gifs: [],
backgroundImages: [],
backgroundImagesLandscape: [],
bkgrdImg: '',
bkgrdImgLandscape: '',
}
: replacedStyle;
};

export const styles = StyleSheet.create({
flex: { flex: 1 },
screenContainer: {
Expand Down
2 changes: 1 addition & 1 deletion src/enums/Storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const DefaultSetting: NoxStorage.PlayerSettingDict = {
biliEditAPI: false,
keepForeground: false,
karaokeLyrics: false,
noWeebSkins: false,
accentColor: false,

appID: AppID,
language: undefined,
Expand Down
50 changes: 50 additions & 0 deletions src/hooks/useAccentColor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useEffect, useState } from 'react';
import { getColors } from 'react-native-image-colors';
import { colord } from 'colord';

import useActiveTrack from './useActiveTrack';
import { useNoxSetting } from '@stores/useApp';
import { replaceStyleColor } from '@components/style';
import logger from '@utils/Logger';

export default (replaceStyle = false) => {
const playerStyle = useNoxSetting(state => state.playerStyle);
const setPlayerStyle = useNoxSetting(state => state.setPlayerStyle);
const playerSetting = useNoxSetting(state => state.playerSetting);
const [backgroundColor, setBackgroundColor] = useState<string>(
playerStyle.colors.background
);
const { track } = useActiveTrack();

const getBackgroundColor = async () => {
if (!playerSetting.accentColor) return;
try {
if (track?.artwork) {
const color = await getColors(track?.artwork, {});
const resolvedColor =
color.platform === 'ios' ? color.primary : color.dominant;
const parsedColor = colord(resolvedColor);
setBackgroundColor(resolvedColor);
if (replaceStyle) {
setPlayerStyle(
replaceStyleColor({
playerStyle,
primaryColor: resolvedColor,
secondaryColor: parsedColor.lighten(0.2).toRgbString(),
contrastColor: parsedColor.invert().toRgbString(),
})
);
}
}
} catch (e) {
logger.warn(e);
setBackgroundColor(playerStyle.colors.background);
}
};

useEffect(() => {
getBackgroundColor();
}, [track]);

return { backgroundColor };
};
Loading

0 comments on commit daf3d07

Please sign in to comment.