Skip to content

Commit

Permalink
Merge pull request #105 from ErickLimaS/Cards/Options-btn
Browse files Browse the repository at this point in the history
Add Options Btn on Media Cards, Block Scroll when components is fullscreen, more...
  • Loading branch information
ErickLimaS authored Jul 13, 2024
2 parents a4c8ac1 + f763ad1 commit a6e5001
Show file tree
Hide file tree
Showing 38 changed files with 1,255 additions and 532 deletions.
2 changes: 1 addition & 1 deletion app/api/anilistMedias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function filterMediasWithAdultContent(mediasList: ApiDefaultResult[] | ApiAiring
axiosRetry(Axios, {
retries: 3,
retryDelay: (retryAttempt) => retryAttempt * 1200,
retryCondition: (error) => error.response?.status == 500 || error.response?.status == 503,
retryCondition: (error) => error.response?.status == 500 || error.response?.status == 404 || error.response?.status == 503,
onRetry: (retryNumber) => console.log(`retry: ${retryNumber} ${retryNumber == 3 ? " - Last Attempt" : ""}`)
})

Expand Down
49 changes: 49 additions & 0 deletions app/api/anilistQueryConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,18 @@ export function defaultApiQueryRequest(otherQueryFields?: unknown, otherMediasFi
}
description(asHtml: true)
isAdult
isFavourite
mediaListEntry {
id
mediaId
status
progress
media {
title{
romaji
}
}
}
status
relations{
nodes{
Expand Down Expand Up @@ -120,6 +132,19 @@ export function defaultApiQueryRequest(otherQueryFields?: unknown, otherMediasFi
}
updatedAt
favourites
isFavourite
mediaListEntry {
id
mediaId
status
progress
media {
title{
romaji
}
}
}
tags{
name
description
Expand Down Expand Up @@ -626,6 +651,19 @@ export function queryMediaWithUserAuthenticated(otherQueryFields?: unknown, othe
genres
type
format
description
isFavourite
mediaListEntry {
id
mediaId
status
progress
media {
title{
romaji
}
}
}
title{
romaji
native
Expand Down Expand Up @@ -725,6 +763,17 @@ export function queryMediaWithUserAuthenticated(otherQueryFields?: unknown, othe
volumes
countryOfOrigin
isLicensed
mediaListEntry {
id
mediaId
status
progress
media {
title{
romaji
}
}
}
source
hashtag
updatedAt
Expand Down
13 changes: 13 additions & 0 deletions app/api/anilistUsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,21 @@ export default {
medium
color
}
description
type
format
isFavourite
mediaListEntry {
id
mediaId
status
progress
media {
title{
romaji
}
}
}
bannerImage
season
seasonYear
Expand Down
94 changes: 46 additions & 48 deletions app/components/Buttons/AddToFavourites/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,22 @@ import { getAuth } from 'firebase/auth'
import { ApiDefaultResult } from '@/app/ts/interfaces/apiAnilistDataInterface'
import { useAuthState } from 'react-firebase-hooks/auth'
import { motion } from 'framer-motion';
import ShowUpLoginPanelAnimated from '../../UserLoginModal/animatedVariant'
import { updateUserFavouriteMedias } from '@/app/lib/user/userDocUpdateOptions'
import { useAppSelector } from '@/app/lib/redux/hooks'
import { useAppDispatch, useAppSelector } from '@/app/lib/redux/hooks'
import anilistUsers from '@/app/api/anilistUsers'
import { toggleShowLoginModalValue } from '@/app/lib/redux/features/loginModal'

export function Button({ mediaInfo, children, svgOnlyColor, isActiveOnAnilist }: { mediaInfo: ApiDefaultResult, children?: React.ReactNode[], svgOnlyColor?: string, isActiveOnAnilist?: boolean }) {
export function Button({ mediaInfo, children, svgOnlyColor, isActiveOnAnilist, customText }: {
mediaInfo: ApiDefaultResult, children?: React.ReactNode[], svgOnlyColor?: string, isActiveOnAnilist?: boolean, customText?: string
}) {

const [isLoading, setIsLoading] = useState<boolean>(false)
const [wasAddedToFavourites, setWasAddedToFavourites] = useState<boolean>(isActiveOnAnilist || false)

const [isUserModalOpen, setIsUserModalOpen] = useState(false)

const anilistUser = useAppSelector((state) => (state.UserInfo).value)

const dispatch = useAppDispatch()

const auth = getAuth()

const [user, loading] = useAuthState(auth)
Expand All @@ -32,18 +34,19 @@ export function Button({ mediaInfo, children, svgOnlyColor, isActiveOnAnilist }:

useEffect(() => {

if ((!user && !anilistUser) || loading) return
if (!loading) {

setIsUserModalOpen(false)
isMediaOnUserDoc()
isMediaOnUserDoc()

}

}, [user, anilistUser, loading])

// WHEN BUTTON IS CLICKED, RUN FUNCTION TO ADD OR REMOVE MEDIA FROM FIRESTORE
async function handleMediaOnFavourites() {

// Opens Login Modal
if (!user && !anilistUser) return setIsUserModalOpen(true)
if (!user && !anilistUser) return dispatch(toggleShowLoginModalValue())

setIsLoading(true)

Expand Down Expand Up @@ -91,45 +94,40 @@ export function Button({ mediaInfo, children, svgOnlyColor, isActiveOnAnilist }:
}

return (
<React.Fragment>

<ShowUpLoginPanelAnimated
apperanceCondition={isUserModalOpen}
customOnClickAction={() => setIsUserModalOpen(false)}
auth={auth}
/>

<motion.button
whileTap={{ scale: 0.85 }}
id={styles.container}
className={children ? styles.custom_text : ""}
onClick={() => handleMediaOnFavourites()}
disabled={isLoading}
data-added={wasAddedToFavourites}
data-unique-color={svgOnlyColor != undefined}
aria-label={wasAddedToFavourites ? "Click To Remove from Favourites" : "Click To Add To Favourites"}
title={wasAddedToFavourites ? `Remove ${mediaInfo.title && mediaInfo.title?.userPreferred} from Favourites` : `Add ${mediaInfo.title && mediaInfo.title?.userPreferred} To Favourites`}
>

{isLoading &&
(<LoadingSvg alt="Loading Icon" width={16} height={16} />)
}

{(!isLoading && wasAddedToFavourites) &&
(children ?
children[1] : (<><FavouriteFillSvg width={16} height={16} fill={"var(--brand-color)"} /> FAVOURITED</>)
)
}

{(!isLoading && !wasAddedToFavourites) &&
(children ?
children[0] : (<><FavouriteSvg width={16} height={16} fill={"var(--white-100)"} /> FAVOURITE</>)
)
}

</motion.button>

</React.Fragment>
<motion.button
whileTap={{ scale: 0.85 }}
id={styles.container}
className={children ? styles.custom_text : ""}
onClick={() => handleMediaOnFavourites()}
disabled={isLoading}
data-added={wasAddedToFavourites}
data-unique-color={svgOnlyColor != undefined}
aria-label={wasAddedToFavourites ? "Click To Remove from Favourites" : "Click To Add To Favourites"}
title={wasAddedToFavourites ?
`Remove ${mediaInfo.title && mediaInfo.title?.userPreferred} from Favourites`
: `Add ${mediaInfo.title && mediaInfo.title?.userPreferred} To Favourites`
}
>

{isLoading &&
(<LoadingSvg alt="Loading Icon" width={16} height={16} />)
}

{(!isLoading && wasAddedToFavourites) &&
(children ?
children[1] : (<><FavouriteFillSvg width={16} height={16} fill={svgOnlyColor || "var(--brand-color)"} /> FAVOURITED</>)
)
}

{(!isLoading && !wasAddedToFavourites) &&
(children ?
children[0] : (<><FavouriteSvg width={16} height={16} fill={svgOnlyColor || "var(--white-100)"} /> FAVOURITE</>)
)
}

{customText || ""}

</motion.button>
)
}

Expand Down
44 changes: 13 additions & 31 deletions app/components/Buttons/AddToList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,28 @@ import { getAuth } from 'firebase/auth'
import { ApiDefaultResult } from '@/app/ts/interfaces/apiAnilistDataInterface'
import { useAuthState } from 'react-firebase-hooks/auth'
import { AnimatePresence, motion } from 'framer-motion';
import ShowUpLoginPanelAnimated from '../../UserLoginModal/animatedVariant'
import { removeMediaOnListByStatus, updateUserMediaListByStatus } from '@/app/lib/user/userDocUpdateOptions'
import { useAppSelector } from '@/app/lib/redux/hooks'
import { useAppDispatch, useAppSelector } from '@/app/lib/redux/hooks'
import anilistUsers from '@/app/api/anilistUsers'
import { ImdbEpisode } from '@/app/ts/interfaces/apiImdbInterface';

type StatusTypes = "COMPLETED" | "CURRENT" | "PLANNING" | "DROPPED" | "PAUSED" | "REPEATING"

const btnValues = [
{ name: "Completed", value: "COMPLETED" },
{ name: "Watching", value: "CURRENT" },
{ name: "Planning", value: "PLANNING" },
{ name: "Dropped", value: "DROPPED" },
{ name: "Paused", value: "PAUSED" },
{ name: "Repeating", value: "REPEATING" },
]
import { userMediaStatusEntries } from '@/app/lib/dataConstants/anilist';
import { toggleShowLoginModalValue } from '@/app/lib/redux/features/loginModal';

export function Button({ mediaInfo, statusOnAnilist, listEntryId, imdbEpisodesList, amountWatchedOrRead, children }: {
mediaInfo: ApiDefaultResult, imdbEpisodesList?: ImdbEpisode[], statusOnAnilist?: string, listEntryId?: number, amountWatchedOrRead?: number, children?: React.ReactNode[]
mediaInfo: ApiDefaultResult, imdbEpisodesList?: ImdbEpisode[], statusOnAnilist?: ApiDefaultResult["mediaListEntry"]["status"], listEntryId?: number, amountWatchedOrRead?: number, children?: React.ReactNode[]
}) {

const [isLoading, setIsLoading] = useState<boolean>(false)
const [isMenuOpen, setIsMenuOpen] = useState<boolean>(false)

const [mediaStatus, setMediaStatus] = useState<StatusTypes | null>(statusOnAnilist as StatusTypes || null)

const [isUserModalOpen, setIsUserModalOpen] = useState(false)
const [mediaStatus, setMediaStatus] = useState<ApiDefaultResult["mediaListEntry"]["status"] | null>(statusOnAnilist || null)

const anilistUser = useAppSelector((state) => (state.UserInfo).value)
const dispatch = useAppDispatch()

const auth = getAuth()

const [user, loading] = useAuthState(auth)
const [user] = useAuthState(auth)

const db = getFirestore(initFirebase())

Expand All @@ -64,11 +53,11 @@ export function Button({ mediaInfo, statusOnAnilist, listEntryId, imdbEpisodesLi

if (!userMediaLists) return

btnValues.map((btn) => {
userMediaStatusEntries.map((btn) => {

const wasMediaFound = userMediaLists[btn.value.toLowerCase()]?.find((media: { id: number }) => media.id == mediaInfo.id)

if (wasMediaFound) setMediaStatus(btn.value as StatusTypes)
if (wasMediaFound) setMediaStatus(btn.value as ApiDefaultResult["mediaListEntry"]["status"])

})

Expand Down Expand Up @@ -104,10 +93,10 @@ export function Button({ mediaInfo, statusOnAnilist, listEntryId, imdbEpisodesLi

}

async function handleAddMediaOnList({ status }: { status: StatusTypes }) {
async function handleAddMediaOnList({ status }: { status: ApiDefaultResult["mediaListEntry"]["status"] }) {

// Opens Login Modal
if (!user && !anilistUser) return setIsUserModalOpen(true)
if (!user && !anilistUser) return dispatch(toggleShowLoginModalValue())

setIsLoading(true)

Expand Down Expand Up @@ -182,13 +171,6 @@ export function Button({ mediaInfo, statusOnAnilist, listEntryId, imdbEpisodesLi
return (
<React.Fragment>

<ShowUpLoginPanelAnimated
apperanceCondition={isUserModalOpen}
customOnClickAction={() => setIsUserModalOpen(false)}
aria-controls={styles.user_media_status_list}
auth={auth}
/>

<motion.button
whileTap={{ scale: 0.85 }}
id={styles.container}
Expand Down Expand Up @@ -220,13 +202,13 @@ export function Button({ mediaInfo, statusOnAnilist, listEntryId, imdbEpisodesLi
>
<ul>

{btnValues.map((btn) => (
{userMediaStatusEntries.map((btn) => (
<li key={btn.value}>
<motion.button
data-active={mediaStatus == btn.value}
disabled={isLoading}
onClick={() => handleAddMediaOnList(
{ status: btn.value as StatusTypes }
{ status: btn.value as ApiDefaultResult["mediaListEntry"]["status"] }
)}
whileTap={{ scale: 0.9 }}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
gap: 0 8px;

background-color: var(--white-100) !important;
color: var(--black-100) !important;
color: #ee9b0d !important;

border-color: var(--black-100) !important;

}
Loading

0 comments on commit a6e5001

Please sign in to comment.