Winter 0.4.2-alpha

This commit is contained in:
ADAMJR 2023-01-03 00:50:00 +00:00
parent cdc5eaca23
commit 836cd78fc3
22 changed files with 152 additions and 74 deletions

View File

@ -8,11 +8,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Theme URLs: Easily share themes by their codes.
- Theme Page: Apply other user themes.
### Changed
### Removed
## [Winter 0.4.2-alpha] - 2023/01/03
### Added
- Theme Page: Easily share themes by their codes.
### Changed
### Fixed
- Sidebar: Improved guild icon tooltips.
- Themes: Replaced theme code with URL.
### Removed
- Voice channels (until further notice).
## [Winter 0.4.1-alpha] - 2023/01/01

View File

@ -11,6 +11,11 @@
# FIXME
[2] unused images should be deleted
> user avatars
> guild icons
> images in messages
# VERIFY
[3] member status: members sometimes remain online, after going offline

View File

@ -105,7 +105,11 @@
"integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q=="
},
"node_modules/@acrd/types": {
"resolved": "file:../frontend/src/types"
"resolved": "file:../frontend/src/types",
"hasInstallScript": true,
"dependencies": {
"typescript": "^4.9.4"
}
},
"node_modules/@aws-crypto/ie11-detection": {
"version": "2.0.2",

View File

@ -8,7 +8,8 @@
"start:prod": "ts-node-transpile-only src/app.ts",
"test": "npm run test:unit && npm run test:int",
"test:e2e": "ts-mocha --exit test/e2e/test.ts",
"test:unit": "ts-mocha --exit test/unit/**/**.test.ts"
"test:unit": "ts-mocha --exit test/unit/**/**.test.ts",
"update:types": "rm -rf ./node_modules/@acrd/types && npm i ../types"
},
"keywords": [],
"author": "github.com/theadamjr",
@ -87,4 +88,4 @@
"ts-node": "^10.4.0",
"ts-node-dev": "^1.1.8"
}
}
}

View File

@ -11,6 +11,9 @@ export default class Channels extends DBWrapper<string, ChannelDocument> {
return channel;
}
public async getDM(id: string | undefined) {
return await this.get(id) as DMChannelDocument;
}
public async getText(id: string | undefined) {
return await this.get(id) as TextChannelDocument;
}
@ -28,6 +31,9 @@ export default class Channels extends DBWrapper<string, ChannelDocument> {
});
}
public async createDM(userIds: string[]) {
return this.create({ userIds }) as Promise<DMChannelDocument>;
}
public async createText(guildId: string) {
return this.create({ guildId }) as Promise<TextChannelDocument>;
}

View File

