92 lines
2.6 KiB
TypeScript
92 lines
2.6 KiB
TypeScript
|
import { ReactNode } from 'react';
|
||
|
import { atom, selector } from 'recoil';
|
||
|
import { Channel, GuildMetadata, Member, Message } from '../data-types';
|
||
|
import CombinedGuild from '../guild-combined';
|
||
|
|
||
|
export interface GuildWithValue<T> {
|
||
|
guild: CombinedGuild;
|
||
|
value: T;
|
||
|
}
|
||
|
|
||
|
export interface GuildWithErrorableValue<T> {
|
||
|
guild: CombinedGuild;
|
||
|
value: T | null;
|
||
|
valueError: unknown | null;
|
||
|
}
|
||
|
|
||
|
export interface ChannelWithErrorableValue<T> {
|
||
|
channel: Channel;
|
||
|
value: T | null;
|
||
|
valueError: unknown | null;
|
||
|
}
|
||
|
|
||
|
export const overlayState = atom<ReactNode>({
|
||
|
key: 'overlayState',
|
||
|
default: null
|
||
|
});
|
||
|
|
||
|
export const guildsState = atom<GuildWithErrorableValue<GuildMetadata>[] | null>({
|
||
|
key: 'guildsState',
|
||
|
default: null
|
||
|
});
|
||
|
|
||
|
export const selectedGuildIdState = atom<number | null>({
|
||
|
key: 'selectedGuildIdState',
|
||
|
default: null
|
||
|
});
|
||
|
|
||
|
export const selectedGuildWithMetaState = selector<GuildWithErrorableValue<GuildMetadata> | null>({
|
||
|
key: 'selectedGuildWithMetaState',
|
||
|
get: ({ get }) => {
|
||
|
const guildsWithMeta = get(guildsState);
|
||
|
if (guildsWithMeta === null) return null;
|
||
|
|
||
|
const guildId = get(selectedGuildIdState);
|
||
|
if (guildId === null) return null;
|
||
|
|
||
|
return guildsWithMeta.find(guildWithMeta => guildWithMeta.guild.id === guildId) ?? null;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
export const selectedGuildState = selector<CombinedGuild | null>({
|
||
|
key: 'selectedGuildState',
|
||
|
get: ({ get }) => {
|
||
|
const guildWithMeta = get(selectedGuildWithMetaState);
|
||
|
if (guildWithMeta === null) return null;
|
||
|
|
||
|
return guildWithMeta.guild;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
export const selectedGuildMembersState = atom<GuildWithErrorableValue<Member[]> | null>({
|
||
|
key: 'selectedGuildMembersState',
|
||
|
default: null
|
||
|
});
|
||
|
|
||
|
export const selectedGuildWithChannelsState = atom<GuildWithErrorableValue<Channel[]> | null>({
|
||
|
key: 'selectedGuildChannelsState',
|
||
|
default: null
|
||
|
});
|
||
|
|
||
|
export const selectedGuildWithActiveChannelIdState = atom<GuildWithValue<string | null> | null>({
|
||
|
key: 'selectedGuildWithActiveChannelIdState',
|
||
|
default: null
|
||
|
});
|
||
|
|
||
|
|
||
|
export const selectedGuildWithActiveChannelMessagesState = atom<GuildWithValue<ChannelWithErrorableValue<Message[]> | null> | null>({
|
||
|
key: 'selectedGuildWithActiveChannelMessagesState',
|
||
|
default: null
|
||
|
});
|
||
|
|
||
|
export const selectedGuildWithActiveChannelState = selector<GuildWithValue<Channel> | null>({
|
||
|
key: 'selectedGuildActiveChannelState',
|
||
|
get: ({ get }) => {
|
||
|
const guildWithChannelMessages = get(selectedGuildWithActiveChannelMessagesState);
|
||
|
if (guildWithChannelMessages === null || guildWithChannelMessages.value === null) return null;
|
||
|
|
||
|
return { guild: guildWithChannelMessages.guild, value: guildWithChannelMessages.value.channel };
|
||
|
}
|
||
|
});
|
||
|
|