Skip to content

Commit

Permalink
feat: random anime button
Browse files Browse the repository at this point in the history
  • Loading branch information
hoangvu12 committed Sep 8, 2024
1 parent 8c1a9ab commit 169cb0a
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 2 deletions.
8 changes: 8 additions & 0 deletions src/gql/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const documents = {
types.AiringScheduleDocument,
'\n query PopularThisSeason($season: MediaSeason, $seasonYear: Int) {\n Page(page: 1, perPage: 10) {\n media(\n type: ANIME\n sort: [POPULARITY_DESC]\n season: $season\n seasonYear: $seasonYear\n isAdult: false\n countryOfOrigin: "JP"\n ) {\n ...CardMedia\n }\n }\n }\n':
types.PopularThisSeasonDocument,
'\n query GetMedia($page: Int!) {\n Page(page: $page, perPage: 1) {\n media(type: ANIME, isAdult: false) {\n id\n }\n }\n }\n':
types.GetMediaDocument,
'\n query UpcomingNextSeason($season: MediaSeason, $seasonYear: Int) {\n Page(page: 1, perPage: 10) {\n media(\n type: ANIME\n sort: [POPULARITY_DESC]\n season: $season\n seasonYear: $seasonYear\n isAdult: false\n countryOfOrigin: "JP"\n ) {\n ...CardMedia\n }\n }\n }\n':
types.UpcomingNextSeasonDocument,
'\n fragment WatchCard on Media {\n id\n title {\n userPreferred\n }\n coverImage {\n large\n }\n bannerImage\n ...MediaUnitStatsMedia\n }\n':
Expand Down Expand Up @@ -163,6 +165,12 @@ export function graphql(
export function graphql(
source: '\n query PopularThisSeason($season: MediaSeason, $seasonYear: Int) {\n Page(page: 1, perPage: 10) {\n media(\n type: ANIME\n sort: [POPULARITY_DESC]\n season: $season\n seasonYear: $seasonYear\n isAdult: false\n countryOfOrigin: "JP"\n ) {\n ...CardMedia\n }\n }\n }\n'
): (typeof documents)['\n query PopularThisSeason($season: MediaSeason, $seasonYear: Int) {\n Page(page: 1, perPage: 10) {\n media(\n type: ANIME\n sort: [POPULARITY_DESC]\n season: $season\n seasonYear: $seasonYear\n isAdult: false\n countryOfOrigin: "JP"\n ) {\n ...CardMedia\n }\n }\n }\n'];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(
source: '\n query GetMedia($page: Int!) {\n Page(page: $page, perPage: 1) {\n media(type: ANIME, isAdult: false) {\n id\n }\n }\n }\n'
): (typeof documents)['\n query GetMedia($page: Int!) {\n Page(page: $page, perPage: 1) {\n media(type: ANIME, isAdult: false) {\n id\n }\n }\n }\n'];
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand Down
83 changes: 83 additions & 0 deletions src/gql/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4787,6 +4787,18 @@ export type PopularThisSeasonQuery = {
} | null;
};

export type GetMediaQueryVariables = Exact<{
page: Scalars['Int']['input'];
}>;

export type GetMediaQuery = {
__typename?: 'Query';
Page?: {
__typename?: 'Page';
media?: Array<{ __typename?: 'Media'; id: number } | null> | null;
} | null;
};

export type UpcomingNextSeasonQueryVariables = Exact<{
season?: InputMaybe<MediaSeason>;
seasonYear?: InputMaybe<Scalars['Int']['input']>;
Expand Down Expand Up @@ -9623,6 +9635,77 @@ export const PopularThisSeasonDocument = {
PopularThisSeasonQuery,
PopularThisSeasonQueryVariables
>;
export const GetMediaDocument = {
kind: 'Document',
definitions: [
{
kind: 'OperationDefinition',
operation: 'query',
name: { kind: 'Name', value: 'GetMedia' },
variableDefinitions: [
{
kind: 'VariableDefinition',
variable: { kind: 'Variable', name: { kind: 'Name', value: 'page' } },
type: {
kind: 'NonNullType',
type: { kind: 'NamedType', name: { kind: 'Name', value: 'Int' } },
},
},
],
selectionSet: {
kind: 'SelectionSet',
selections: [
{
kind: 'Field',
name: { kind: 'Name', value: 'Page' },
arguments: [
{
kind: 'Argument',
name: { kind: 'Name', value: 'page' },
value: {
kind: 'Variable',
name: { kind: 'Name', value: 'page' },
},
},
{
kind: 'Argument',
name: { kind: 'Name', value: 'perPage' },
value: { kind: 'IntValue', value: '1' },
},
],
selectionSet: {
kind: 'SelectionSet',
selections: [
{
kind: 'Field',
name: { kind: 'Name', value: 'media' },
arguments: [
{
kind: 'Argument',
name: { kind: 'Name', value: 'type' },
value: { kind: 'EnumValue', value: 'ANIME' },
},
{
kind: 'Argument',
name: { kind: 'Name', value: 'isAdult' },
value: { kind: 'BooleanValue', value: false },
},
],
selectionSet: {
kind: 'SelectionSet',
selections: [
{ kind: 'Field', name: { kind: 'Name', value: 'id' } },
],
},
},
],
},
},
],
},
},
],
} as unknown as DocumentNode<GetMediaQuery, GetMediaQueryVariables>;
export const UpcomingNextSeasonDocument = {
kind: 'Document',
definitions: [
Expand Down
86 changes: 86 additions & 0 deletions src/screens/anime/components/random-anime.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { useFocusEffect, useNavigation } from '@react-navigation/native';
import { ShuffleIcon } from 'lucide-react-native';
import React, { useState } from 'react';
import { ToastAndroid } from 'react-native';

import { graphql } from '@/gql';
import anilistClient from '@/services/anilist';
import { ActivityIndicator, Button, Text } from '@/ui';

const randomAnimeDocument = graphql(`
query GetMedia($page: Int!) {
Page(page: $page, perPage: 1) {
media(type: ANIME, isAdult: false) {
id
}
}
}
`);

// Last updated: 2024-09-08
const totalAnimeCount = 17151;

const RandomAnime = () => {
const navigation = useNavigation();

const [isLoading, setIsLoading] = useState(false);

const [shouldShowLuckyText, setShouldShowLuckyText] = useState(false);

useFocusEffect(() => {
// 20% chance to show the lucky text
if (Math.random() < 0.2) {
setShouldShowLuckyText(true);
}
});

const handlePress = async () => {
setIsLoading(true);

const randomPage = Math.ceil(Math.random() * totalAnimeCount);

const randomAnimeResponse = await anilistClient.request(
randomAnimeDocument,
{
page: randomPage,
}
);

const id = randomAnimeResponse?.Page?.media?.[0]?.id;

setIsLoading(false);

if (!id) {
ToastAndroid.show(
'Cannot find any anime, you are unlucky!',
ToastAndroid.SHORT
);

return;
}

navigation.navigate('AnimeDetails', {
mediaId: id,
});
};

return (
<Button
onPress={handlePress}
variant="defaults"
className="grow bg-thunder-800"
>
{isLoading ? (
<ActivityIndicator className="h-6 w-6" color="white" />
) : (
<ShuffleIcon size={24} color="white" />
)}

<Text className="ml-1">
{shouldShowLuckyText ? 'I feel lucky' : 'Random Anime'}
</Text>
</Button>
);
};

export default RandomAnime;
2 changes: 1 addition & 1 deletion src/screens/anime/components/your-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const YourList = () => {
navigation.navigate('AnimeList');
}}
variant="defaults"
className="mt-4 bg-thunder-800"
className="mr-2 grow bg-thunder-800"
>
<Text>Your Anime List</Text>
</Button>
Expand Down
7 changes: 6 additions & 1 deletion src/screens/anime/screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { BannerList } from '@/ui/banner-card';
import AiringTodayList from './components/airing-today-list';
import GenreList from './components/genre-list';
import PopularThisSeason from './components/popular-this-season';
import RandomAnime from './components/random-anime';
import UpcomingNextSeason from './components/upcoming-next-season';
import WatchedList from './components/watched-list';
import YourList from './components/your-list';
Expand All @@ -37,7 +38,11 @@ export const AnimeHomeScreen = () => {
<View className="flex-1 space-y-4 p-4">
<WatchedList />

<YourList />
<View className="mt-4 flex flex-row">
<YourList />

<RandomAnime />
</View>

<View className="w-full space-y-2">
<Text variant="lg">Genres</Text>
Expand Down

0 comments on commit 169cb0a

Please sign in to comment.