Skip to content

Commit

Permalink
Merge pull request #360 from lovegaoshi/dev
Browse files Browse the repository at this point in the history
feat: explore
  • Loading branch information
lovegaoshi authored Apr 8, 2024
2 parents 8c3274f + 600de71 commit 028ce68
Show file tree
Hide file tree
Showing 6 changed files with 355 additions and 184 deletions.
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@
"fflate": "^0.8.2",
"ffmpeg-kit-react-native": "^6.0.2",
"he": "^1.2.0",
"i18next": "^23.10.1",
"i18next": "^23.11.0",
"libmuse": "git+https://github.com/lovegaoshi/muse.git#apm-release",
"lottie-react-native": "^6.7.0",
"lottie-react-native": "^6.7.2",
"lru-cache": "7.14.0",
"md5": "^2.3.0",
"metro": "^0.80.8",
Expand Down Expand Up @@ -124,22 +124,22 @@
"@types/he": "^1.2.3",
"@types/jest": "^29.5.12",
"@types/md5": "^2.3.5",
"@types/node": "^20.12.4",
"@types/node": "^20.12.5",
"@types/react": "^18.2.74",
"@types/react-native": "^0.73.0",
"@types/react-native-background-timer": "^2.0.2",
"@types/react-native-share-menu": "^5.0.5",
"@types/react-native-video": "^5.0.20",
"@types/react-test-renderer": "^18.0.6",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0",
"@typescript-eslint/eslint-plugin": "^7.6.0",
"@typescript-eslint/parser": "^7.6.0",
"@welldone-software/why-did-you-render": "^8.0.1",
"argparse": "^2.0.1",
"babel-jest": "^29.6.4",
"babel-plugin-module-resolver": "^5.0.0",
"cpx": "^1.5.0",
"eslint": "^8.56.0",
"eslint": "^9.0.0",
"eslint-config-prettier": "^9.0.0",
"eslint-import-resolver-babel-module": "^5.3.2",
"eslint-plugin-import": "^2.29.1",
Expand All @@ -154,9 +154,9 @@
"react-native-clean-project": "^4.0.1",
"react-native-dotenv": "^3.4.11",
"react-test-renderer": "18.2.0",
"reactotron-react-native": "^5.1.5",
"reactotron-react-native": "^5.1.6",
"rimraf": "^5.0.5",
"typescript": "5.4.3"
"typescript": "5.4.4"
},
"engines": {
"node": ">=18.0.0"
Expand Down
129 changes: 119 additions & 10 deletions src/components/explore/bilibili/View.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Image } from 'expo-image';
import { useTranslation } from 'react-i18next';
import { useNavigation } from '@react-navigation/native';