@ -4,6 +4,11 @@ import { createdAtToDate, useId } from '../../utils/utils';
import validators from '../../utils/validators';
import { generateSnowflake } from '../snowflake-entity';
export interface DMChannelDocument extends Document, ChannelTypes.DM {
_id: string | never;
id: string;
createdAt: never;
}
export interface TextChannelDocument extends Document, ChannelTypes.Text {
_id: string | never;
id: string;
@ -13,8 +18,6 @@ export interface VoiceChannelDocument extends Document, ChannelTypes.Voice {
_id: string | never;
id: string;
createdAt: never;
memberIds: string[];
filterProfanity: never;
}
export type ChannelDocument = TextChannelDocument | VoiceChannelDocument;

View File

@ -4,5 +4,5 @@ REACT_APP_CDN_URL="http://localhost:3000/assets"
REACT_APP_WEBSITE_URL="http://localhost:4200"
REACT_APP_REPO_URL="https://github.com/acrdapp/app"
REACT_APP_VERSION_NAME="Winter"
REACT_APP_VERSION_NUMBER="0.4.2-pre-release"
REACT_APP_VERSION_NUMBER="0.4.2-alpha"
REACT_APP_ROOT_API_URL="http://localhost:3000"

View File

@ -4,5 +4,5 @@ REACT_APP_CDN_URL="https://api.acrd.app/assets"
REACT_APP_WEBSITE_URL="https://acrd.app"
REACT_APP_REPO_URL="https://github.com/acrdapp/app"
REACT_APP_VERSION_NAME="Winter"
REACT_APP_VERSION_NUMBER="0.4.2-pre-release"
REACT_APP_VERSION_NUMBER="0.4.2-alpha"
REACT_APP_ROOT_API_URL="https://api.acrd.app"

View File

@ -5,29 +5,29 @@ import { useSelector } from 'react-redux';
export interface TextChannelHeaderProps {
canRead?: boolean;
}
const TextChannelHeader: React.FunctionComponent<TextChannelHeaderProps> = ({ canRead }) => {
const channel = useSelector((s: Store.AppState) => s.ui.activeChannel)!;
return (
<div className="flex m-4 pb-6 border-bottom justify-center">
<div>
<span className="flex justify-center rounded-full">
<FontAwesomeIcon
className="muted bg-bg-tertiary p-4 rounded-full"
icon={canRead ? faHashtag : faEyeSlash}
size="4x" />
</span>
<h1 className="text-3xl font-bold my-2 text-center">
{(canRead)
? `This is #${channel.name}`
: `Message history hidden.`
}</h1>
<p className="lead">
{(canRead)
? `You have reached the top.`
: `Insufficient permissions to view messages in this channel.`
}</p>
<span className="flex justify-center rounded-full">
<FontAwesomeIcon
className="muted bg-bg-tertiary p-4 rounded-full"
icon={canRead ? faHashtag : faEyeSlash}
size="4x" />
</span>
<h1 className="text-3xl font-bold my-2 text-center">
{(canRead)
? `This is #${channel.name}`
: `Message history hidden.`
}</h1>
<p className="lead">
{(canRead)
? `You have reached the top.`
: `Insufficient permissions to view messages in this channel.`
}</p>
</div>
</div>
);

View File

@ -3,9 +3,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { useDispatch, useSelector } from 'react-redux';
import usePerms from '../../hooks/use-perms';
import { actions as ui } from '../../store/ui';
import CreateChannel from '../modals/create-channel';
import CreateInvite from '../modals/create-invite';
import GuildSettings from '../modals/guild-settings/guild-settings';
import Dropdown from '../utils/dropdown';
const GuildDropdown: React.FunctionComponent = () => {
@ -40,14 +37,14 @@ const GuildDropdown: React.FunctionComponent = () => {
{(perms.can('MANAGE_GUILD', guild.id)
|| perms.can('MANAGE_ROLES', guild.id)
|| perms.can('MANAGE_INVITES', guild.id)) && (
<a onClick={() => dispatch(ui.openedModal('GuildSettings'))}
className="rounded-sm flex items-center justify-between p-2 h-8 text-sm">
<span className="font">Guild settings</span>
<FontAwesomeIcon
className="float-right w-1"
icon={faCog} />
</a>
)}
<a onClick={() => dispatch(ui.openedModal('GuildSettings'))}
className="rounded-sm flex items-center justify-between p-2 h-8 text-sm">
<span className="font">Guild settings</span>
<FontAwesomeIcon
className="float-right w-1"
icon={faCog} />
</a>
)}
</Dropdown>
);
}

View File

@ -0,0 +1,25 @@
import { faLock } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import ReactTooltip from 'react-tooltip';
const UserDropdown: React.FunctionComponent = () => {
return null;
// (<h1 className='flex-grow font-bold pl-2 p-3'>
// <FontAwesomeIcon
// data-tip
// data-for={'secureTooltip'}
// icon={faLock}
// color='var(--success)'
// className='mr-2' />
// <ReactTooltip
// id='secureTooltip'
// backgroundColor='var(--bg-tertiary)'
// effect='solid'>
// Messages
// </ReactTooltip>
// <span>Private Messages</span>
// </h1>
// );
}
export default UserDropdown;

View File

