cordis/src/client/webapp/elements/atoms.ts

92 lines
2.6 KiB
TypeScript
Raw Normal View History

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 };
}
});