added the guild that the fetch value was fetched from alongside fetch values in guild subscriptions

This commit is contained in:
Michael Peters 2022-01-13 23:17:15 -06:00
parent a1bd951812
commit fa10c8a7a9
9 changed files with 127 additions and 60 deletions

View File

@ -25,9 +25,9 @@ const GuildInvitesDisplay: FC<GuildInvitesDisplayProps> = (props: GuildInvitesDi
const url = 'https://localhost:3030'; // TODO: this will likely be a dropdown list at some point
const [ fetchRetryCallable, tokens, tokensError ] = useTokensSubscription(guild);
const [ fetchRetryCallable, tokens, tokensGuild, tokensError ] = useTokensSubscription(guild);
const [ guildMeta, guildMetaError ] = useGuildMetadataSubscription(guild);
const [ guildMeta, guildMetaGuild, guildMetaError ] = useGuildMetadataSubscription(guild);
const [ expiresFromNow, setExpiresFromNow ] = useState<Duration | null>(moment.duration(1, 'day'));
const [ expiresFromNowText, setExpiresFromNowText ] = useState<string>('1 day');

View File

@ -18,8 +18,9 @@ export interface GuildOverviewDisplayProps {
const GuildOverviewDisplay: FC<GuildOverviewDisplayProps> = (props: GuildOverviewDisplayProps) => {
const { guild } = props;
const [ guildMeta, guildMetaError ] = useGuildMetadataSubscription(guild);
const [ iconResource, iconResourceError ] = useResourceSubscription(guild, guildMeta?.iconResourceId ?? null);
// TODO: Use the one from guild.tsx (for both of these?)
const [ guildMeta, guildMetaGuild, guildMetaError ] = useGuildMetadataSubscription(guild);
const [ iconResource, iconResourceGuild, iconResourceError ] = useResourceSubscription(guild, guildMeta?.iconResourceId ?? null);
const [ savedName, setSavedName ] = useState<string | null>(null);
const [ savedIconBuff, setSavedIconBuff ] = useState<Buffer | null>(null);

View File

@ -22,7 +22,7 @@ const GuildListElement: FC<GuildListElementProps> = (props: GuildListElementProp
// TODO: state higher up
// TODO: handle metadata error
const [ guildMeta, guildMetaError ] = useGuildMetadataSubscription(guild);
const [ guildMeta, guildMetaGuild, guildMetaError ] = useGuildMetadataSubscription(guild);
const [ selfMember ] = useSelfMemberSubscription(guild);
const [ iconSrc ] = useSoftImageSrcResourceSubscription(guild, guildMeta?.iconResourceId ?? null);

View File

@ -53,7 +53,7 @@ const PreviewImageElement: FC<PreviewImageElementProps> = (props: PreviewImageEl
const { guild, previewWidth, previewHeight, resourcePreviewId, resourceId, resourceName, setOverlay } = props;
// TODO: Handle resourceError
const [ previewImgSrc, previewResource, previewResourceError ] = useSoftImageSrcResourceSubscription(guild, resourcePreviewId);
const [ previewImgSrc, previewResource, previewResourceGuild, previewResourceError ] = useSoftImageSrcResourceSubscription(guild, resourcePreviewId);
const [ contextMenu, onContextMenu ] = useContextClickContextMenu((alignment: IAlignment, relativeToPos: { x: number, y: number }, close: () => void) => {
if (!previewResource) return null;

View File

@ -26,6 +26,7 @@ const MessageList: FC<MessageListProps> = (props: MessageListProps) => {
setScrollRatio,
fetchResult,
messages,
messagesGuild,
messagesFetchError,
messagesFetchAboveError,
messagesFetchBelowError

View File

@ -24,7 +24,7 @@ const ImageOverlay: FC<ImageOverlayProps> = (props: ImageOverlayProps) => {
const rootRef = useRef<HTMLDivElement>(null);
const [ imgSrc, resource, resourceError ] = useSoftImageSrcResourceSubscription(guild, resourceId);
const [ imgSrc, resource, resourceGuild, resourceError ] = useSoftImageSrcResourceSubscription(guild, resourceId);
const [ contextMenu, onContextMenu ] = useContextClickContextMenu((alignment: IAlignment, relativeToPos: { x: number, y: number }, close: () => void) => {
if (!resource) return null;

View File

@ -25,7 +25,7 @@ const PersonalizeOverlay: FC<PersonalizeOverlayProps> = (props: PersonalizeOverl
const rootRef = useRef<HTMLDivElement>(null);
const [ avatarResource, avatarResourceError ] = useResourceSubscription(guild, selfMember.avatarResourceId)
const [ avatarResource, avatarResourceGuild, avatarResourceError ] = useResourceSubscription(guild, selfMember.avatarResourceId)
const displayNameInputRef = createRef<HTMLInputElement>();

View File

@ -34,7 +34,7 @@ export type MultipleSubscriptionEvents<T> = {
interface EffectParams<T> {
guild: CombinedGuild;
onFetch: (value: T | null) => void;
onFetch: (value: T | null, valueGuild: CombinedGuild) => void;
onFetchError: (e: unknown) => void;
bindEventsFunc: () => void;
unbindEventsFunc: () => void;
@ -77,6 +77,7 @@ function useGuildSubscriptionEffect<T>(
const isMounted = useIsMountedRef();
const guildRef = useRef<CombinedGuild>(guild);
guildRef.current = guild;
const fetchManagerFunc = useCallback(async () => {
if (!isMounted.current) return;
@ -84,8 +85,8 @@ function useGuildSubscriptionEffect<T>(
try {
const value = await fetchFunc();
if (!isMounted.current) return;
if (guildRef.current !== guild) return; // Don't call onFetch if we changed guilds
onFetch(value);
if (guildRef.current !== guild) return; // Don't call onFetch if we changed guilds. TODO: Test this
onFetch(value, guild);
} catch (e: unknown) {
LOG.error('error fetching for subscription', e);
if (!isMounted.current) return;
@ -118,18 +119,22 @@ function useSingleGuildSubscription<T, UE extends keyof Connectable, CE extends
guild: CombinedGuild,
eventMappingParams: SingleEventMappingParams<T, UE, CE>,
fetchFunc: (() => Promise<T>) | (() => Promise<T | null>)
): [value: T | null, fetchError: unknown | null, events: EventEmitter<SingleSubscriptionEvents>] {
): [value: T | null, valueGuild: CombinedGuild | null, fetchError: unknown | null, events: EventEmitter<SingleSubscriptionEvents>] {
const { updatedEventName, updatedEventArgsMap, conflictEventName, conflictEventArgsMap } = eventMappingParams;
const isMounted = useIsMountedRef();
const guildRef = useRef<CombinedGuild>(guild);
guildRef.current = guild;
const [ fetchError, setFetchError ] = useState<unknown | null>(null);
const [ value, setValue ] = useState<T | null>(null);
const [ valueGuild, setValueGuild ] = useState<CombinedGuild | null>(null);
const events = useMemo(() => new EventEmitter<SingleSubscriptionEvents>(), []);
const onFetch = useCallback((fetchValue: T | null) => {
const onFetch = useCallback((fetchValue: T | null, fetchValueGuild: CombinedGuild) => {
setValue(fetchValue);
setValueGuild(fetchValueGuild);
setFetchError(null);
events.emit('fetch');
}, []);
@ -137,16 +142,23 @@ function useSingleGuildSubscription<T, UE extends keyof Connectable, CE extends
const onFetchError = useCallback((e: unknown) => {
setFetchError(e);
setValue(null);
setValueGuild(null);
events.emit('fetch-error');
}, []);
const onUpdated = useCallback((updateValue: T) => {
const onUpdated = useCallback((updateValue: T, updateValueGuild: CombinedGuild) => {
setValue(updateValue);
if (updateValueGuild !== guildRef.current) {
LOG.warn(`update guild (${updateValueGuild.id}) != current guild (${guildRef.current})`);
}
events.emit('updated');
}, []);
const onConflict = useCallback((conflictValue: T) => {
const onConflict = useCallback((conflictValue: T, conflictValueGuild: CombinedGuild) => {
setValue(conflictValue);
if (conflictValueGuild !== guildRef.current) {
LOG.warn(`conflict guild (${conflictValueGuild.id}) != current guild (${guildRef.current})`);
}
events.emit('conflict');
}, []);
@ -154,23 +166,25 @@ function useSingleGuildSubscription<T, UE extends keyof Connectable, CE extends
// otherwise, I may have done this wrong. Forcing it to work with these calls
const boundUpdateFunc = useCallback((...args: Arguments<Connectable[UE]>): void => {
if (!isMounted.current) return;
if (guildRef.current !== guild) return;
const value = updatedEventArgsMap(...args);
onUpdated(value);
}, []) as (Connectable & Conflictable)[UE];
onUpdated(value, guild);
}, [ guild ]) as (Connectable & Conflictable)[UE];
const boundConflictFunc = useCallback((...args: Arguments<Conflictable[CE]>): void => {
if (!isMounted.current) return;
if (guildRef.current !== guild) return;
const value = conflictEventArgsMap(...args);
onConflict(value);
}, []) as (Connectable & Conflictable)[CE];
onConflict(value, guild);
}, [ guild ]) as (Connectable & Conflictable)[CE];
const bindEventsFunc = useCallback(() => {
guild.on(updatedEventName, boundUpdateFunc);
guild.on(conflictEventName, boundConflictFunc);
}, []);
}, [ boundUpdateFunc, boundConflictFunc ]);
const unbindEventsFunc = useCallback(() => {
guild.off(updatedEventName, boundUpdateFunc);
guild.off(conflictEventName, boundConflictFunc);
}, []);
}, [ boundUpdateFunc, boundConflictFunc ]);
useGuildSubscriptionEffect({
guild,
@ -180,7 +194,7 @@ function useSingleGuildSubscription<T, UE extends keyof Connectable, CE extends
unbindEventsFunc
}, fetchFunc);
return [ value, fetchError, events ];
return [ value, valueGuild, fetchError, events ];
}
function useMultipleGuildSubscription<
@ -196,6 +210,7 @@ function useMultipleGuildSubscription<
): [
fetchRetryCallable: () => Promise<void>,
value: T[] | null,
valueGuild: CombinedGuild | null,
fetchError: unknown | null,
events: EventEmitter<MultipleSubscriptionEvents<T>>
] {
@ -208,15 +223,19 @@ function useMultipleGuildSubscription<
} = eventMappingParams;
const isMounted = useIsMountedRef();
const guildRef = useRef<CombinedGuild>(guild);
guildRef.current = guild;
const [ fetchError, setFetchError ] = useState<unknown | null>(null);
const [ value, setValue ] = useState<T[] | null>(null);
const [ valueGuild, setValueGuild ] = useState<CombinedGuild | null>(null);
const events = useMemo(() => new EventEmitter<MultipleSubscriptionEvents<T>>(), []);
const onFetch = useCallback((fetchValue: T[] | null) => {
const onFetch = useCallback((fetchValue: T[] | null, fetchValueGuild: CombinedGuild) => {
if (fetchValue) fetchValue.sort(sortFunc);
setValue(fetchValue);
setValueGuild(fetchValueGuild);
setFetchError(null);
events.emit('fetch');
}, [ sortFunc ]);
@ -227,30 +246,39 @@ function useMultipleGuildSubscription<
events.emit('fetch-error');
}, []);
const onNew = useCallback((newElements: T[]) => {
const onNew = useCallback((newElements: T[], newElementsGuild: CombinedGuild) => {
setValue(currentValue => {
if (currentValue === null) return null;
if (currentValue === null) return Array.from(newElements).sort(sortFunc);
return currentValue.concat(newElements).sort(sortFunc);
})
});
if (newElementsGuild !== guildRef.current) {
LOG.warn(`new elements guild (${newElementsGuild.id}) != current guild (${guildRef.current})`);
}
events.emit('new', newElements);
}, [ sortFunc ]);
const onUpdated = useCallback((updatedElements: T[]) => {
const onUpdated = useCallback((updatedElements: T[], updatedElementsGuild: CombinedGuild) => {
setValue(currentValue => {
if (currentValue === null) return null;
return currentValue.map(element => updatedElements.find(updatedElement => updatedElement.id === element.id) ?? element).sort(sortFunc);
});
if (updatedElementsGuild !== guildRef.current) {
LOG.warn(`updated elements guild (${updatedElementsGuild.id}) != current guild (${guildRef.current})`);
}
events.emit('updated', updatedElements);
}, [ sortFunc ]);
const onRemoved = useCallback((removedElements: T[]) => {
const onRemoved = useCallback((removedElements: T[], removedElementsGuild: CombinedGuild) => {
setValue(currentValue => {
if (currentValue === null) return null;
const deletedIds = new Set(removedElements.map(deletedElement => deletedElement.id));
return currentValue.filter(element => !deletedIds.has(element.id)).sort(sortFunc);
});
if (removedElementsGuild !== guildRef.current) {
LOG.warn(`removed elements guild (${removedElementsGuild.id}) != current guild (${guildRef.current})`);
}
events.emit('removed', removedElements);
}, [ sortFunc ]);
const onConflict = useCallback((changes: Changes<T>) => {
const onConflict = useCallback((changes: Changes<T>, changesGuild: CombinedGuild) => {
setValue(currentValue => {
if (currentValue === null) return null;
const deletedIds = new Set(changes.deleted.map(deletedElement => deletedElement.id));
@ -260,6 +288,10 @@ function useMultipleGuildSubscription<
.filter(element => !deletedIds.has(element.id))
.sort(sortFunc);
});
if (changesGuild !== guildRef.current) {
LOG.warn(`conflict changes guild (${changesGuild.id}) != current guild (${guildRef.current})`);
}
setValueGuild(changesGuild);
events.emit('conflict', changes);
}, [ sortFunc ]);
@ -267,20 +299,24 @@ function useMultipleGuildSubscription<
// otherwise, I may have done this wrong. Forcing it to work with these calls
const boundNewFunc = useCallback((...args: Arguments<Connectable[NE]>): void => {
if (!isMounted.current) return;
onNew(newEventArgsMap(...args));
}, [ onNew, newEventArgsMap ]) as (Connectable & Conflictable)[NE];
if (guildRef.current !== guild) return; // prevent changes from a different guild
onNew(newEventArgsMap(...args), guild);
}, [ guild, onNew, newEventArgsMap ]) as (Connectable & Conflictable)[NE];
const boundUpdateFunc = useCallback((...args: Arguments<Connectable[UE]>): void => {
if (!isMounted.current) return;
onUpdated(updatedEventArgsMap(...args));
}, [ onUpdated, updatedEventArgsMap ]) as (Connectable & Conflictable)[UE];
if (guildRef.current !== guild) return;
onUpdated(updatedEventArgsMap(...args), guild);
}, [ guild, onUpdated, updatedEventArgsMap ]) as (Connectable & Conflictable)[UE];
const boundRemovedFunc = useCallback((...args: Arguments<Connectable[RE]>): void => {
if (!isMounted.current) return;
onRemoved(removedEventArgsMap(...args));
}, [ onRemoved, removedEventArgsMap ]) as (Connectable & Conflictable)[RE];
if (guildRef.current !== guild) return;
onRemoved(removedEventArgsMap(...args), guild);
}, [ guild, onRemoved, removedEventArgsMap ]) as (Connectable & Conflictable)[RE];
const boundConflictFunc = useCallback((...args: Arguments<Conflictable[CE]>): void => {
if (!isMounted.current) return;
onConflict(conflictEventArgsMap(...args));
}, [ onConflict, conflictEventArgsMap ]) as (Connectable & Conflictable)[CE];
if (guildRef.current !== guild) return;
onConflict(conflictEventArgsMap(...args), guild);
}, [ guild, onConflict, conflictEventArgsMap ]) as (Connectable & Conflictable)[CE];
const bindEventsFunc = useCallback(() => {
guild.on(newEventName, boundNewFunc);
@ -303,7 +339,7 @@ function useMultipleGuildSubscription<
unbindEventsFunc
}, fetchFunc);
return [ fetchRetryCallable, value, fetchError, events ];
return [ fetchRetryCallable, value, valueGuild, fetchError, events ];
}
function useMultipleGuildSubscriptionScrolling<
@ -327,6 +363,7 @@ function useMultipleGuildSubscriptionScrolling<
setScrollRatio: Dispatch<SetStateAction<number>>,
fetchResult: { hasMoreAbove: boolean, hasMoreBelow: boolean } | null,
value: T[] | null,
valueGuild: CombinedGuild | null,
fetchError: unknown | null,
fetchAboveError: unknown | null,
fetchBelowError: unknown | null,
@ -341,8 +378,11 @@ function useMultipleGuildSubscriptionScrolling<
} = eventMappingParams;
const isMounted = useIsMountedRef();
const guildRef = useRef<CombinedGuild>(guild);
guildRef.current = guild;
const [ value, setValue ] = useState<T[] | null>(null);
const [ valueGuild, setValueGuild ] = useState<CombinedGuild | null>(null);
const [ fetchError, setFetchError ] = useState<unknown | null>(null);
const [ fetchAboveError, setFetchAboveError ] = useState<unknown | null>(null);
@ -376,11 +416,13 @@ function useMultipleGuildSubscriptionScrolling<
const fetchAboveCallable = useCallback(async (): Promise<{ hasMoreAbove: boolean, removedFromBottom: boolean }> => {
if (!isMounted.current) return { hasMoreAbove: false, removedFromBottom: false };
if (guildRef.current !== guild) return { hasMoreAbove: false, removedFromBottom: false };
if (!value || value.length === 0) return { hasMoreAbove: false, removedFromBottom: false };
try {
const reference = value[0] as T;
const aboveElements = await fetchAboveFunc(reference);
if (!isMounted.current) return { hasMoreAbove: false, removedFromBottom: false };
if (guildRef.current !== guild) return { hasMoreAbove: false, removedFromBottom: false };
setFetchAboveError(null);
if (aboveElements) {
const hasMoreAbove = aboveElements.length >= maxFetchElements;
@ -400,18 +442,21 @@ function useMultipleGuildSubscriptionScrolling<
} catch (e: unknown) {
LOG.error('error fetching above for subscription', e);
if (!isMounted.current) return { hasMoreAbove: false, removedFromBottom: false };
if (guildRef.current !== guild) return { hasMoreAbove: false, removedFromBottom: false };
setFetchAboveError(e);
return { hasMoreAbove: true, removedFromBottom: false };
}
}, [ value, fetchAboveFunc, maxFetchElements ]);
}, [ guild, value, fetchAboveFunc, maxFetchElements ]);
const fetchBelowCallable = useCallback(async (): Promise<{ hasMoreBelow: boolean, removedFromTop: boolean }> => {
if (!isMounted.current) return { hasMoreBelow: false, removedFromTop: false };
if (guildRef.current !== guild) return { hasMoreBelow: false, removedFromTop: false };
if (!value || value.length === 0) return { hasMoreBelow: false, removedFromTop: false };
try {
const reference = value[value.length - 1] as T;
const belowElements = await fetchBelowFunc(reference);
if (!isMounted.current) return { hasMoreBelow: false, removedFromTop: false };
if (guildRef.current !== guild) return { hasMoreBelow: false, removedFromTop: false };
setFetchBelowError(null);
if (belowElements) {
const hasMoreBelow = belowElements.length >= maxFetchElements;
@ -431,12 +476,13 @@ function useMultipleGuildSubscriptionScrolling<
} catch (e: unknown) {
LOG.error('error fetching below for subscription', e);
if (!isMounted.current) return { hasMoreBelow: false, removedFromTop: false };
if (guildRef.current !== guild) return { hasMoreBelow: false, removedFromTop: false };
setFetchBelowError(e);
return { hasMoreBelow: true, removedFromTop: false };
}
}, [ value, fetchBelowFunc, maxFetchElements ]);
const onFetch = useCallback((fetchValue: T[] | null) => {
const onFetch = useCallback((fetchValue: T[] | null, fetchValueGuild: CombinedGuild) => {
let hasMoreAbove = false;
if (fetchValue) {
if (fetchValue.length >= maxFetchElements) hasMoreAbove = true;
@ -444,6 +490,7 @@ function useMultipleGuildSubscriptionScrolling<
}
setFetchResult({ hasMoreAbove, hasMoreBelow: false });
setValue(fetchValue);
setValueGuild(fetchValueGuild);
setFetchError(null);
events.emit('fetch');
}, [ sortFunc, maxFetchElements, maxElements ]);
@ -451,10 +498,11 @@ function useMultipleGuildSubscriptionScrolling<
const onFetchError = useCallback((e: unknown) => {
setFetchError(e);
setValue(null);
setValueGuild(null);
events.emit('fetch-error');
}, []);
const onNew = useCallback((newElements: T[]) => {
const onNew = useCallback((newElements: T[], newElementsGuild: CombinedGuild) => {
setValue(currentValue => {
if (currentValue === null) return null;
let newValue = currentValue.concat(newElements).sort(sortFunc);
@ -462,26 +510,35 @@ function useMultipleGuildSubscriptionScrolling<
newValue = removeByCounts(newValue, getRemoveCounts(newValue.length - maxElements));
}
return newValue;
})
});
if (newElementsGuild !== guildRef.current) {
LOG.warn(`new elements guild (${newElementsGuild.id}) != current guild (${guildRef.current})`);
}
events.emit('new', newElements);
}, [ sortFunc, getRemoveCounts ]);
const onUpdated = useCallback((updatedElements: T[]) => {
const onUpdated = useCallback((updatedElements: T[], updatedElementsGuild: CombinedGuild) => {
setValue(currentValue => {
if (currentValue === null) return null;
return currentValue.map(element => updatedElements.find(updatedElement => updatedElement.id === element.id) ?? element).sort(sortFunc);
});
if (updatedElementsGuild !== guildRef.current) {
LOG.warn(`updated elements guild (${updatedElementsGuild.id}) != current guild (${guildRef.current})`);
}
events.emit('updated', updatedElements);
}, [ sortFunc ]);
const onRemoved = useCallback((removedElements: T[]) => {
const onRemoved = useCallback((removedElements: T[], removedElementsGuild: CombinedGuild) => {
setValue(currentValue => {
if (currentValue === null) return null;
const deletedIds = new Set(removedElements.map(deletedElement => deletedElement.id));
return currentValue.filter(element => !deletedIds.has(element.id)).sort(sortFunc);
});
if (removedElementsGuild !== guildRef.current) {
LOG.warn(`updated elements guild (${removedElementsGuild.id}) != current guild (${guildRef.current})`);
}
events.emit('removed', removedElements);
}, [ sortFunc ]);
const onConflict = useCallback((changes: Changes<T>) => {
const onConflict = useCallback((changes: Changes<T>, changesGuild: CombinedGuild) => {
setValue(currentValue => {
if (currentValue === null) return null;
const deletedIds = new Set(changes.deleted.map(deletedElement => deletedElement.id));
@ -495,6 +552,9 @@ function useMultipleGuildSubscriptionScrolling<
}
return newValue;
});
if (changesGuild !== guildRef.current) {
LOG.warn(`conflict changes guild (${changesGuild.id}) != current guild (${guildRef.current})`);
}
events.emit('conflict', changes);
}, [ sortFunc, getRemoveCounts ]);
@ -502,19 +562,23 @@ function useMultipleGuildSubscriptionScrolling<
// otherwise, I may have done this wrong. Forcing it to work with these calls
const boundNewFunc = useCallback((...args: Arguments<Connectable[NE]>): void => {
if (!isMounted.current) return;
onNew(newEventArgsMap(...args));
}, [ onNew, newEventArgsMap ]) as (Connectable & Conflictable)[NE];
if (guildRef.current !== guild) return; // Cancel calls when the guild changes
onNew(newEventArgsMap(...args), guild);
}, [ guild, onNew, newEventArgsMap ]) as (Connectable & Conflictable)[NE];
const boundUpdateFunc = useCallback((...args: Arguments<Connectable[UE]>): void => {
if (!isMounted.current) return;
onUpdated(updatedEventArgsMap(...args));
if (guildRef.current !== guild) return; // Cancel calls when the guild changes
onUpdated(updatedEventArgsMap(...args), guild);
}, [ onUpdated, updatedEventArgsMap ]) as (Connectable & Conflictable)[UE];
const boundRemovedFunc = useCallback((...args: Arguments<Connectable[RE]>): void => {
if (!isMounted.current) return;
onRemoved(removedEventArgsMap(...args));
if (guildRef.current !== guild) return; // Cancel calls when the guild changes
onRemoved(removedEventArgsMap(...args), guild);
}, [ onRemoved, removedEventArgsMap ]) as (Connectable & Conflictable)[RE];
const boundConflictFunc = useCallback((...args: Arguments<Conflictable[CE]>): void => {
if (!isMounted.current) return;
onConflict(conflictEventArgsMap(...args));
if (guildRef.current !== guild) return; // Cancel calls when the guild changes
onConflict(conflictEventArgsMap(...args), guild);
}, [ onConflict, conflictEventArgsMap ]) as (Connectable & Conflictable)[CE];
const bindEventsFunc = useCallback(() => {
@ -545,6 +609,7 @@ function useMultipleGuildSubscriptionScrolling<
setScrollRatio,
fetchResult,
value,
valueGuild,
fetchError,
fetchAboveError,
fetchBelowError,
@ -579,8 +644,8 @@ export function useResourceSubscription(guild: CombinedGuild, resourceId: string
}, fetchResourceFunc);
}
export function useSoftImageSrcResourceSubscription(guild: CombinedGuild, resourceId: string | null): [ imgSrc: string, resource: Resource | null, fetchError: unknown | null ] {
const [ resource, fetchError ] = useResourceSubscription(guild, resourceId);
export function useSoftImageSrcResourceSubscription(guild: CombinedGuild, resourceId: string | null): [ imgSrc: string, resource: Resource | null, resourceGuild: CombinedGuild | null, fetchError: unknown | null ] {
const [ resource, resourceGuild, fetchError ] = useResourceSubscription(guild, resourceId);
const [ imgSrc ] = useOneTimeAsyncAction(
async () => {
@ -592,7 +657,7 @@ export function useSoftImageSrcResourceSubscription(guild: CombinedGuild, resour
[ resource, fetchError ]
);
return [ imgSrc, resource, fetchError ];
return [ imgSrc, resource, resourceGuild, fetchError ];
}
export function useChannelsSubscription(guild: CombinedGuild) {
@ -629,8 +694,8 @@ export function useMembersSubscription(guild: CombinedGuild) {
}, fetchMembersFunc);
}
export function useSelfMemberSubscription(guild: CombinedGuild): [ selfMember: Member | null ] {
const [ fetchRetryCallable, members, fetchError ] = useMembersSubscription(guild);
export function useSelfMemberSubscription(guild: CombinedGuild): [ selfMember: Member | null, selfMemberGuild: CombinedGuild | null ] {
const [ fetchRetryCallable, members, membersGuild, fetchError ] = useMembersSubscription(guild);
// TODO: Show an error if we can't fetch and allow retry
@ -646,7 +711,7 @@ export function useSelfMemberSubscription(guild: CombinedGuild): [ selfMember: M
return null;
}, [ guild.memberId, members ]);
return [ selfMember ];
return [ selfMember, membersGuild ];
}
export function useTokensSubscription(guild: CombinedGuild) {

View File

@ -23,10 +23,10 @@ const GuildElement: FC<GuildElementProps> = (props: GuildElementProps) => {
// TODO: React set hasMessagesAbove and hasMessagesBelow when re-verified?
// TODO: React jump messages to bottom when the current user sent a message
const [ selfMember ] = useSelfMemberSubscription(guild);
const [ guildMeta, guildMetaFetchError ] = useGuildMetadataSubscription(guild);
const [ membersRetry, members, membersFetchError ] = useMembersSubscription(guild);
const [ channelsRetry, channels, channelsFetchError ] = useChannelsSubscription(guild);
const [ selfMember, selfMemberGuild ] = useSelfMemberSubscription(guild);
const [ guildMeta, guildMetaGuild, guildMetaFetchError ] = useGuildMetadataSubscription(guild);
const [ membersRetry, members, membersGuild, membersFetchError ] = useMembersSubscription(guild);
const [ channelsRetry, channels, channelsGuild, channelsFetchError ] = useChannelsSubscription(guild);
const [ activeChannel, setActiveChannel ] = useState<Channel | null>(null);