BetterForwards: bug fixes and improvements (#1286)
* BetterForwards: bug fixes, improvements * BetterForwards: unknown channel fallback * BetterForwards: Guild and channel preload, bug fixes * BetterForwards: DM/GDM icons * BetterForwards: remove unnecessary condition * BetterForwards: hide current server * Update stores.ts * Clean up imports and type definitions in components.tsx Removed unused imports and type definitions for better code clarity. --------- Co-authored-by: thororen <78185467+thororen1234@users.noreply.github.com>
This commit is contained in:
parent
bc6abcbda6
commit
d6aa5a0325
7 changed files with 182 additions and 85 deletions
|
|
@ -332,6 +332,8 @@ export class Channel extends DiscordRecord {
|
|||
isMultiUserDM(): boolean;
|
||||
/** Whether the channel is marked as NSFW. */
|
||||
isNSFW(): boolean;
|
||||
/** Whether the channel details are obfuscated */
|
||||
isObfuscated(): boolean;
|
||||
/**
|
||||
* Checks if the given user is the channel owner.
|
||||
* @param userId User ID to check.
|
||||
|
|
|
|||
13
packages/discord-types/src/stores/BasicGuildStore.d.ts
vendored
Normal file
13
packages/discord-types/src/stores/BasicGuildStore.d.ts
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { FluxStore, Guild } from "..";
|
||||
|
||||
export interface BasicGuild extends Pick<Guild, "id" | "name" | "description" | "icon" | "splash" | "features"> {
|
||||
discovery_splash: Guild["discoverySplash"];
|
||||
home_header: Guild["homeHeader"];
|
||||
}
|
||||
|
||||
export class BasicGuildStore extends FluxStore {
|
||||
getGuild(guildId: string): BasicGuild;
|
||||
getGuildOrStatus(guildId: string): BasicGuild | { type: "loading"; } | { type: "failed"; } | undefined;
|
||||
isGuildFetching(guildId: string): boolean;
|
||||
getVersion(): number;
|
||||
}
|
||||
1
packages/discord-types/src/stores/index.d.ts
vendored
1
packages/discord-types/src/stores/index.d.ts
vendored
|
|
@ -9,6 +9,7 @@ export * from "./ApplicationStreamPreviewStore";
|
|||
export * from "./AuthenticationStore";
|
||||
export * from "./AuthorizedAppsStore";
|
||||
export * from "./AuthSessionsStore";
|
||||
export * from "./BasicGuildStore";
|
||||
export * from "./CallStore";
|
||||
export * from "./ChannelMemberStore";
|
||||
export * from "./ChannelRTCStore";
|
||||
|
|
|
|||
|
|
@ -8,11 +8,12 @@ import { BaseText } from "@components/BaseText";
|
|||
import { Flex, FlexProps } from "@components/Flex";
|
||||
import { RightArrow } from "@components/Icons";
|
||||
import { iconsModule } from "@equicordplugins/_core/concatenatedModules";
|
||||
import { MessageAttachment } from "@vencord/discord-types";
|
||||
import { ChannelType } from "@vencord/discord-types/enums";
|
||||
import { getGuildAcronym, getIntlMessage } from "@utils/discord";
|
||||
import { getUserAvatarUrl } from "@utils/misc";
|
||||
import { BasicGuild, Guild, MessageAttachment } from "@vencord/discord-types";
|
||||
import { findByCodeLazy, findComponentByCodeLazy, findCssClassesLazy } from "@webpack";
|
||||
import { ChannelStore, DateUtils, GuildStore, IconUtils, match, NavigationRouter, Popout, React, SelectedGuildStore, SnowflakeUtils, useMemo, useRef, UserStore, useStateFromStores } from "@webpack/common";
|
||||
import { PropsWithChildren } from "react";
|
||||
import { BasicGuildStore, ChannelActionCreators, ChannelStore, DateUtils, GuildStore, IconUtils, Popout, React, RelationshipStore, SelectedGuildStore, SnowflakeUtils, useEffect, useMemo, useRef, UserStore, useStateFromStores } from "@webpack/common";
|
||||
import { PropsWithChildren, ReactNode } from "react";
|
||||
|
||||
import { cl, ForwardOptionsContext, ForwardOptionsState } from ".";
|
||||
|
||||
|
|
@ -20,25 +21,40 @@ type AttachmentType = "IMAGE" | "VIDEO" | "CLIP" | "AUDIO" | "VISUAL_PLACEHOLDER
|
|||
|
||||
const tagClasses = findCssClassesLazy("tagList", "tagGroup", "tag");
|
||||
const ServerProfileComponent = findComponentByCodeLazy("{guildProfile:", "GUILD_PROFILE");
|
||||
const getAttachmentType: (attachment: MessageAttachment, inlineAttachmentMedia?: boolean) => AttachmentType = findByCodeLazy('"PLAINTEXT_PREVIEW":"OTHER"');
|
||||
const getAttachmentType = findByCodeLazy('"PLAINTEXT_PREVIEW":"OTHER"');
|
||||
const formatChannelName = findByCodeLazy("#{intl::NO_ACCESS}", "isObfuscated()");
|
||||
const getChannelIcon = findByCodeLazy("textFocused:", "isGameInvitesChannel()");
|
||||
const navigateTo = findByCodeLazy('getConfig({location:"channel_mention"})');
|
||||
const fetchBasicGuild = findByCodeLazy('type:"BASIC_GUILD_FETCH_SUCCESS"');
|
||||
|
||||
export function GuildName({ guildId }: { guildId: string; }) {
|
||||
const guild = useStateFromStores(
|
||||
[GuildStore, SelectedGuildStore],
|
||||
() => {
|
||||
const current = SelectedGuildStore.getGuildId();
|
||||
return current !== guildId ? GuildStore.getGuild(guildId) : null;
|
||||
},
|
||||
const currentGuildId = useStateFromStores([SelectedGuildStore], () => SelectedGuildStore.getGuildId(), []);
|
||||
const guild: Guild | BasicGuild | undefined = useStateFromStores(
|
||||
[GuildStore, BasicGuildStore],
|
||||
() => GuildStore.getGuild(guildId) ?? BasicGuildStore.getGuild(guildId),
|
||||
[guildId]
|
||||
);
|
||||
|
||||
const icon = useMemo(() => {
|
||||
if (!guild?.icon) return null;
|
||||
return IconUtils.getGuildIconURL({ id: guildId, icon: guild.icon, canAnimate: true, size: 16 });
|
||||
}, [guildId, guild?.icon]);
|
||||
if (!guild) return null;
|
||||
|
||||
return guild.icon ? (
|
||||
<img
|
||||
src={IconUtils.getGuildIconURL({ ...guild, canAnimate: true, size: 16 })}
|
||||
alt={`Server icon for ${guild.name}`}
|
||||
className={cl("guild-icon")}
|
||||
/>
|
||||
) : (
|
||||
<div className={cl("guild-acronym")}>{getGuildAcronym(guild)}</div>
|
||||
);
|
||||
}, [guild]);
|
||||
|
||||
const guildDivRef = useRef(null);
|
||||
|
||||
useEffect(() => void fetchBasicGuild(guildId), [guildId]);
|
||||
|
||||
return (
|
||||
guild && (
|
||||
currentGuildId !== guildId && (
|
||||
<Popout
|
||||
position="top"
|
||||
renderPopout={() => <ServerProfileComponent guildId={guildId} />}
|
||||
|
|
@ -46,11 +62,11 @@ export function GuildName({ guildId }: { guildId: string; }) {
|
|||
>
|
||||
{popoutProps => (
|
||||
<div ref={guildDivRef} className={cl("footer-element")} {...popoutProps}>
|
||||
{icon && <img src={icon} alt={`Server icon for ${guild.name}`} className={cl("guild-icon")} />}
|
||||
{icon}
|
||||
<BaseText size="sm" weight="medium" className={cl("footer-text")}>
|
||||
{guild ? guild.name : "View server"}
|
||||
</BaseText>
|
||||
<RightArrow width={12} height={12} fill="var(--text-muted)" />
|
||||
<RightArrow width={12} height={12} fill="currentColor" />
|
||||
</div>
|
||||
)}
|
||||
</Popout>
|
||||
|
|
@ -59,45 +75,61 @@ export function GuildName({ guildId }: { guildId: string; }) {
|
|||
}
|
||||
|
||||
export function ChannelName({ guildId, channelId, messageId }: { guildId?: string; channelId: string; messageId: string; }) {
|
||||
const name = useStateFromStores(
|
||||
[ChannelStore, UserStore],
|
||||
() => {
|
||||
const channel = ChannelStore.getChannel(channelId);
|
||||
if (!channel) return null;
|
||||
|
||||
return match(channel.type)
|
||||
.with(ChannelType.DM, () => {
|
||||
const user = UserStore.getUser(channel.recipients[0]);
|
||||
return `@${user.globalName || user.username}`;
|
||||
})
|
||||
.with(ChannelType.GROUP_DM, () => {
|
||||
if (channel.name) return channel.name;
|
||||
const users = channel.recipients.map(r => UserStore.getUser(r));
|
||||
return users.map(u => u.globalName || u.username).join(", ");
|
||||
})
|
||||
.with(
|
||||
ChannelType.ANNOUNCEMENT_THREAD,
|
||||
ChannelType.PRIVATE_THREAD,
|
||||
ChannelType.PUBLIC_THREAD,
|
||||
() => channel.name
|
||||
)
|
||||
.otherwise(() => `#${channel.name}`);
|
||||
},
|
||||
[channelId]
|
||||
const channel = useStateFromStores([ChannelStore], () => ChannelStore.getChannel(channelId), [channelId]);
|
||||
const name: ReactNode = useStateFromStores(
|
||||
[UserStore, RelationshipStore],
|
||||
() =>
|
||||
channel ? (
|
||||
formatChannelName(channel, UserStore, RelationshipStore, false, false)
|
||||
) : (
|
||||
<i>{guildId ? getIntlMessage("UNKNOWN_CHANNEL").toLowerCase() : getIntlMessage("UNKNOWN_USER")}</i>
|
||||
),
|
||||
[channel, guildId]
|
||||
);
|
||||
|
||||
const icon = useMemo(() => {
|
||||
if (channel?.isDM()) {
|
||||
const [user] = channel.recipients.map(UserStore.getUser).filter(Boolean);
|
||||
if (user)
|
||||
return (
|
||||
<img
|
||||
src={getUserAvatarUrl(user, guildId, true, 16)}
|
||||
alt={`DM icon for ${name}`}
|
||||
className={cl("user-icon")}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (channel?.isGroupDM()) {
|
||||
return (
|
||||
<img
|
||||
src={IconUtils.getChannelIconURL({
|
||||
...channel,
|
||||
applicationId: channel.getApplicationId(),
|
||||
size: 16
|
||||
})}
|
||||
alt={`Group DM icon for ${name}`}
|
||||
className={cl("user-icon")}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const Icon = (channel && getChannelIcon(channel)) ?? (guildId ? iconsModule.TextIcon : iconsModule.AtIcon);
|
||||
return <Icon size="xs" color="currentColor" />;
|
||||
}, [channel, guildId, name]);
|
||||
|
||||
return (
|
||||
name && (
|
||||
<div
|
||||
className={cl("footer-element")}
|
||||
onClick={() => NavigationRouter.transitionTo(`/channels/${guildId ?? "@me"}/${channelId}/${messageId}`)}
|
||||
>
|
||||
<BaseText size="sm" weight="medium" className={cl("footer-text")}>
|
||||
{name}
|
||||
</BaseText>
|
||||
<RightArrow width={12} height={12} fill="var(--text-muted)" />
|
||||
</div>
|
||||
)
|
||||
<div
|
||||
className={cl("footer-element")}
|
||||
onClick={() => navigateTo(guildId ?? "@me", channelId, messageId)}
|
||||
onMouseEnter={() => ChannelActionCreators.preload(guildId ?? "@me", channelId)}
|
||||
>
|
||||
{icon}
|
||||
<BaseText size="sm" weight="medium" className={cl("footer-text")}>
|
||||
{name}
|
||||
</BaseText>
|
||||
<RightArrow width={12} height={12} fill="currentColor" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -118,18 +150,19 @@ export function Timestamp({ snowflake }: { snowflake: string; }) {
|
|||
|
||||
export function ForwardPicker() {
|
||||
const state = React.useContext(ForwardOptionsContext);
|
||||
const { message } = state;
|
||||
|
||||
if (state.message.embeds.length + state.message.attachments.length === 0) return null;
|
||||
if (!message || message.embeds.length + message.attachments.length === 0) return null;
|
||||
|
||||
return (
|
||||
<Flex gap={12} flexDirection="column">
|
||||
{state.message.attachments.length > 0 && <AttachmentPicker {...state} />}
|
||||
{state.message.embeds.length > 0 && <EmbedPicker {...state} />}
|
||||
{message.attachments.length > 0 && <AttachmentPicker {...state} message={message} />}
|
||||
{message.embeds.length > 0 && <EmbedPicker {...state} message={message} />}
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
export function EmbedPicker({ message, opts, setOpts, hasOpts, defaultOpts }: ForwardOptionsState) {
|
||||
export function EmbedPicker({ message, opts, setOpts, hasOpts, defaultOpts }: Required<ForwardOptionsState>) {
|
||||
const embeds = useMemo(() => {
|
||||
let id = 0;
|
||||
return message.embeds.map(({ rawTitle, rawDescription, image, images = image ? [image] : [], video }, i) => {
|
||||
|
|
@ -158,7 +191,7 @@ export function EmbedPicker({ message, opts, setOpts, hasOpts, defaultOpts }: Fo
|
|||
|
||||
const { EmbedIcon, ImageIcon } = iconsModule;
|
||||
|
||||
return embeds.map(({ title, subEmbeds }) => (
|
||||
return embeds?.map(({ title, subEmbeds }) => (
|
||||
<Flex gap={4} flexDirection="column" key={subEmbeds[0].id}>
|
||||
<BaseText
|
||||
size="sm"
|
||||
|
|
@ -176,7 +209,7 @@ export function EmbedPicker({ message, opts, setOpts, hasOpts, defaultOpts }: Fo
|
|||
key={id}
|
||||
id={id}
|
||||
source={hasOpts ? (opts.onlyEmbedIndices ?? []) : defaultOpts.onlyEmbedIndices}
|
||||
onChange={data => setOpts(prev => ({ ...prev, onlyEmbedIndices: data }))}
|
||||
onChange={onlyEmbedIndices => setOpts(prev => ({ ...prev, onlyEmbedIndices }))}
|
||||
disabled={!hasOpts}
|
||||
>
|
||||
{Icon && <Icon size="xs" style={{ flexShrink: 0 }} />}
|
||||
|
|
@ -189,7 +222,7 @@ export function EmbedPicker({ message, opts, setOpts, hasOpts, defaultOpts }: Fo
|
|||
));
|
||||
}
|
||||
|
||||
export function AttachmentPicker({ message, opts, setOpts, hasOpts, defaultOpts }: ForwardOptionsState) {
|
||||
export function AttachmentPicker({ message, opts, setOpts, hasOpts, defaultOpts }: Required<ForwardOptionsState>) {
|
||||
return (
|
||||
<TagContainer>
|
||||
{message.attachments.map(attachment => (
|
||||
|
|
@ -197,7 +230,7 @@ export function AttachmentPicker({ message, opts, setOpts, hasOpts, defaultOpts
|
|||
key={attachment.id}
|
||||
id={attachment.id}
|
||||
source={hasOpts ? opts.onlyAttachmentIds ?? [] : defaultOpts.onlyAttachmentIds}
|
||||
onChange={data => setOpts(prev => ({ ...prev, onlyAttachmentIds: data }))}
|
||||
onChange={onlyAttachmentIds => setOpts(prev => ({ ...prev, onlyAttachmentIds }))}
|
||||
disabled={!hasOpts}
|
||||
>
|
||||
<AttachmentIcon attachment={attachment} />
|
||||
|
|
@ -219,7 +252,7 @@ function Tag<T>({ id, children, source, onChange, disabled }: { id: T; source: T
|
|||
<div
|
||||
className={tagClasses.tag}
|
||||
data-selection-mode="multiple"
|
||||
data-selected={!disabled &&selected ? "true" : undefined}
|
||||
data-selected={!disabled && selected ? "true" : undefined}
|
||||
onClick={() => onChange(selected ? source.filter(x => x !== id) : [...source, id])}
|
||||
style={{ textWrap: "wrap", opacity: disabled ? .5 : undefined }}
|
||||
inert={disabled}
|
||||
|
|
@ -229,7 +262,7 @@ function Tag<T>({ id, children, source, onChange, disabled }: { id: T; source: T
|
|||
);
|
||||
}
|
||||
|
||||
const icons: Partial<Record<AttachmentType, string>> = {
|
||||
const attachmentIcons: Partial<Record<AttachmentType, string>> = {
|
||||
IMAGE: "Image",
|
||||
VIDEO: "Video",
|
||||
CLIP: "Clips",
|
||||
|
|
@ -240,7 +273,7 @@ const icons: Partial<Record<AttachmentType, string>> = {
|
|||
function AttachmentIcon({ attachment }: { attachment: MessageAttachment; }) {
|
||||
const Icon = useMemo(() => {
|
||||
const type = getAttachmentType(attachment, true);
|
||||
return iconsModule[(icons[type] ?? "ImageFile") + "Icon"];
|
||||
return iconsModule[(attachmentIcons[type] ?? "ImageFile") + "Icon"];
|
||||
}, [attachment]);
|
||||
|
||||
return Icon && <Icon size="xs" style={{ flexShrink: 0 }} />;
|
||||
|
|
|
|||
|
|
@ -34,16 +34,15 @@ export interface ForwardOptionsState {
|
|||
setOpts: Dispatch<SetStateAction<ForwardOptions>>;
|
||||
defaultOpts: Required<ForwardOptions>;
|
||||
hasOpts: boolean;
|
||||
message: Message;
|
||||
message?: Message;
|
||||
}
|
||||
|
||||
export const ForwardOptionsContext = proxyLazyWebpack(() =>
|
||||
React.createContext<ForwardOptionsState & { message: Message }>({
|
||||
React.createContext<ForwardOptionsState>({
|
||||
opts: {},
|
||||
setOpts: () => {},
|
||||
setOpts: () => { },
|
||||
defaultOpts: { onlyAttachmentIds: [], onlyEmbedIndices: [] },
|
||||
hasOpts: false,
|
||||
message: {} as Message
|
||||
})
|
||||
);
|
||||
|
||||
|
|
@ -159,7 +158,7 @@ export default definePlugin({
|
|||
}
|
||||
],
|
||||
|
||||
async sendForward(additionalMessage: string | null, channels: { id: string; type: string }[], message: Message, options: ForwardOptions) {
|
||||
async sendForward(additionalMessage: string | null, channels: { id: string; type: string; }[], message: Message, options: ForwardOptions) {
|
||||
const contentMessage = message.messageSnapshots[0]?.message ?? message;
|
||||
|
||||
const newLine = `\n${settings.store.forwardPreface} `;
|
||||
|
|
@ -199,7 +198,7 @@ export default definePlugin({
|
|||
ignore = !!event?.shiftKey;
|
||||
},
|
||||
|
||||
renderForwardFooter({ message }: { message: Message }) {
|
||||
renderForwardFooter({ message }: { message: Message; }) {
|
||||
if (!message.messageReference) return null;
|
||||
|
||||
const { guild_id, channel_id, message_id } = message.messageReference;
|
||||
|
|
@ -215,8 +214,9 @@ export default definePlugin({
|
|||
);
|
||||
},
|
||||
|
||||
useProps(props: { message: Message; forwardOptions?: ForwardOptions }) {
|
||||
const message = props.message.messageSnapshots[0]?.message ?? props.message;
|
||||
useProps(props: { message?: Message; forwardOptions?: ForwardOptions; }) {
|
||||
// Message is undefined in certain forward contexts (e.g. forwarding an item from the shop)
|
||||
const message = props.message?.messageSnapshots[0]?.message ?? props.message;
|
||||
|
||||
const [opts, setOpts] = useState(() => {
|
||||
if (!props.forwardOptions || !props.forwardOptions.onlyEmbedIndices)
|
||||
|
|
@ -226,18 +226,18 @@ export default definePlugin({
|
|||
const embedsIds = new Set(props.forwardOptions.onlyEmbedIndices as number[]);
|
||||
|
||||
// Discord incorrectly assumes that embed indices directly map to whole embeds, this is an attempt to fix that
|
||||
const onlyEmbedIndices = message.embeds
|
||||
const onlyEmbedIndices = message?.embeds
|
||||
.flatMap((e, i) => e.images?.map(() => ({ id: id++, eId: i })) ?? { id: id++, eId: i })
|
||||
.filter(({ eId }) => embedsIds.has(eId))
|
||||
.map(({ id }) => id);
|
||||
.map(({ id }) => id) ?? [];
|
||||
|
||||
return { ...props.forwardOptions, onlyEmbedIndices };
|
||||
});
|
||||
|
||||
const defaultOpts = useMemo(
|
||||
() => ({
|
||||
onlyAttachmentIds: message.attachments.map(a => a.id),
|
||||
onlyEmbedIndices: message.embeds.flatMap(e => e.images ?? [{}]).map((_, i) => i)
|
||||
onlyAttachmentIds: message?.attachments.map(a => a.id) ?? [],
|
||||
onlyEmbedIndices: message?.embeds.flatMap(e => e.images ?? [{}]).map((_, i) => i) ?? []
|
||||
}),
|
||||
[message]
|
||||
);
|
||||
|
|
@ -272,7 +272,7 @@ export default definePlugin({
|
|||
<ErrorBoundary noop>
|
||||
<ForwardOptionsContext.Provider value={state}>
|
||||
{children}
|
||||
{message.embeds.length + message.attachments.length > 0 && (
|
||||
{message && message.embeds.length + message.attachments.length > 0 && (
|
||||
<Flex className={Margins.top16}>
|
||||
<Checkbox value={!hasOpts} onChange={() => setOpts(!hasOpts ? defaultOpts : {})} size={20}>
|
||||
<BaseText size="sm">Forward everything</BaseText>
|
||||
|
|
|
|||
|
|
@ -8,10 +8,32 @@
|
|||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.vc-betterforwards-guild-icon {
|
||||
margin-block: 0;
|
||||
border-radius: 4px;
|
||||
.vc-betterforwards-guild-icon,
|
||||
.vc-betterforwards-user-icon,
|
||||
.vc-betterforwards-guild-acronym {
|
||||
margin-right: 2px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.vc-betterforwards-guild-icon {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.vc-betterforwards-user-icon {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.vc-betterforwards-guild-acronym {
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
font-size: 9.6px;
|
||||
border-radius: 4px;
|
||||
white-space: nowrap;
|
||||
background-color: var(--background-base-lower);
|
||||
color: var(--text-default);
|
||||
}
|
||||
|
||||
.vc-betterforwards-footer-element {
|
||||
|
|
@ -39,6 +61,12 @@
|
|||
padding: 1px 0 1px 2px;
|
||||
border-radius: 4px;
|
||||
vertical-align: middle;
|
||||
color: var(--text-muted);
|
||||
|
||||
svg,
|
||||
img {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -48,6 +76,26 @@
|
|||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
[class^="forwardPreview"] > [class^="contentWrapper"] {
|
||||
overflow: hidden;
|
||||
}
|
||||
[class^="forwardPreview"] {
|
||||
height: fit-content;
|
||||
|
||||
> [class^="contentWrapper"] {
|
||||
max-height: 250px;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: thin;
|
||||
|
||||
> [class^="forwardPreviewMessage"] {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
[class^="tagGroup"] > [class^="tag"] {
|
||||
text-wrap: nowrap !important;
|
||||
min-width: 0;
|
||||
|
||||
.vc-text-base {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ export let ReferencedMessageStore: t.ReferencedMessageStore;
|
|||
export let SessionsStore: t.SessionsStore;
|
||||
export let GuildAvailabilityStore: t.GuildAvailabilityStore;
|
||||
export let UserGuildJoinRequestStore: t.UserGuildJoinRequestStore;
|
||||
export let BasicGuildStore: t.BasicGuildStore;
|
||||
|
||||
/**
|
||||
* @see jsdoc of {@link t.useStateFromStores}
|
||||
|
|
@ -179,14 +180,13 @@ waitForStore("AuthSessionsStore", m => AuthSessionsStore = m);
|
|||
waitForStore("ClientThemesBackgroundStore", m => ClientThemesBackgroundStore = m);
|
||||
waitForStore("ConnectedAccountsStore", m => ConnectedAccountsStore = m);
|
||||
waitForStore("ChannelMemberStore", m => ChannelMemberStore = m);
|
||||
// comeback
|
||||
waitForStore("ThreadMemberListStore", m => ThreadMemberListStore = m);
|
||||
waitForStore("CollapsedVoiceChannelStore", m => CollapsedVoiceChannelStore = m);
|
||||
waitForStore("ReferencedMessageStore", m => ReferencedMessageStore = m);
|
||||
// comeback
|
||||
waitForStore("SessionsStore", m => SessionsStore = m);
|
||||
waitForStore("GuildAvailabilityStore", m => GuildAvailabilityStore = m);
|
||||
waitForStore("UserGuildJoinRequestStore", m => UserGuildJoinRequestStore = m);
|
||||
waitForStore("BasicGuildStore", m => BasicGuildStore = m);
|
||||
waitForStore("ThemeStore", m => {
|
||||
ThemeStore = m;
|
||||
// Importing this directly causes all webpack commons to be imported, which can easily cause circular dependencies.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue