0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00

Ensured queries are dependent on siteUrl

refs https://linear.app/tryghost/issue/AP-469

The first time `useSiteUrl` was called it would return the origin of the admin
url, rather than the site url which causes errors in production. Instead of
relying on the admin-x-framework to get the site url, we can make the request
ourselves and cache it - this ensures that we always have the correct URL.
This commit is contained in:
Fabien O'Carroll 2024-10-04 09:34:56 +07:00 committed by Fabien 'egg' O'Carroll
parent 44eeed2472
commit 5bdfac4e1f

View file

@ -1,12 +1,18 @@
import {Activity} from '../components/activities/ActivityItem'; import {Activity} from '../components/activities/ActivityItem';
import {ActivityPubAPI, type Profile, type SearchResults} from '../api/activitypub'; import {ActivityPubAPI, type Profile, type SearchResults} from '../api/activitypub';
import {useBrowseSite} from '@tryghost/admin-x-framework/api/site';
import {useInfiniteQuery, useMutation, useQuery, useQueryClient} from '@tanstack/react-query'; import {useInfiniteQuery, useMutation, useQuery, useQueryClient} from '@tanstack/react-query';
export function useSiteUrl() { let SITE_URL: string;
const site = useBrowseSite();
return site.data?.site?.url ?? window.location.origin; async function getSiteUrl() {
}; if (!SITE_URL) {
const response = await fetch('/ghost/api/admin/site');
const json = await response.json();
SITE_URL = json.site.url;
}
return SITE_URL;
}
function createActivityPubAPI(handle: string, siteUrl: string) { function createActivityPubAPI(handle: string, siteUrl: string) {
return new ActivityPubAPI( return new ActivityPubAPI(
@ -17,21 +23,21 @@ function createActivityPubAPI(handle: string, siteUrl: string) {
} }
export function useLikedForUser(handle: string) { export function useLikedForUser(handle: string) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useQuery({ return useQuery({
queryKey: [`liked:${handle}`], queryKey: [`liked:${handle}`],
async queryFn() { async queryFn() {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.getLiked(); return api.getLiked();
} }
}); });
} }
export function useReplyMutationForUser(handle: string) { export function useReplyMutationForUser(handle: string) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useMutation({ return useMutation({
async mutationFn({id, content}: {id: string, content: string}) { async mutationFn({id, content}: {id: string, content: string}) {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return await api.reply(id, content) as Activity; return await api.reply(id, content) as Activity;
} }
}); });
@ -39,10 +45,10 @@ export function useReplyMutationForUser(handle: string) {
export function useLikeMutationForUser(handle: string) { export function useLikeMutationForUser(handle: string) {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useMutation({ return useMutation({
mutationFn(id: string) { async mutationFn(id: string) {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.like(id); return api.like(id);
}, },
onMutate: (id) => { onMutate: (id) => {
@ -82,10 +88,10 @@ export function useLikeMutationForUser(handle: string) {
export function useUnlikeMutationForUser(handle: string) { export function useUnlikeMutationForUser(handle: string) {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useMutation({ return useMutation({
mutationFn: (id: string) => { async mutationFn(id: string) {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.unlike(id); return api.unlike(id);
}, },
onMutate: async (id) => { onMutate: async (id) => {
@ -133,55 +139,55 @@ export function useUnlikeMutationForUser(handle: string) {
} }
export function useUserDataForUser(handle: string) { export function useUserDataForUser(handle: string) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useQuery({ return useQuery({
queryKey: [`user:${handle}`], queryKey: [`user:${handle}`],
async queryFn() { async queryFn() {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.getUser(); return api.getUser();
} }
}); });
} }
export function useFollowersCountForUser(handle: string) { export function useFollowersCountForUser(handle: string) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useQuery({ return useQuery({
queryKey: [`followersCount:${handle}`], queryKey: [`followersCount:${handle}`],
async queryFn() { async queryFn() {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.getFollowersCount(); return api.getFollowersCount();
} }
}); });
} }
export function useFollowingCountForUser(handle: string) { export function useFollowingCountForUser(handle: string) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useQuery({ return useQuery({
queryKey: [`followingCount:${handle}`], queryKey: [`followingCount:${handle}`],
async queryFn() { async queryFn() {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.getFollowingCount(); return api.getFollowingCount();
} }
}); });
} }
export function useFollowingForUser(handle: string) { export function useFollowingForUser(handle: string) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useQuery({ return useQuery({
queryKey: [`following:${handle}`], queryKey: [`following:${handle}`],
async queryFn() { async queryFn() {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.getFollowing(); return api.getFollowing();
} }
}); });
} }
export function useFollowersForUser(handle: string) { export function useFollowersForUser(handle: string) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useQuery({ return useQuery({
queryKey: [`followers:${handle}`], queryKey: [`followers:${handle}`],
async queryFn() { async queryFn() {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.getFollowers(); return api.getFollowers();
} }
}); });
@ -198,11 +204,11 @@ export function useAllActivitiesForUser({
includeReplies?: boolean; includeReplies?: boolean;
filter?: {type?: string[]} | null; filter?: {type?: string[]} | null;
}) { }) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useQuery({ return useQuery({
queryKey: [`activities:${JSON.stringify({handle, includeOwn, includeReplies, filter})}`], queryKey: [`activities:${JSON.stringify({handle, includeOwn, includeReplies, filter})}`],
async queryFn() { async queryFn() {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.getAllActivities(includeOwn, includeReplies, filter); return api.getAllActivities(includeOwn, includeReplies, filter);
} }
}); });
@ -219,11 +225,11 @@ export function useActivitiesForUser({
includeReplies?: boolean; includeReplies?: boolean;
filter?: {type?: string[]} | null; filter?: {type?: string[]} | null;
}) { }) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useInfiniteQuery({ return useInfiniteQuery({
queryKey: [`activities:${JSON.stringify({handle, includeOwn, includeReplies, filter})}`], queryKey: [`activities:${JSON.stringify({handle, includeOwn, includeReplies, filter})}`],
async queryFn({pageParam}: {pageParam?: string}) { async queryFn({pageParam}: {pageParam?: string}) {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.getActivities(includeOwn, includeReplies, filter, pageParam); return api.getActivities(includeOwn, includeReplies, filter, pageParam);
}, },
getNextPageParam(prevPage) { getNextPageParam(prevPage) {
@ -233,15 +239,14 @@ export function useActivitiesForUser({
} }
export function useSearchForUser(handle: string, query: string) { export function useSearchForUser(handle: string, query: string) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const queryKey = ['search', {handle, query}]; const queryKey = ['search', {handle, query}];
const searchQuery = useQuery({ const searchQuery = useQuery({
enabled: query !== '',
queryKey, queryKey,
async queryFn() { async queryFn() {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.search(query); return api.search(query);
} }
}); });
@ -268,10 +273,10 @@ export function useSearchForUser(handle: string, query: string) {
} }
export function useFollow(handle: string, onSuccess: () => void, onError: () => void) { export function useFollow(handle: string, onSuccess: () => void, onError: () => void) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useMutation({ return useMutation({
async mutationFn(username: string) { async mutationFn(username: string) {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.follow(username); return api.follow(username);
}, },
onSuccess, onSuccess,
@ -280,11 +285,11 @@ export function useFollow(handle: string, onSuccess: () => void, onError: () =>
} }
export function useFollowersForProfile(handle: string) { export function useFollowersForProfile(handle: string) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useInfiniteQuery({ return useInfiniteQuery({
queryKey: [`followers:${handle}`], queryKey: [`followers:${handle}`],
async queryFn({pageParam}: {pageParam?: string}) { async queryFn({pageParam}: {pageParam?: string}) {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.getFollowersForProfile(handle, pageParam); return api.getFollowersForProfile(handle, pageParam);
}, },
getNextPageParam(prevPage) { getNextPageParam(prevPage) {
@ -294,11 +299,11 @@ export function useFollowersForProfile(handle: string) {
} }
export function useFollowingForProfile(handle: string) { export function useFollowingForProfile(handle: string) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useInfiniteQuery({ return useInfiniteQuery({
queryKey: [`following:${handle}`], queryKey: [`following:${handle}`],
async queryFn({pageParam}: {pageParam?: string}) { async queryFn({pageParam}: {pageParam?: string}) {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.getFollowingForProfile(handle, pageParam); return api.getFollowingForProfile(handle, pageParam);
}, },
getNextPageParam(prevPage) { getNextPageParam(prevPage) {
@ -308,14 +313,14 @@ export function useFollowingForProfile(handle: string) {
} }
export function useSuggestedProfiles(handle: string, handles: string[]) { export function useSuggestedProfiles(handle: string, handles: string[]) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const queryKey = ['profiles', {handles}]; const queryKey = ['profiles', {handles}];
const suggestedProfilesQuery = useQuery({ const suggestedProfilesQuery = useQuery({
queryKey, queryKey,
async queryFn() { async queryFn() {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return Promise.all( return Promise.all(
handles.map(h => api.getProfile(h)) handles.map(h => api.getProfile(h))
); );
@ -341,11 +346,11 @@ export function useSuggestedProfiles(handle: string, handles: string[]) {
} }
export function useProfileForUser(handle: string, fullHandle: string) { export function useProfileForUser(handle: string, fullHandle: string) {
const siteUrl = useSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return useQuery({ return useQuery({
queryKey: [`profile:${fullHandle}`], queryKey: [`profile:${fullHandle}`],
async queryFn() { async queryFn() {
const siteUrl = await getSiteUrl();
const api = createActivityPubAPI(handle, siteUrl);
return api.getProfile(fullHandle); return api.getProfile(fullHandle);
} }
}); });