@ -16,7 +16,7 @@ const CreateChannel: React.FunctionComponent = () => {
setValue('name', '');
};
const types: ChannelTypes.Type[] = ['TEXT', 'VOICE'];
const types: ChannelTypes.Type[] = ['TEXT'];
return (
<Modal typeName={'CreateChannel'} size="sm">

View File

@ -3,7 +3,7 @@ import { faHashtag, faUserFriends } from '@fortawesome/free-solid-svg-icons';
import { useDispatch, useSelector } from 'react-redux';
import { toggleMemberList } from '../../store/config';
import classNames from 'classnames';
const AppNavbar: React.FunctionComponent = () => {
const dispatch = useDispatch();
const channel = useSelector((s: Store.AppState) => s.ui.activeChannel);
@ -13,6 +13,7 @@ const AppNavbar: React.FunctionComponent = () => {
return (
<div className="shadow-elevation flex items-center h-12 px-5">
{channel && <FontAwesomeIcon
color="var(--muted)"
icon={faHashtag}
className="scale-150 mr-2" />}
<h3 className="flex-grow ml-1">
@ -30,5 +31,5 @@ const AppNavbar: React.FunctionComponent = () => {
</div>
);
}
export default AppNavbar;

View File

@ -17,7 +17,8 @@ import { Entity } from '@acrd/types';
const ChannelTabs: React.FunctionComponent = () => {
const dispatch = useDispatch();
const { activeGuild, activeChannel } = useSelector((s: Store.AppState) => s.ui);
const guildChannels = useSelector(getGuildChannels(activeGuild?.id));
const guildChannels = useSelector(getGuildChannels(activeGuild?.id))
.filter(c => c.type !== 'VOICE');
const perms = usePerms();
if (!activeGuild || !perms.can('VIEW_CHANNELS', activeGuild.id)) return null;

View File

@ -15,7 +15,8 @@ const PlusIcon: React.FunctionComponent<PlusIconProps> = (props) => {
<SidebarIcon
childClasses="success"
disableHoverEffect={props.disableHoverEffect}
name="+" />
name="+"
tooltip="Add Guild" />
</div>
);
}

View File

@ -1,18 +1,22 @@
import SidebarFooter from './sidebar-footer';
import { useDispatch } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import { actions as ui } from '../../../store/ui';
import GuildDropdown from '../../dropdowns/guild-dropdown';
import ChannelTabs from './channel-tabs';
import UserDropdown from '../../dropdowns/user-dropdown';
const SidebarContent: React.FunctionComponent = () => {
const SidebarContent: React.FunctionComponent = () => {
const dispatch = useDispatch();
const guild = useSelector((s: Store.AppState) => s.ui.activeGuild);
return (
<div className="flex flex-col bg-bg-secondary w-60">
<div
id="sidebarHeader"
className="items-center shadow-elevation cursor-pointer h-12 pl-2.5 pr-4"
onClick={() => dispatch(ui.toggleDropdown(GuildDropdown))}>
<GuildDropdown />
{guild && <GuildDropdown />}
{!guild && <UserDropdown />}
</div>
<nav className="sidebar-tabs flex-grow px-2 pt-4">
<ChannelTabs />
@ -21,5 +25,5 @@ const SidebarContent: React.FunctionComponent = () => {
</div>
);
}
export default SidebarContent;

View File

@ -2,11 +2,13 @@ import './sidebar-icon.scoped.css';
import classNames from 'classnames';
import { useLocation } from 'react-router-dom';
import Image from '../../utils/image';
import ReactTooltip from 'react-tooltip';
export interface SidebarIconProps {
imageURL?: string;
name: string;
to?: string;
tooltip?: string;
childClasses?: string;
disableHoverEffect?: boolean;
styles?: any;
@ -31,25 +33,34 @@ const SidebarIcon: React.FunctionComponent<SidebarIconProps> = (props) => {
alt={name} />
: <span className="select-none flex items-center justify-center h-12 w-12">{getAbbr(name)}</span>;
const isActive = to && location.pathname.startsWith(to);
const isActive = (to && location.pathname.startsWith(to));
const activeClasses = (isActive)
? 'rounded-xl bg-primary'
: 'rounded-full';
return (
<div
className={classNames('wrapper sidebar-icon', { 'active': isActive })}
title={name}>
<div className={classNames({
'selected rounded absolute bg-white -left-1 h-0 w-2': !disableHoverEffect,
'hidden': disableHoverEffect,
})} />
<div className={classNames(
`cursor-pointer guild-icon flex justify-center mb-2`,
activeClasses,
childClasses,
)}><Icon /></div>
</div>
<>
<div data-tip
data-for={name + 'GuildTooltip'}
className={classNames('wrapper sidebar-icon', { 'active': isActive })}>
<div className={classNames({
'selected rounded absolute bg-white -left-1 h-0 w-2': !disableHoverEffect,
'hidden': disableHoverEffect,
})} />
<div className={classNames(
`cursor-pointer guild-icon flex justify-center mb-2`,
activeClasses,
childClasses,
)}><Icon /></div>
</div>
<ReactTooltip
id={name + 'GuildTooltip'}
backgroundColor='var(--bg-primary)'
effect='solid'
place='right'>
{props.tooltip}
</ReactTooltip>
</>
);
}

View File

@ -4,9 +4,9 @@ import SidebarIcon from './sidebar-icon';
import { ContextMenuTrigger } from 'react-contextmenu';
import GuildMenu from '../../ctx-menus/guild-menu';
import PlusIcon from './plus-icon';
const SidebarIcons: React.FunctionComponent = () => {
const user = useSelector((s: Store.AppState) => s.auth.user)!;
const user = useSelector((s: Store.AppState) => s.auth.user)!;
const guilds = useSelector((s: Store.AppState) => s.entities.guilds)!;
const guildIcons = guilds.map(g => (
@ -15,19 +15,21 @@ const SidebarIcons: React.FunctionComponent = () => {
<SidebarIcon
to={`/channels/${g.id}`}
imageURL={g.iconURL}
name={g.name} />
name={g.name}
tooltip={g.name} />
</Link>
<GuildMenu guild={g} />
</ContextMenuTrigger>
));
return (
<div className="overflow-auto min-h-screen float-left p-3 flex flex-col bg-bg-tertiary">
<Link to="/channels/@me">
<SidebarIcon
to="/channels/@me"
imageURL={user.avatarURL}
name={user.username} />
name={user.username}
tooltip="Private Messages" />
</Link>
<div className="flex justify-center mb-1">
<div className="h-0.5 w-8 rounded-sm bg-bg-modifier-accent mb-1" />
@ -37,5 +39,5 @@ const SidebarIcons: React.FunctionComponent = () => {
</div>
);
}
export default SidebarIcons;

View File

@ -92,7 +92,10 @@ export declare namespace Entity {
}
}
export declare namespace ChannelTypes {
type Type = 'TEXT' | 'VOICE';
type Type = 'TEXT' | 'VOICE' | 'DM';
interface DM extends Entity.Channel {
type: 'DM';
}
interface Text extends Entity.Channel {
type: 'TEXT';
}

View File

@ -20,7 +20,6 @@ var PermissionTypes;
})(General = PermissionTypes.General || (PermissionTypes.General = {}));
let Text;
(function (Text) {
// ADD_REACTIONS = 2048 * 16,
Text[Text["SEND_FILES"] = 16384] = "SEND_FILES";
Text[Text["READ_MESSAGES"] = 8192] = "READ_MESSAGES";
Text[Text["MANAGE_MESSAGES"] = 4096] = "MANAGE_MESSAGES";
@ -39,7 +38,6 @@ var PermissionTypes;
| PermissionTypes.Text.SEND_MESSAGES
| PermissionTypes.Text.READ_MESSAGES
| PermissionTypes.Text.SEND_FILES
// | PermissionTypes.Text.ADD_REACTIONS
| PermissionTypes.Voice.CONNECT
| PermissionTypes.Voice.SPEAK;
})(PermissionTypes = exports.PermissionTypes || (exports.PermissionTypes = {}));
@ -53,4 +51,4 @@ function getPermString(integer) {
: integer.toString();
}
exports.getPermString = getPermString;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbnMudHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcGVybWlzc2lvbnMudHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsSUFBaUIsZUFBZSxDQTZDL0I7QUE3Q0QsV0FBaUIsZUFBZTtJQUM5QixJQUFZLE9BYVg7SUFiRCxXQUFZLE9BQU87UUFDakIsMERBQW9CLENBQUE7UUFDcEIsMkNBQTJDO1FBQzNDLDBDQUEwQztRQUMxQywyREFBb0IsQ0FBQTtRQUNwQix5REFBbUIsQ0FBQTtRQUNuQixzREFBaUIsQ0FBQTtRQUNqQixxQ0FBcUM7UUFDckMsNERBQW9CLENBQUE7UUFDcEIscURBQWdCLENBQUE7UUFDaEIscURBQWdCLENBQUE7UUFDaEIsdUNBQXVDO1FBQ3ZDLHVEQUFpQixDQUFBO0lBQ25CLENBQUMsRUFiVyxPQUFPLEdBQVAsdUJBQU8sS0FBUCx1QkFBTyxRQWFsQjtJQUNELElBQVksSUFNWDtJQU5ELFdBQVksSUFBSTtRQUNkLDZCQUE2QjtRQUM3QiwrQ0FBcUIsQ0FBQTtRQUNyQixvREFBd0IsQ0FBQTtRQUN4Qix3REFBMEIsQ0FBQTtRQUMxQixvREFBb0IsQ0FBQTtJQUN0QixDQUFDLEVBTlcsSUFBSSxHQUFKLG9CQUFJLEtBQUosb0JBQUksUUFNZjtJQUNELElBQVksS0FLWDtJQUxELFdBQVksS0FBSztRQUNmLHNEQUF3QixDQUFBO1FBQ3hCLHNEQUF3QixDQUFBO1FBQ3hCLHVDQUFpQixDQUFBO1FBQ2pCLDJDQUFlLENBQUE7SUFDakIsQ0FBQyxFQUxXLEtBQUssR0FBTCxxQkFBSyxLQUFMLHFCQUFLLFFBS2hCO0lBQ1ksbUJBQUcsaURBQ1gsT0FBTyxHQUNQLElBQUksR0FDSixLQUFLLENBQ1QsQ0FBQTtJQUlZLGtDQUFrQixHQUM3QixlQUFlLENBQUMsT0FBTyxDQUFDLGFBQWE7VUFDbkMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxhQUFhO1VBQ3JDLGVBQWUsQ0FBQyxJQUFJLENBQUMsYUFBYTtVQUNsQyxlQUFlLENBQUMsSUFBSSxDQUFDLGFBQWE7VUFDbEMsZUFBZSxDQUFDLElBQUksQ0FBQyxVQUFVO1FBQ2pDLHVDQUF1QztVQUNyQyxlQUFlLENBQUMsS0FBSyxDQUFDLE9BQU87VUFDN0IsZUFBZSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7QUFDbEMsQ0FBQyxFQTdDZ0IsZUFBZSxHQUFmLHVCQUFlLEtBQWYsdUJBQWUsUUE2Qy9CO0FBRUQsU0FBZ0IsYUFBYSxDQUFDLE9BQXdCOztJQUNwRCxPQUFPLENBQUMsT0FBTyxPQUFPLEtBQUssUUFBUSxDQUFDO1FBQ2xDLENBQUMsQ0FBQyxNQUFBLE1BQUEsTUFBTTthQUNMLE9BQU8sQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDO2FBQzVCLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDeEMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxPQUFPLElBQUksQ0FBQyxLQUFLLE9BQU8sQ0FBQywwQ0FBRyxDQUFDLENBQUMsbUNBQUksRUFBRTtRQUM5RCxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQ3pCLENBQUM7QUFQRCxzQ0FPQyJ9
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbnMudHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcGVybWlzc2lvbnMudHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsSUFBaUIsZUFBZSxDQTJDL0I7QUEzQ0QsV0FBaUIsZUFBZTtJQUM5QixJQUFZLE9BYVg7SUFiRCxXQUFZLE9BQU87UUFDakIsMERBQW9CLENBQUE7UUFDcEIsMkNBQTJDO1FBQzNDLDBDQUEwQztRQUMxQywyREFBb0IsQ0FBQTtRQUNwQix5REFBbUIsQ0FBQTtRQUNuQixzREFBaUIsQ0FBQTtRQUNqQixxQ0FBcUM7UUFDckMsNERBQW9CLENBQUE7UUFDcEIscURBQWdCLENBQUE7UUFDaEIscURBQWdCLENBQUE7UUFDaEIsdUNBQXVDO1FBQ3ZDLHVEQUFpQixDQUFBO0lBQ25CLENBQUMsRUFiVyxPQUFPLEdBQVAsdUJBQU8sS0FBUCx1QkFBTyxRQWFsQjtJQUNELElBQVksSUFLWDtJQUxELFdBQVksSUFBSTtRQUNkLCtDQUFxQixDQUFBO1FBQ3JCLG9EQUF3QixDQUFBO1FBQ3hCLHdEQUEwQixDQUFBO1FBQzFCLG9EQUFvQixDQUFBO0lBQ3RCLENBQUMsRUFMVyxJQUFJLEdBQUosb0JBQUksS0FBSixvQkFBSSxRQUtmO0lBQ0QsSUFBWSxLQUtYO0lBTEQsV0FBWSxLQUFLO1FBQ2Ysc0RBQXdCLENBQUE7UUFDeEIsc0RBQXdCLENBQUE7UUFDeEIsdUNBQWlCLENBQUE7UUFDakIsMkNBQWUsQ0FBQTtJQUNqQixDQUFDLEVBTFcsS0FBSyxHQUFMLHFCQUFLLEtBQUwscUJBQUssUUFLaEI7SUFDWSxtQkFBRyxpREFDWCxPQUFPLEdBQ1AsSUFBSSxHQUNKLEtBQUssQ0FDVCxDQUFBO0lBSVksa0NBQWtCLEdBQzdCLGVBQWUsQ0FBQyxPQUFPLENBQUMsYUFBYTtVQUNuQyxlQUFlLENBQUMsT0FBTyxDQUFDLGFBQWE7VUFDckMsZUFBZSxDQUFDLElBQUksQ0FBQyxhQUFhO1VBQ2xDLGVBQWUsQ0FBQyxJQUFJLENBQUMsYUFBYTtVQUNsQyxlQUFlLENBQUMsSUFBSSxDQUFDLFVBQVU7VUFDL0IsZUFBZSxDQUFDLEtBQUssQ0FBQyxPQUFPO1VBQzdCLGVBQWUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO0FBQ2xDLENBQUMsRUEzQ2dCLGVBQWUsR0FBZix1QkFBZSxLQUFmLHVCQUFlLFFBMkMvQjtBQUVELFNBQWdCLGFBQWEsQ0FBQyxPQUF3Qjs7SUFDcEQsT0FBTyxDQUFDLE9BQU8sT0FBTyxLQUFLLFFBQVEsQ0FBQztRQUNsQyxDQUFDLENBQUMsTUFBQSxNQUFBLE1BQU07YUFDTCxPQUFPLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQzthQUM1QixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ3hDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssT0FBTyxJQUFJLENBQUMsS0FBSyxPQUFPLENBQUMsMENBQUcsQ0FBQyxDQUFDLG1DQUFJLEVBQUU7UUFDOUQsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUN6QixDQUFDO0FBUEQsc0NBT0MifQ==

View File

@ -1,7 +1,10 @@
{
"name": "@acrd/types",
"main": "lib/main.js",
"scripts": {
"preinstall": "tsc"
},
"dependencies": {
"typescript": "^4.9.4"
}
}
}

View File

@ -93,8 +93,12 @@ export namespace Entity {
}
export namespace ChannelTypes {
export type Type = 'TEXT' | 'VOICE';
export type Type = 'TEXT' | 'VOICE' | 'DM';
export interface DM extends Entity.Channel {
type: 'DM';
userIds: string[];
}
export interface Text extends Entity.Channel {
type: 'TEXT';
}