import { chunkArray } from '@utils/Utils';
import { fetchDynamic } from '@utils/mediafetch/biliDynamic';
import { fetchRanking } from '@utils/mediafetch/biliRanking';
import { styles } from '@components/style';
Expand All @@ -25,13 +26,75 @@ interface BiliCatSongs {

interface BiliSongCardProp {
songs: NoxMedia.Song[];
category: string;
title?: string;
totalSongs?: NoxMedia.Song[];
}

const BiliSongCard = ({
songs = [],
category = 'Dummy Category',
}: BiliSongCardProp) => {
const BiliSongRow = ({ songs = [], title, totalSongs }: BiliSongCardProp) => {
const navigationGlobal = useNavigation();
const playerStyle = useNoxSetting(state => state.playerStyle);
const { playAsSearchList } = usePlayback();

const fontColor = playerStyle.metaData.darkTheme ? 'white' : 'black';

return (
<View
style={{
width: Dimensions.get('window').width,
paddingRight: 10,
paddingLeft: 5,
}}
>
{title && (
<Text style={{ fontSize: 20, color: fontColor, paddingBottom: 5 }}>
{title}
</Text>
)}
<FlatList
showsHorizontalScrollIndicator={false}
data={songs}
horizontal
renderItem={({ item }) => (
<View style={{ paddingHorizontal: 5, flex: 1 }}>
<TouchableOpacity
onPress={() => {
navigationGlobal.navigate(ViewEnum.PLAYER_PLAYLIST as never);
playAsSearchList({ songs: totalSongs || songs, song: item });
}}
>
<Image
style={{ width: 140, height: 140, borderRadius: 5 }}
source={{ uri: item.cover }}
/>
<View style={{ flex: 1 }}>
<Text
style={{
color: fontColor,
paddingLeft: 5,
width: 140,
}}
variant="titleMedium"
numberOfLines={2}
>
{item.name}
</Text>
<Text
style={{ color: 'grey', paddingLeft: 5, width: 140 }}
variant="titleSmall"
numberOfLines={1}
>
{item.singer}
</Text>
</View>
</TouchableOpacity>
</View>
)}
/>
</View>
);
};

const BiliSongCard = ({ songs = [], title, totalSongs }: BiliSongCardProp) => {
const navigationGlobal = useNavigation();
const playerStyle = useNoxSetting(state => state.playerStyle);
const { playAsSearchList } = usePlayback();
Expand All @@ -47,7 +110,7 @@ const BiliSongCard = ({
paddingLeft: 5,
}}
>
<Text style={{ fontSize: 20, color: fontColor }}>{category}</Text>
{title && <Text style={{ fontSize: 20, color: fontColor }}>{title}</Text>}
<FlatList
showsVerticalScrollIndicator={false}
data={songs}
Expand All @@ -57,7 +120,7 @@ const BiliSongCard = ({
style={{ height: 70, flexDirection: 'row' }}
onPress={() => {
navigationGlobal.navigate(ViewEnum.PLAYER_PLAYLIST as never);
playAsSearchList({ songs, song: item });
playAsSearchList({ songs: totalSongs || songs, song: item });
}}
>
<Image
Expand Down Expand Up @@ -110,7 +173,7 @@ const BiliSongCatsCard = ({ songs = {} }: { songs?: BiliCatSongs }) => {
{Object.keys(songs).map(k => (
<BiliSongCard
key={k}
category={t(`BiliCategory.${k}`)}
title={t(`BiliCategory.${k}`)}
songs={songs[Number(k)]}
/>
))}
Expand All @@ -120,7 +183,46 @@ const BiliSongCatsCard = ({ songs = {} }: { songs?: BiliCatSongs }) => {
);
};

const BiliSongsTabCard = ({
songs = {},
title,
}: {
songs?: BiliCatSongs;
title: string;
}) => {
const concatSongs = Object.values(songs).reduce(
(acc, curr) => acc.concat(curr),
[]
);
const splicedSongs: NoxMedia.Song[][] = chunkArray(concatSongs, 4);

return (
<View>
<Text style={{ fontSize: 20, paddingLeft: 5, paddingBottom: 10 }}>
{title}
</Text>
<ScrollView
horizontal
disableIntervalMomentum
snapToInterval={Dimensions.get('window').width * 0.8}
showsVerticalScrollIndicator={false}
showsHorizontalScrollIndicator={false}
>
{splicedSongs.map((k, i) => (
<BiliSongCard
key={`BiliRankTab${i}`}
songs={k}
totalSongs={concatSongs}
/>
))}
<View style={{ width: Dimensions.get('window').width * 0.2 }}></View>
</ScrollView>
</View>
);
};

export default () => {
const { t } = useTranslation();
const [biliDynamic, setBiliDynamic] = React.useState<BiliCatSongs>({});
const [biliRanking, setBiliRanking] = React.useState<BiliCatSongs>({});
const [refreshing, setRefreshing] = React.useState(false);
Expand All @@ -129,7 +231,7 @@ export default () => {
const initData = async () =>
Promise.all([
fetchRanking().then(setBiliRanking),
// fetchDynamic().then(setBiliDynamic),
fetchDynamic().then(setBiliDynamic),
]);

const onRefresh = React.useCallback(() => {
Expand Down Expand Up @@ -160,7 +262,14 @@ export default () => {
<Text style={{ paddingHorizontal: 5, fontSize: 20 }}>
Bilibili experimental discover page
</Text>
<BiliSongCatsCard songs={biliRanking} />
<BiliSongsTabCard songs={biliRanking} title={t('BiliCategory.ranking')} />
{Object.keys(biliDynamic).map((k, i) => (
<BiliSongRow
key={`BiliDynamicRow${i}`}
songs={biliDynamic[Number(k)]}
title={t(`BiliCategory.${k}`)}
/>
))}
</ScrollView>
);
};
2 changes: 1 addition & 1 deletion src/enums/MediaFetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ MV mv 193 为音乐作品配合拍摄或制作的音乐录影带(Music Video
音乐教学 tutorial 244 以音乐教学为目的的内容 /v/music/tutorial
电音(已下线) electronic 194 以电子合成器、音乐软体等产生的电子声响制作的音乐 /v/music/electronic
*/
export const BiliMusicTid = [28, 31, 59, 193, 29];
export const BiliMusicTid = [28, 31, 59, 193]; // , 29
14 changes: 2 additions & 12 deletions src/utils/ChromeStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { dummyPlaylist, dummyPlaylistList } from '../objects/Playlist';
import { NoxRepeatMode } from '../enums/RepeatMode';
import { PLAYLIST_ENUMS } from '../enums/Playlist';
import AzusaTheme from '../components/styles/AzusaTheme';
import { chunkArray as chunkArrayRaw, arrayToObject } from '../utils/Utils';
import { chunkArray, arrayToObject } from '../utils/Utils';
import {
STORAGE_KEYS,
appID,
Expand Down Expand Up @@ -147,16 +147,6 @@ export const removeCookie = async (site: string) => {
saveItem(STORAGE_KEYS.COOKIES, cookies);
};

/**
* splits an array to chunks of given size.
* @param arr
* @param size
* @returns
*/
const chunkArray = <T>(arr: Array<T>, size = MAX_SONGLIST_SIZE): Array<T[]> => {
return chunkArrayRaw(arr, size);
};

/**
* a generic chunk splitter to store arrays that may exceed 2MB storage limits.
* see known storage limits:
Expand All @@ -170,7 +160,7 @@ const saveChucked = async (
saveToStorage = true
) => {
// splice into chunks
const chuckedObject = chunkArray(objects);
const chuckedObject = chunkArray(objects, MAX_SONGLIST_SIZE);
const chuckedIndices = chuckedObject.map((val, index) => `${key}.${index}`);
chuckedObject.forEach((list, index) => saveItem(chuckedIndices[index], list));
if (saveToStorage) {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const getUniqObjects = <T>(
* @param size
* @returns
*/
export const chunkArray = <T>(arr: Array<T>, size: number): Array<T[]> => {
export const chunkArray = <T>(arr: Array<T>, size = 400): Array<T[]> => {
return arr.reduce(
(chunks, item, index) => {
const chunkIndex = Math.floor(index / size);
Expand Down
Loading

0 comments on commit 028ce68

Please sign in to comment.