feat: patreon check

This commit is contained in:
TrèsAbhi committed 2024-06-14 13:57:54 -05:00
1 parent cb09f57a91
commit 0a0376312b
8 files changed
+114 -19

No files matched your search

@@ -0,0 +1,75 @@
import { NextResponse } from 'next/server';
interface PatreonMembershipResponse {
data: {
attributes: unknown;
id: `${number}`;
relationships: {
memberships: {
data: {
id: string; // uuid
type: 'member';
}[];
};
};
type: 'user';
};
included: (
| {
attributes: {
patron_status:
| 'active_patron'
| 'declined_patron'
| 'former_patron'
| null; // null = never a paid member
};
id: string; // uuid
relationships: {
campaign: {
data: {
id: `${number}`; // id of my campaign to check against
type: 'campaign';
};
links: {
related: string; // url
};
};
};
type: 'member';
}
| {
attributes: {};
id: `${number}`;
type: 'campaign'; // ignore this discriminator
}
)[];
links: {
self: 'https://www.patreon.com/api/oauth2/v2/user/124201389';
};
}
export async function GET(
request: Request,
{ params }: { params: { token: string } },
) {
const response = await fetch(
encodeURI(
'https://www.patreon.com/api/oauth2/v2/identity?include=memberships.campaign&fields[member]=patron_status',
),
{ headers: { Authorization: `Bearer ${params.token}` } },
);
if (!response.ok) return NextResponse.json(false);
const json = (await response.json()) as PatreonMembershipResponse;
return NextResponse.json(
json.included.some(
(item) =>
item.type === 'member' &&
item.relationships.campaign.data.id ===
process.env.PATREON_CAMPAIGN_ID &&
item.attributes.patron_status === 'active_patron',
),
);
}
+1 -1
View File
@@ -51,7 +51,7 @@ export default function Page({
if (!searchParams.code) break;
const data = (await fetch(
`/api/auth/patreon/${searchParams.code}`,
`/api/patreon/auth/${searchParams.code}`,
).then((response) => response.json())) as PatreonAuthResponse;
mutateApp((draft) => {
+14 -12
View File
@@ -1,10 +1,11 @@
'use client';
import { Box, BoxProps, Flex, Text } from '@radix-ui/themes';
import { Box, BoxProps, Text } from '@radix-ui/themes';
import { uniqueId } from 'lodash';
import { useEffect, useRef } from 'react';
import { Vector2Tuple } from 'three';
import { imgur } from '../core/blitzkit/imgur';
import { useAdExempt } from '../hooks/useAdExempt';
export enum AdType {
MediumRectangleHorizontalPurple = 738182777,
@@ -28,6 +29,8 @@ export function Ad({ type, style, ...props }: AdProps) {
const id = useRef(uniqueId());
const dimensions = AD_DIMENSIONS[type];
useAdExempt();
useEffect(() => {
(window as any).msAdsQueue.push(function () {
(window as any).mmnow.render({
@@ -51,19 +54,18 @@ export function Ad({ type, style, ...props }: AdProps) {
}}
{...props}
>
<Flex
position="absolute"
top="50%"
left="50%"
style={{ transform: 'translate(-50%, -50%)' }}
direction="column"
<Text
color="gray"
style={{
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
}}
align="center"
>
<Text color="gray">Advertisement</Text>
<Text size="1" color="gray">
{dimensions[0]}x{dimensions[1]}
</Text>
</Flex>
Advertisement
</Text>
<Box
width={`${dimensions[0]}px`}
+12 -5
View File
@@ -1,3 +1,5 @@
'use client';
import {
Cross1Icon,
DiscordLogoIcon,
@@ -16,7 +18,7 @@ import {
Separator,
Text,
} from '@radix-ui/themes';
import { usePathname } from 'next/navigation';
import { usePathname, useRouter } from 'next/navigation';
import { useState } from 'react';
import { REGIONS } from '../../constants/regions';
import { TOOLS } from '../../constants/tools';
@@ -35,6 +37,7 @@ import * as styles from './index.css';
export const NAVBAR_HEIGHT = 64;
export default function Navbar() {
const router = useRouter();
const [showHamburgerMenu, setShowHamburgerMenu] = useState(false);
const pathname = usePathname();
const logins = useApp((state) => state.logins);
@@ -191,7 +194,7 @@ export default function Navbar() {
{!logins.patreon && (
<Link
style={{ width: '100%' }}
href={`https://www.patreon.com/oauth2/authorize?response_type=code&client_id=${process.env.NEXT_PUBLIC_PATREON_CLIENT_ID}&redirect_uri=${process.env.NEXT_PUBLIC_PATREON_REDIRECT_URI}`}
href={`https://www.patreon.com/oauth2/authorize?response_type=code&client_id=${process.env.NEXT_PUBLIC_PATREON_CLIENT_ID}&redirect_uri=${process.env.NEXT_PUBLIC_PATREON_REDIRECT_URI}&scope=identity`}
>
<Button style={{ width: '100%' }} color="tomato">
<PatreonIcon width={15} height={15} /> Patreon
@@ -215,9 +218,13 @@ export default function Navbar() {
{REGIONS.map((region) => (
<Dialog.Close>
<Link
href={`https://api.worldoftanks.${region}/wot/auth/login/?application_id=${WARGAMING_APPLICATION_ID}&redirect_uri=${encodeURIComponent(
`${location.origin}/auth/wargaming?return=${location.origin}${location.pathname}`,
)}`}
href={
typeof window?.location === undefined
? undefined
: `https://api.worldoftanks.${region}/wot/auth/login/?application_id=${WARGAMING_APPLICATION_ID}&redirect_uri=${encodeURIComponent(
`${location.origin}/auth/wargaming?return=${location.origin}${location.pathname}`,
)}`
}
>
<Button color="red">
{strings.common.regions.normal[region]}
+1 -1
View File
@@ -7,7 +7,7 @@ export async function extendAuthPatreon() {
if (!patreon) return;
const data = (await fetch(
`/api/auth/patreon/refresh/${patreon.refreshToken}`,
`/api/patreon/refresh/${patreon.refreshToken}`,
).then((response) => response.json())) as PatreonAuthResponse;
mutateApp((draft) => {
+11
View File
@@ -0,0 +1,11 @@
import { useApp } from '../stores/app';
export function useAdExempt() {
const patreon = useApp((state) => state.logins.patreon);
if (!patreon) return false;
fetch(`/api/patreon/membership/${patreon.token}`)
.then((response) => response.json())
.then(console.log);
}