Skip to content

Commit

Permalink
Use @gw2api/fetch to access the GW2 API from the browser
Browse files Browse the repository at this point in the history
  • Loading branch information
darthmaim committed Jul 22, 2024
1 parent be52f62 commit 5ba3ca0
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 97 deletions.
6 changes: 3 additions & 3 deletions apps/web/app/[language]/achievement/[id]/tier-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ const TierTableAccountRow: FC<TierTableAccountRowProps> = ({ achievement, accoun
<>
{tiers.map((tier, index) => {
const previousTier = index === 0 ? { points: 0, count: 0 } : tiers[index - 1];
const isDone = progress && (progress.done || progress.current >= tier.count);
const isCurrent = progress && !isDone && progress.current >= previousTier.count;
const percentage = isDone ? 1 : isCurrent ? ((progress.current - previousTier.count) / (tier.count - previousTier.count)) : 0;
const isDone = progress && (progress.done || (progress.current ?? 0) >= tier.count);
const isCurrent = progress && !isDone && (progress.current ?? 0) >= previousTier.count;
const percentage = isDone ? 1 : isCurrent ? (((progress.current ?? 0) - previousTier.count) / (tier.count - previousTier.count)) : 0;

return (
<ProgressCell key={tier.count} progress={percentage}>
Expand Down
20 changes: 0 additions & 20 deletions apps/web/app/[language]/wizards-vault/objectives.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ import { Scope } from '@gw2me/client';
import { useSubscription } from '@/components/Gw2Api/Gw2AccountSubscriptionProvider';
import { useGw2Accounts } from '@/components/Gw2Api/use-gw2-accounts';
import type { Gw2Account } from '@/components/Gw2Api/types';
import { FlexRow } from '@gw2treasures/ui/components/Layout/FlexRow';
import { SubmitButton } from '@gw2treasures/ui/components/Form/Buttons/SubmitButton';
import { reauthorize } from '@/components/Gw2Api/reauthorize';
import { Waypoint } from '@/components/Waypoint/Waypoint';
import { Gw2AccountName } from '@/components/Gw2Api/Gw2AccountName';
import { Gw2AccountAuthorizationNotice } from '@/components/Gw2Api/Gw2AccountAuthorizationNotice';
Expand Down Expand Up @@ -194,20 +191,3 @@ const AccountObjectiveDetails: FC<AccountObjectivesProps> = ({ account, objectiv
</>
);
};

interface WizardsProgress {
meta_progress_current: number,
meta_progress_complete: number,
meta_reward_item_id: number,
meta_reward_astral: number,
meta_reward_claimed: number,
objectives: {
id: number,
title: string,
track: string,
acclaim: number,
progress_current: number,
progress_complete: number,
claimed: boolean,
}[]
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ export const AccountAchievementProgressCell: FC<AccountAchievementProgressCellPr
}

return (
<ProgressCell progress={progress.done ? 1 : progress.current / progress.max}>
{progress.done ? <Icon icon="checkmark"/> : `${progress.current} / ${progress.max}`}
<ProgressCell progress={progress.done ? 1 : (progress.current ?? 0) / (progress.max ?? 1)}>
{progress.done ? <Icon icon="checkmark"/> : `${(progress.current ?? 0)} / ${(progress.max ?? 1)}`}
{progress.repeated && ` (↻ ${progress.repeated})`}
</ProgressCell>
);
Expand Down
83 changes: 16 additions & 67 deletions apps/web/components/Gw2Api/Gw2AccountSubscriptionProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { fetchAccessTokens } from './fetch-accounts-action';
import type { Language } from '@gw2treasures/database';
import { getResetDate } from '../Reset/ResetTimer';
import { useVisibilityState } from '@/lib/useVisibilityState';
import { fetchGw2Api } from '@gw2api/fetch';
import type { AccountAchievement } from '@gw2api/types/data/account-achievements';
import type { AccountWallet } from '@gw2api/types/data/account-wallet';

export interface Gw2AccountSubscriptionProviderProps {
children: ReactNode
Expand All @@ -14,10 +17,10 @@ export interface Gw2AccountSubscriptionProviderProps {
type SubscriptionType = 'achievements' | 'skins' | 'wallet' | 'wizards-vault';

type SubscriptionData<T extends SubscriptionType> =
T extends 'achievements' ? Gw2ApiAccountProgression :
T extends 'achievements' ? AccountAchievement[] :
T extends 'skins' ? number[] :
T extends 'wallet' ? AccountWallet :
T extends 'wizards-vault' ? AccountWizardsVaultData :
T extends 'wallet' ? AccountWallet[] :
T extends 'wizards-vault' ? Awaited<ReturnType<typeof loadAccountsWizardsVault>> :
never

type SubscriptionResponse<T extends SubscriptionType> = {
Expand Down Expand Up @@ -223,82 +226,28 @@ function useRefTo<T>(to: T): MutableRefObject<T> {
return ref;
}

const fetchJson = async <T extends unknown = unknown>(url: string): Promise<T> => {
const response = await fetch(url, { redirect: 'manual', cache: 'no-cache' });
if(!response.ok) {
throw new Error('Bad response');
}

return response.json();
};

const achievementFetch = (accessToken: string) => fetchJson(`https://api.guildwars2.com/v2/account/achievements?access_token=${accessToken}`) as Promise<Gw2ApiAccountProgression>;
const skinsFetch = (accessToken: string) => fetchJson(`https://api.guildwars2.com/v2/account/skins?access_token=${accessToken}`) as Promise<number[]>;
const walletFetch = (accessToken: string) => fetchJson(`https://api.guildwars2.com/v2/account/wallet?access_token=${accessToken}`) as Promise<AccountWallet>;
const achievementFetch = (accessToken: string) => fetchGw2Api('/v2/account/achievements', { accessToken, cache: 'no-cache' });
const skinsFetch = (accessToken: string) => fetchGw2Api('/v2/account/skins', { accessToken, cache: 'no-cache' });
const walletFetch = (accessToken: string) => fetchGw2Api('/v2/account/wallet', { accessToken, cache: 'no-cache' });
const wizardsVaultFetch = (accessToken: string) => loadAccountsWizardsVault(accessToken, 'en');

type Gw2ApiAccountProgression = {
id: number,
current: number,
max: number,
done: boolean,
bits?: number[],
repeated?: number,
unlocked?: boolean,
}[];

type AccountWallet = {
id: number,
value: number,
}[];

interface AccountWizardsVaultData {
account: { id: string, last_modified: string, name: string },
lastModifiedToday: boolean,
lastModifiedThisWeek: boolean,
daily: WizardsProgress | undefined,
weekly: WizardsProgress | undefined,
special: WizardsProgress | undefined,
acclaim: number,
}

interface WizardsProgress {
meta_progress_current: number,
meta_progress_complete: number,
meta_reward_item_id: number,
meta_reward_astral: number,
meta_reward_claimed: number,
objectives: {
id: number,
title: string,
track: string,
acclaim: number,
progress_current: number,
progress_complete: number,
claimed: boolean,
}[]
}

async function loadAccountsWizardsVault(subtoken: string, lang: Language): Promise<AccountWizardsVaultData> {
const account = await fetchJson<AccountWizardsVaultData['account']>(`https://api.guildwars2.com/v2/account?v=2019-02-21T00:00:00.000Z&access_token=${subtoken}`);
async function loadAccountsWizardsVault(accessToken: string, lang: Language) {
const account = await fetchGw2Api('/v2/account', { accessToken, schema: '2019-02-21T00:00:00.000Z', cache: 'no-cache' });

const lastModified = new Date(account.last_modified);
const lastModifiedToday = lastModified > getResetDate('last-daily');
const lastModifiedThisWeek = lastModified > getResetDate('last-weekly');

const [daily, weekly, special, acclaim] = await Promise.all([
lastModifiedToday ? fetchJson<WizardsProgress>(`https://api.guildwars2.com/v2/account/wizardsvault/daily?v=2019-02-21T00:00:00.000Z&lang=${lang}&access_token=${subtoken}`) : undefined,
lastModifiedThisWeek ? fetchJson<WizardsProgress>(`https://api.guildwars2.com/v2/account/wizardsvault/weekly?v=2019-02-21T00:00:00.000Z&lang=${lang}&access_token=${subtoken}`) : undefined,
fetchJson<WizardsProgress>(`https://api.guildwars2.com/v2/account/wizardsvault/special?v=2019-02-21T00:00:00.000Z&lang=${lang}&access_token=${subtoken}`),
// TODO: needs wallet permission
// fetch(`https://api.guildwars2.com/v2/account/wallet?v=2019-02-21T00:00:00.000Z&access_token=${subtoken}`).then((r) => r.json()).then((wallet) => wallet.find((currency: any) => currency.id === 63)?.value) as Promise<number>,
0
const [daily, weekly, special] = await Promise.all([
lastModifiedToday ? fetchGw2Api('/v2/account/wizardsvault/daily', { accessToken, cache: 'no-cache' }) : undefined,
lastModifiedThisWeek ? fetchGw2Api('/v2/account/wizardsvault/weekly', { accessToken, cache: 'no-cache' }) : undefined,
fetchGw2Api('/v2/account/wizardsvault/special', { accessToken, cache: 'no-cache' }),
]);

return {
account,
lastModifiedToday,
lastModifiedThisWeek,
daily, weekly, special, acclaim
daily, weekly, special
};
}
9 changes: 4 additions & 5 deletions apps/web/components/Item/TradingPost.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
'use client';

import type { Gw2Api } from 'gw2-api-types';
import { type FC, useEffect, useState } from 'react';
import { Coins } from '../Format/Coins';
import { FormatNumber } from '../Format/FormatNumber';
import { fetchGw2Api } from '@gw2api/fetch';
import styles from './TradingPost.module.css';
import type { Price } from '@gw2api/types/data/commerce';

export interface TradingPostProps {
itemId: number;
}

export const TradingPost: FC<TradingPostProps> = ({ itemId }) => {
const [tpData, setTpData] = useState<Gw2Api.Commerce.Price>();
const [tpData, setTpData] = useState<Price>();

useEffect(() => {
fetch(`https://api.guildwars2.com/v2/commerce/prices/${itemId}`).then((r) => r.json()).then((prices) => {
setTpData(prices);
});
fetchGw2Api(`/v2/commerce/prices/${itemId}`, {}).then(setTpData);
}, [itemId]);

return (
Expand Down
2 changes: 2 additions & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"@floating-ui/react": "0.26.19",
"@floating-ui/react-dom": "2.1.1",
"@formatjs/intl-localematcher": "0.5.4",
"@gw2api/fetch": "0.1.0",
"@gw2api/types": "0.0.8",
"@gw2me/client": "0.2.5",
"@gw2treasures/database": "*",
"@gw2treasures/eslint-plugin-nextjs": "*",
Expand Down
15 changes: 15 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5ba3ca0

Please sign in to comment.