LTS Code. Tried to add DMs *I failed
This commit is contained in:
parent
e6e063366d
commit
77f611886b
@ -6,7 +6,22 @@ import { WSEvent } from './ws-event';
|
||||
export default class implements WSEvent<'CHANNEL_CREATE'> {
|
||||
public on = 'CHANNEL_CREATE' as const;
|
||||
|
||||
public async invoke(ws: WebSocket, client: Socket, { name, guildId, type }: WS.Params.ChannelCreate) {
|
||||
public async invoke(ws: WebSocket, client: Socket, params: WS.Params.ChannelCreate) {
|
||||
const { name, guildId, type, userIds } = params;
|
||||
|
||||
if (type === 'DM') {
|
||||
if (!userIds) throw new TypeError('userIds required for DM creation');
|
||||
const channel = await deps.channels.createDM(userIds);
|
||||
return [{
|
||||
emit: this.on,
|
||||
to: userIds,
|
||||
send: {
|
||||
channel,
|
||||
creatorId: ws.sessions.get(client.id),
|
||||
},
|
||||
}];
|
||||
}
|
||||
|
||||
if (!name || !guildId || !type)
|
||||
throw new TypeError('Not enough options were provided');
|
||||
|
||||
@ -23,4 +38,4 @@ export default class implements WSEvent<'CHANNEL_CREATE'> {
|
||||
},
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ import OverviewPage from './pages/overview-page';
|
||||
import LogoutPage from './pages/auth/logout-page';
|
||||
import PrivateRoute from './routing/private-route';
|
||||
import NotFoundPage from './pages/not-found-page';
|
||||
import DMPage from './pages/dm-page';
|
||||
import { useEffect } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { ready } from '../store/auth';
|
||||
@ -38,6 +39,7 @@ export default function App() {
|
||||
{/* Users must be logged in to use private routes. */}
|
||||
<PrivateRoute exact path="/themes/:themeCode" component={ThemePage} />
|
||||
<PrivateRoute exact path="/channels/@me" component={OverviewPage} />
|
||||
<PrivateRoute exact path="/channels/@me/:channelId?" component={DMPage} />
|
||||
<PrivateRoute exact path="/channels/:guildId/:channelId?" component={GuildPage} />
|
||||
|
||||
{/* This route is a catch-all for any other routes that don't exist. */}
|
||||
|
@ -11,7 +11,7 @@ import { Util } from '@acrd/types';
|
||||
const TextBasedChannel: React.FunctionComponent = () => {
|
||||
const dispatch = useDispatch();
|
||||
const channel = useSelector((s: Store.AppState) => s.ui.activeChannel)!;
|
||||
const guild = useSelector((s: Store.AppState) => s.ui.activeGuild)!;
|
||||
const guild = useSelector((s: Store.AppState) => s.ui.activeGuild);
|
||||
const messages = useSelector(getChannelMessages(channel.id));
|
||||
const perms = usePerms();
|
||||
const [cachedContent, setCachedContent] = useState<Util.Dictionary>({});
|
||||
@ -41,7 +41,11 @@ const TextBasedChannel: React.FunctionComponent = () => {
|
||||
dispatch(fetchMessages(channel.id, back));
|
||||
}
|
||||
|
||||
const canRead = perms.canInChannel('READ_MESSAGES', guild.id, channel.id);
|
||||
const canRead = channel.type === 'DM'
|
||||
? true
|
||||
: guild
|
||||
? perms.canInChannel('READ_MESSAGES', guild.id, channel.id)
|
||||
: false;
|
||||
|
||||
const LoadingIndicator: React.FunctionComponent = () => (
|
||||
<>
|
||||
|
36
frontend/src/components/navigation/sidebar/dm-list.tsx
Normal file
36
frontend/src/components/navigation/sidebar/dm-list.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { getDMChannels } from '../../../store/channels';
|
||||
import FoundUsername from '../../user/username';
|
||||
import { ChannelTypes } from '@acrd/types';
|
||||
|
||||
const DMList: React.FunctionComponent = () => {
|
||||
const channels = useSelector(getDMChannels());
|
||||
const selfUser = useSelector((s: Store.AppState) => s.auth.user)!;
|
||||
const users = useSelector((s: Store.AppState) => s.entities.users);
|
||||
|
||||
|
||||
return (
|
||||
<div className="channels px-2 w-60 bg-bg-secondary">
|
||||
<div className="mt-2">
|
||||
{channels.map(c => {
|
||||
const otherUserId = (c as ChannelTypes.DM).userIds
|
||||
.find(id => id !== selfUser.id);
|
||||
const otherUser = users.find(u => u.id === otherUserId);
|
||||
if (!otherUser) return null;
|
||||
|
||||
return (
|
||||
<Link
|
||||
key={c.id}
|
||||
to={`/channels/@me/${c.id}`}
|
||||
className="flex items-center rounded p-2 mb-2 hover:bg-bg-modifier-hover">
|
||||
<FoundUsername user={otherUser} size="sm" />
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default DMList;
|
58
frontend/src/components/pages/dm-page.tsx
Normal file
58
frontend/src/components/pages/dm-page.tsx
Normal file
@ -0,0 +1,58 @@
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import AppNavbar from '../navigation/app-navbar';
|
||||
import Sidebar from '../navigation/sidebar/sidebar';
|
||||
import { Redirect, useParams } from 'react-router-dom';
|
||||
import { actions as uiActions } from '../../store/ui';
|
||||
import TextBasedChannel from '../channel/text-based-channel';
|
||||
import { useEffect } from 'react';
|
||||
import PageWrapper from './page-wrapper';
|
||||
import { getDMChannel, createDM } from '../../store/channels';
|
||||
import WSListener from '../ws-listener';
|
||||
import DMList from '../navigation/sidebar/dm-list';
|
||||
|
||||
const DMPage: React.FunctionComponent = () => {
|
||||
const { channelId }: any = useParams();
|
||||
const dispatch = useDispatch();
|
||||
const channel = useSelector(getDMChannel(channelId));
|
||||
const users = useSelector((s: Store.AppState) => s.entities.users);
|
||||
const selfUser = useSelector((s: Store.AppState) => s.auth.user)!;
|
||||
const ui = useSelector((s: Store.AppState) => s.ui);
|
||||
|
||||
useEffect(() => {
|
||||
if (!channel && channelId) {
|
||||
const otherUser = users.find(u => u.id === channelId);
|
||||
if (otherUser) {
|
||||
dispatch(createDM(otherUser.id));
|
||||
}
|
||||
}
|
||||
dispatch(uiActions.pageSwitched({ channel }));
|
||||
}, [channel, channelId]);
|
||||
|
||||
if (!channel && !channelId)
|
||||
return <Redirect to="/channels/@me" />;
|
||||
|
||||
const otherUser = users.find(u =>
|
||||
channel?.type === 'DM' && channel.userIds.includes(u.id) && u.id !== selfUser.id);
|
||||
|
||||
return (
|
||||
<PageWrapper pageTitle={otherUser?.username ?? 'Direct Messages'}>
|
||||
<WSListener />
|
||||
<div className="flex">
|
||||
<Sidebar />
|
||||
<div className="bg-bg-primary flex-1">
|
||||
<AppNavbar />
|
||||
<div
|
||||
style={{ height: 'calc(100vh - 48px)' }}
|
||||
className="flex">
|
||||
{channel && ui.activeChannel && {
|
||||
'DM': <TextBasedChannel />,
|
||||
}[channel.type]}
|
||||
<DMList />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
export default DMPage;
|
@ -40,6 +40,7 @@ const GuildPage: React.FunctionComponent = () => {
|
||||
className="flex">
|
||||
{ui.activeChannel && {
|
||||
'TEXT': <TextBasedChannel />,
|
||||
'DM': <TextBasedChannel />,
|
||||
'VOICE': <div className="w-full p-2">Add something cool here for voice channels?</div>,
|
||||
}[channel.type]}
|
||||
<MemberList />
|
||||
|
@ -67,6 +67,11 @@ export const getChannel = (id: string) => createSelector(
|
||||
channels => channels.find(c => c.id === id),
|
||||
);
|
||||
|
||||
export const getDMChannel = (id: string) => createSelector(
|
||||
state => state.entities.channels,
|
||||
channels => channels.find(c => c.id === id && c.type === 'DM')
|
||||
);
|
||||
|
||||
export const getChannelByName = (guildId: string, name: string) => createSelector(
|
||||
state => state.entities.channels,
|
||||
channels => {
|
||||
@ -80,4 +85,29 @@ export const getChannelUsers = (channelId: string) => createSelector(
|
||||
const vc = channels.find(c => c.id === channelId) as ChannelTypes.Voice;
|
||||
return vc.userIds.map(id => users.find(u => u.id === id))
|
||||
},
|
||||
);
|
||||
);
|
||||
|
||||
export const getDMChannels = () => createSelector(
|
||||
state => state.entities.channels,
|
||||
channels => channels.filter(c => c.type === 'DM')
|
||||
);
|
||||
|
||||
export const createDM = (userId: string) => (dispatch, getState: () => Store.AppState) => {
|
||||
const selfUser = getState().auth.user!;
|
||||
const existingDM = getState().entities.channels
|
||||
.find(c => c.type === 'DM' &&
|
||||
c.userIds.includes(selfUser.id) &&
|
||||
c.userIds.includes(userId));
|
||||
|
||||
if (existingDM) return;
|
||||
|
||||
dispatch(api.wsCallBegan({
|
||||
event: 'CHANNEL_CREATE',
|
||||
data: {
|
||||
type: 'DM',
|
||||
userIds: [selfUser.id, userId],
|
||||
name: 'DM',
|
||||
guildId: '0'
|
||||
} as unknown as WS.Params.ChannelCreate,
|
||||
}));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user