-
diff --git a/src/components/MessageBar/index.ts b/src/components/MessageBar/index.ts
index 569e49b..f553fef 100644
--- a/src/components/MessageBar/index.ts
+++ b/src/components/MessageBar/index.ts
@@ -1 +1,2 @@
export * from "./MessageBar";
+export * from "./types";
diff --git a/src/components/MessageBar/types.ts b/src/components/MessageBar/types.ts
new file mode 100644
index 0000000..7d38270
--- /dev/null
+++ b/src/components/MessageBar/types.ts
@@ -0,0 +1,7 @@
+interface IMessageBarProps {
+ text: string;
+ onChangeText?: (text: string) => void;
+ onSend?: () => void;
+}
+
+export { type IMessageBarProps };
diff --git a/src/services/auth/auth.ts b/src/services/auth/auth.ts
index 78b1265..c0d13f0 100644
--- a/src/services/auth/auth.ts
+++ b/src/services/auth/auth.ts
@@ -12,6 +12,10 @@ const fetchLogin = async (username: string, password: string) => {
type: AuthActionTypes.FETCH_LOGIN_FINISH,
payload: data,
});
+
+ dispatch({
+ type: AuthActionTypes.FETCH_REFRESH_START,
+ });
};
const fetchRefresh = async () => {
@@ -21,6 +25,11 @@ const fetchRefresh = async () => {
type: AuthActionTypes.FETCH_REFRESH_FINISH,
payload: data,
});
+
+ dispatch({
+ type: AuthActionTypes.SET_LOGGED_IN,
+ payload: "id" in data,
+ });
};
export { fetchLogin, fetchRefresh };
diff --git a/src/services/channel/channel.ts b/src/services/channel/channel.ts
index 773427d..0ac72dd 100644
--- a/src/services/channel/channel.ts
+++ b/src/services/channel/channel.ts
@@ -3,6 +3,7 @@ import {
createChannelApi,
updateChannelApi,
removeChannelApi,
+ fetchChannelMessagesApi,
} from "../../api/channel";
import { ChannelActionTypes } from "../../store/channel";
import { dispatch } from "../../store/state";
@@ -58,4 +59,21 @@ const removeChannel = async (id: string) => {
});
};
-export { fetchChannel, createChannel, updateChannel, removeChannel };
+const fetchChannelMessages = async (id: string) => {
+ const data = await fetchChannelMessagesApi({
+ id: id,
+ });
+
+ dispatch({
+ type: ChannelActionTypes.FETCH_CHANNEL_MESSAGES_FINISH,
+ payload: data,
+ });
+};
+
+export {
+ fetchChannel,
+ createChannel,
+ updateChannel,
+ removeChannel,
+ fetchChannelMessages,
+};
diff --git a/src/services/message/index.ts b/src/services/message/index.ts
new file mode 100644
index 0000000..9b2c485
--- /dev/null
+++ b/src/services/message/index.ts
@@ -0,0 +1 @@
+export * from "./message";
diff --git a/src/services/message/message.ts b/src/services/message/message.ts
new file mode 100644
index 0000000..2f77422
--- /dev/null
+++ b/src/services/message/message.ts
@@ -0,0 +1,56 @@
+import {
+ fetchMessageApi,
+ createMessageApi,
+ updateMessageApi,
+ removeMessageApi,
+} from "../../api/message";
+import { MessageActionTypes } from "../../store/message";
+import { dispatch } from "../../store/state";
+
+const fetchMessage = async (id: string) => {
+ const data = await fetchMessageApi({
+ id: id,
+ });
+
+ dispatch({
+ type: MessageActionTypes.FETCH_MESSAGE_FINISH,
+ payload: data,
+ });
+};
+
+const createMessage = async (text: string, channelId: string) => {
+ const data = await createMessageApi({
+ text: text,
+ channelId: channelId,
+ });
+
+ dispatch({
+ type: MessageActionTypes.CREATE_MESSAGE_FINISH,
+ payload: data,
+ });
+};
+
+const updateMessage = async (id: string, text: string) => {
+ const data = await updateMessageApi({
+ id: id,
+ text: text,
+ });
+
+ dispatch({
+ type: MessageActionTypes.UPDATE_MESSAGE_FINISH,
+ payload: data,
+ });
+};
+
+const removeMessage = async (id: string) => {
+ const data = await removeMessageApi({
+ id: id,
+ });
+
+ dispatch({
+ type: MessageActionTypes.REMOVE_MESSAGE_FINISH,
+ payload: data,
+ });
+};
+
+export { fetchMessage, createMessage, updateMessage, removeMessage };
diff --git a/src/services/websocket/config.json b/src/services/websocket/config.json
new file mode 100644
index 0000000..0b390ff
--- /dev/null
+++ b/src/services/websocket/config.json
@@ -0,0 +1,6 @@
+{
+ "schema": "ws",
+ "url": "localhost",
+ "port": 3012,
+ "path": "ws"
+}
diff --git a/src/services/websocket/index.ts b/src/services/websocket/index.ts
new file mode 100644
index 0000000..771550d
--- /dev/null
+++ b/src/services/websocket/index.ts
@@ -0,0 +1,2 @@
+export * from "./websocket";
+export * from "./types";
diff --git a/src/services/websocket/types.ts b/src/services/websocket/types.ts
new file mode 100644
index 0000000..e79a5c1
--- /dev/null
+++ b/src/services/websocket/types.ts
@@ -0,0 +1,46 @@
+import { IFetchChannelMessage } from "../../api/channel";
+
+enum SocketRequestTypes {
+ PING = "PING",
+}
+
+enum SocketMessageTypes {
+ NEW_ANNOUNCEMENT = "NEW_ANNOUNCEMENT",
+ NEW_MESSAGE = "NEW_MESSAGE",
+ NEW_CHANNEL = "NEW_CHANNEL",
+}
+
+type SocketRequest = {
+ type: SocketRequestTypes.PING;
+};
+
+type SocketMessage =
+ | {
+ type: SocketMessageTypes.NEW_ANNOUNCEMENT;
+ payload: {
+ title: string;
+ description: string;
+ };
+ }
+ | {
+ type: SocketMessageTypes.NEW_MESSAGE;
+ payload: {
+ channelId: string;
+ message: IFetchChannelMessage;
+ };
+ }
+ | {
+ type: SocketMessageTypes.NEW_CHANNEL;
+ payload: {
+ id: string;
+ communityId: string;
+ name: string;
+ };
+ };
+
+export {
+ SocketRequestTypes,
+ SocketMessageTypes,
+ type SocketRequest,
+ type SocketMessage,
+};
diff --git a/src/services/websocket/websocket.ts b/src/services/websocket/websocket.ts
new file mode 100644
index 0000000..fca7251
--- /dev/null
+++ b/src/services/websocket/websocket.ts
@@ -0,0 +1,57 @@
+import { ChannelActionTypes } from "../../store/channel";
+import { dispatch } from "../../store/state";
+import config from "./config.json";
+import { SocketMessage, SocketMessageTypes } from "./types";
+
+let connection: WebSocket;
+
+const connectWs = () => {
+ connection = new WebSocket(
+ `${config.schema}://${config.url}:${config.port}/${config.path}`,
+ );
+
+ connection.onclose = onCloseWs;
+ connection.onmessage = onMessageWs;
+};
+
+const onCloseWs = () => {
+ setTimeout(connectWs, 10000);
+};
+
+const onMessageWs = (event: MessageEvent) => {
+ const message = parseMessage(event.data);
+
+ if (message) {
+ handleMessage(message);
+ }
+};
+
+const parseMessage = (data: string): SocketMessage | null => {
+ const request = JSON.parse(data) as SocketMessage;
+
+ if (!request.type) {
+ return null;
+ }
+
+ return request;
+};
+
+const handleMessage = (message: SocketMessage) => {
+ switch (message.type) {
+ case SocketMessageTypes.NEW_MESSAGE: {
+ dispatch({
+ type: ChannelActionTypes.SET_CHANNEL_MESSAGE,
+ payload: {
+ id: message.payload.channelId,
+ message: message.payload.message,
+ },
+ });
+ }
+ case SocketMessageTypes.NEW_CHANNEL: {
+ }
+ case SocketMessageTypes.NEW_ANNOUNCEMENT: {
+ }
+ }
+};
+
+export { connection, connectWs };
diff --git a/src/store/actions.ts b/src/store/actions.ts
index bd664d9..51769c9 100644
--- a/src/store/actions.ts
+++ b/src/store/actions.ts
@@ -6,6 +6,7 @@ import { ChannelActionTypes, ChannelAction } from "./channel";
import { RoleActionTypes, RoleAction } from "./role";
import { SessionActionTypes, SessionAction } from "./session";
import { InviteActionTypes, InviteAction } from "./invite";
+import { MessageActionTypes, MessageAction } from "./message";
type ActionTypes =
| AppActionTypes
@@ -15,7 +16,8 @@ type ActionTypes =
| ChannelActionTypes
| RoleActionTypes
| SessionActionTypes
- | InviteActionTypes;
+ | InviteActionTypes
+ | MessageActionTypes;
type Action =
| AppAction
@@ -25,6 +27,7 @@ type Action =
| ChannelAction
| RoleAction
| SessionAction
- | InviteAction;
+ | InviteAction
+ | MessageAction;
export { type Action, type ActionTypes };
diff --git a/src/store/app/actions.ts b/src/store/app/actions.ts
index 8c60c2d..9525b14 100644
--- a/src/store/app/actions.ts
+++ b/src/store/app/actions.ts
@@ -2,11 +2,16 @@ enum AppActionTypes {
SET_HOME_OPEN = "SET_HOME_OPEN",
SET_SETTINGS_OPEN = "SET_SETTINGS_OPEN",
SET_ADD_COMMUNITY_OPEN = "SET_ADD_COMMUNITY_OPEN",
+ SET_ADD_COMMUNITY_SETTINGS_OPEN = "SET_ADD_COMMUNITY_SETTINGS_OPEN",
}
type AppAction =
| { type: AppActionTypes.SET_HOME_OPEN; payload: boolean }
| { type: AppActionTypes.SET_SETTINGS_OPEN; payload: boolean }
- | { type: AppActionTypes.SET_ADD_COMMUNITY_OPEN; payload: boolean };
+ | { type: AppActionTypes.SET_ADD_COMMUNITY_OPEN; payload: boolean }
+ | {
+ type: AppActionTypes.SET_ADD_COMMUNITY_SETTINGS_OPEN;
+ payload: boolean;
+ };
export { AppActionTypes, type AppAction };
diff --git a/src/store/app/app.ts b/src/store/app/app.ts
index 9df5573..b9956ef 100644
--- a/src/store/app/app.ts
+++ b/src/store/app/app.ts
@@ -15,6 +15,15 @@ function appReducer(_state: IAppState, action: AppAction) {
setState("app", "dialogsOpen", "addCommunityOpen", false);
setState("app", "dialogsOpen", "addCommunityOpen", action.payload);
break;
+ case AppActionTypes.SET_ADD_COMMUNITY_SETTINGS_OPEN:
+ setState("app", "dialogsOpen", "communitySettingsOpen", false);
+ setState(
+ "app",
+ "dialogsOpen",
+ "communitySettingsOpen",
+ action.payload,
+ );
+ break;
}
}
diff --git a/src/store/app/types.ts b/src/store/app/types.ts
index 8091315..a2de7f3 100644
--- a/src/store/app/types.ts
+++ b/src/store/app/types.ts
@@ -6,6 +6,7 @@ interface IAppState {
interface IDialogsOpen {
settingsOpen: boolean;
addCommunityOpen: boolean;
+ communitySettingsOpen: boolean;
}
export { type IAppState, type IDialogsOpen };
diff --git a/src/store/auth/actions.ts b/src/store/auth/actions.ts
index c4db806..9e0e4d6 100644
--- a/src/store/auth/actions.ts
+++ b/src/store/auth/actions.ts
@@ -1,10 +1,12 @@
import {
IFetchLoginRequest,
IFetchLoginResponse,
- IFetchRefreshResponse,
+ IFetchRefreshResponseError,
+ IFetchRefreshResponseSuccess,
} from "../../api/auth";
enum AuthActionTypes {
+ SET_LOGGED_IN = "SET_LOGGED_IN",
FETCH_LOGIN_START = "FETCH_LOGIN_START",
FETCH_LOGIN_FINISH = "FETCH_LOGIN_FINISH",
FETCH_REFRESH_START = "FETCH_REFRESH_START",
@@ -12,6 +14,7 @@ enum AuthActionTypes {
}
type AuthAction =
+ | { type: AuthActionTypes.SET_LOGGED_IN; payload: boolean }
| { type: AuthActionTypes.FETCH_LOGIN_START; payload: IFetchLoginRequest }
| {
type: AuthActionTypes.FETCH_LOGIN_FINISH;
@@ -20,7 +23,7 @@ type AuthAction =
| { type: AuthActionTypes.FETCH_REFRESH_START }
| {
type: AuthActionTypes.FETCH_REFRESH_FINISH;
- payload: IFetchRefreshResponse;
+ payload: IFetchRefreshResponseError | IFetchRefreshResponseSuccess;
};
export { AuthActionTypes, type AuthAction };
diff --git a/src/store/auth/auth.ts b/src/store/auth/auth.ts
index 569b4ed..14685cf 100644
--- a/src/store/auth/auth.ts
+++ b/src/store/auth/auth.ts
@@ -5,6 +5,9 @@ import { IAuthState } from "./types";
function authReducer(_state: IAuthState, action: AuthAction) {
switch (action.type) {
+ case AuthActionTypes.SET_LOGGED_IN:
+ setState("auth", "loggedIn", action.payload);
+ break;
case AuthActionTypes.FETCH_LOGIN_START:
fetchLogin(action.payload.username, action.payload.password);
break;
@@ -15,7 +18,9 @@ function authReducer(_state: IAuthState, action: AuthAction) {
fetchRefresh();
break;
case AuthActionTypes.FETCH_REFRESH_FINISH:
- setState("auth", "session", action.payload);
+ if ("id" in action.payload) {
+ setState("auth", "session", action.payload);
+ }
break;
}
}
diff --git a/src/store/auth/types.ts b/src/store/auth/types.ts
index 21bd7a5..a57272f 100644
--- a/src/store/auth/types.ts
+++ b/src/store/auth/types.ts
@@ -1,4 +1,5 @@
interface IAuthState {
+ loggedIn?: boolean;
session?: ISession;
}
diff --git a/src/store/channel/actions.ts b/src/store/channel/actions.ts
index 6c29458..c6b97cb 100644
--- a/src/store/channel/actions.ts
+++ b/src/store/channel/actions.ts
@@ -5,12 +5,16 @@ import {
ICreateChannelResponse,
IUpdateChannelResponse,
IRemoveChannelResponse,
+ IFetchChannelMessagesResponse,
+ IFetchChannelMessage,
} from "../../api/channel";
import { IFetchCommunityChannel } from "../../api/community";
enum ChannelActionTypes {
SET_CHANNEL = "SET_CHANNEL",
SET_ACTIVE_CHANNEL = "SET_ACTIVE_CHANNEL",
+ SET_TEXT = "SET_TEXT",
+ SET_CHANNEL_MESSAGE = "SET_CHANNEL_MESSAGE",
FETCH_CHANNEL_START = "FETCH_CHANNEL_START",
FETCH_CHANNEL_FINISH = "FETCH_CHANNEL_FINISH",
CREATE_CHANNEL_START = "CREATE_CHANNEL_START",
@@ -19,6 +23,8 @@ enum ChannelActionTypes {
UPDATE_CHANNEL_FINISH = "UPDATE_CHANNEL_FINISH",
REMOVE_CHANNEL_START = "REMOVE_CHANNEL_START",
REMOVE_CHANNEL_FINISH = "REMOVE_CHANNEL_FINISH",
+ FETCH_CHANNEL_MESSAGES_START = "FETCH_CHANNEL_MESSAGES_START",
+ FETCH_CHANNEL_MESSAGES_FINISH = "FETCH_CHANNEL_MESSAGES_FINISH",
}
type ChannelAction =
@@ -30,6 +36,14 @@ type ChannelAction =
type: ChannelActionTypes.SET_ACTIVE_CHANNEL;
payload: string | undefined;
}
+ | {
+ type: ChannelActionTypes.SET_TEXT;
+ payload: { id: string; text: string };
+ }
+ | {
+ type: ChannelActionTypes.SET_CHANNEL_MESSAGE;
+ payload: { id: string; message: IFetchChannelMessage };
+ }
| { type: ChannelActionTypes.FETCH_CHANNEL_START; payload: string }
| {
type: ChannelActionTypes.FETCH_CHANNEL_FINISH;
@@ -55,6 +69,11 @@ type ChannelAction =
| {
type: ChannelActionTypes.REMOVE_CHANNEL_FINISH;
payload: IRemoveChannelResponse;
+ }
+ | { type: ChannelActionTypes.FETCH_CHANNEL_MESSAGES_START; payload: string }
+ | {
+ type: ChannelActionTypes.FETCH_CHANNEL_MESSAGES_FINISH;
+ payload: IFetchChannelMessagesResponse;
};
export { ChannelActionTypes, type ChannelAction };
diff --git a/src/store/channel/channel.ts b/src/store/channel/channel.ts
index 704f5ed..3205b6e 100644
--- a/src/store/channel/channel.ts
+++ b/src/store/channel/channel.ts
@@ -3,12 +3,13 @@ import {
createChannel,
updateChannel,
removeChannel,
+ fetchChannelMessages,
} from "../../services/channel";
import { setState } from "../state";
import { ChannelActionTypes, ChannelAction } from "./actions";
import { IChannelState } from "./types";
-function channelReducer(state: IChannelState, action: ChannelAction) {
+function channelReducer(_state: IChannelState, action: ChannelAction) {
switch (action.type) {
case ChannelActionTypes.SET_CHANNEL:
setState("channel", "channels", action.payload.id, action.payload);
@@ -16,6 +17,25 @@ function channelReducer(state: IChannelState, action: ChannelAction) {
case ChannelActionTypes.SET_ACTIVE_CHANNEL:
setState("channel", "active", action.payload);
break;
+ case ChannelActionTypes.SET_TEXT:
+ setState(
+ "channel",
+ "channels",
+ action.payload.id,
+ "text",
+ action.payload.text,
+ );
+ break;
+ case ChannelActionTypes.SET_CHANNEL_MESSAGE:
+ setState(
+ "channel",
+ "channels",
+ action.payload.id,
+ "messages",
+ action.payload.message.id,
+ action.payload.message,
+ );
+ break;
case ChannelActionTypes.FETCH_CHANNEL_START:
fetchChannel(action.payload);
break;
@@ -48,6 +68,25 @@ function channelReducer(state: IChannelState, action: ChannelAction) {
return copy;
});
break;
+ case ChannelActionTypes.FETCH_CHANNEL_MESSAGES_START:
+ fetchChannelMessages(action.payload);
+ break;
+ case ChannelActionTypes.FETCH_CHANNEL_MESSAGES_FINISH:
+ setState(
+ "channel",
+ "channels",
+ action.payload.id,
+ "messages",
+ (messages) => {
+ const newMessages = Object.fromEntries(
+ action.payload.messages.map((item) => [item.id, item]),
+ );
+
+ const copy = { ...messages, ...newMessages };
+ return copy;
+ },
+ );
+ break;
}
}
diff --git a/src/store/channel/types.ts b/src/store/channel/types.ts
index 1b23130..fc2ff58 100644
--- a/src/store/channel/types.ts
+++ b/src/store/channel/types.ts
@@ -1,3 +1,5 @@
+import { IMessage } from "../message";
+
interface IChannelState {
active?: string;
channels: Record
;
@@ -9,6 +11,8 @@ interface IChannel {
description?: string;
communityId?: string;
creationDate?: number;
+ text?: string;
+ messages?: Record;
}
export { type IChannelState, type IChannel };
diff --git a/src/store/community/community.ts b/src/store/community/community.ts
index 8a67c0f..fbcde23 100644
--- a/src/store/community/community.ts
+++ b/src/store/community/community.ts
@@ -12,7 +12,7 @@ import { setState } from "../state";
import { CommunityActionTypes, CommunityAction } from "./actions";
import { ICommunityState } from "./types";
-function communityReducer(state: ICommunityState, action: CommunityAction) {
+function communityReducer(_state: ICommunityState, action: CommunityAction) {
switch (action.type) {
case CommunityActionTypes.SET_COMMUNITY:
setState(
diff --git a/src/store/invite/invite.ts b/src/store/invite/invite.ts
index 1123afd..5fdf5be 100644
--- a/src/store/invite/invite.ts
+++ b/src/store/invite/invite.ts
@@ -3,7 +3,7 @@ import { setState } from "../state";
import { InviteActionTypes, InviteAction } from "./actions";
import { IInviteState } from "./types";
-function inviteReducer(state: IInviteState, action: InviteAction) {
+function inviteReducer(_state: IInviteState, action: InviteAction) {
switch (action.type) {
case InviteActionTypes.SET_INVITE:
setState("invite", "invites", action.payload.id, action.payload);
diff --git a/src/store/message/actions.ts b/src/store/message/actions.ts
new file mode 100644
index 0000000..23e152e
--- /dev/null
+++ b/src/store/message/actions.ts
@@ -0,0 +1,49 @@
+import {
+ ICreateMessageRequest,
+ IUpdateMessageRequest,
+ IFetchMessageResponse,
+ ICreateMessageResponse,
+ IUpdateMessageResponse,
+ IRemoveMessageResponse,
+} from "../../api/message";
+
+enum MessageActionTypes {
+ FETCH_MESSAGE_START = "FETCH_MESSAGE_START",
+ FETCH_MESSAGE_FINISH = "FETCH_MESSAGE_FINISH",
+ CREATE_MESSAGE_START = "CREATE_MESSAGE_START",
+ CREATE_MESSAGE_FINISH = "CREATE_MESSAGE_FINISH",
+ UPDATE_MESSAGE_START = "UPDATE_MESSAGE_START",
+ UPDATE_MESSAGE_FINISH = "UPDATE_MESSAGE_FINISH",
+ REMOVE_MESSAGE_START = "REMOVE_MESSAGE_START",
+ REMOVE_MESSAGE_FINISH = "REMOVE_MESSAGE_FINISH",
+}
+
+type MessageAction =
+ | { type: MessageActionTypes.FETCH_MESSAGE_START; payload: string }
+ | {
+ type: MessageActionTypes.FETCH_MESSAGE_FINISH;
+ payload: IFetchMessageResponse;
+ }
+ | {
+ type: MessageActionTypes.CREATE_MESSAGE_START;
+ payload: ICreateMessageRequest;
+ }
+ | {
+ type: MessageActionTypes.CREATE_MESSAGE_FINISH;
+ payload: ICreateMessageResponse;
+ }
+ | {
+ type: MessageActionTypes.UPDATE_MESSAGE_START;
+ payload: IUpdateMessageRequest;
+ }
+ | {
+ type: MessageActionTypes.UPDATE_MESSAGE_FINISH;
+ payload: IUpdateMessageResponse;
+ }
+ | { type: MessageActionTypes.REMOVE_MESSAGE_START; payload: string }
+ | {
+ type: MessageActionTypes.REMOVE_MESSAGE_FINISH;
+ payload: IRemoveMessageResponse;
+ };
+
+export { MessageActionTypes, type MessageAction };
diff --git a/src/store/message/index.ts b/src/store/message/index.ts
new file mode 100644
index 0000000..a6332db
--- /dev/null
+++ b/src/store/message/index.ts
@@ -0,0 +1,3 @@
+export * from "./message";
+export * from "./actions";
+export * from "./types";
diff --git a/src/store/message/message.ts b/src/store/message/message.ts
new file mode 100644
index 0000000..5166923
--- /dev/null
+++ b/src/store/message/message.ts
@@ -0,0 +1,59 @@
+import {
+ fetchMessage,
+ createMessage,
+ updateMessage,
+ removeMessage,
+} from "../../services/message";
+import { setState } from "../state";
+import { MessageActionTypes, MessageAction } from "./actions";
+import { IMessageState } from "./types";
+
+function messageReducer(_state: IMessageState, action: MessageAction) {
+ switch (action.type) {
+ case MessageActionTypes.FETCH_MESSAGE_START:
+ fetchMessage(action.payload);
+ break;
+ case MessageActionTypes.FETCH_MESSAGE_FINISH:
+ setState("message", "message", action.payload);
+ setState(
+ "channel",
+ "channels",
+ action.payload.channelId,
+ action.payload,
+ );
+ break;
+ case MessageActionTypes.CREATE_MESSAGE_START:
+ createMessage(action.payload.text, action.payload.channelId);
+ break;
+ case MessageActionTypes.CREATE_MESSAGE_FINISH:
+ setState("message", "message", action.payload);
+ setState(
+ "channel",
+ "channels",
+ action.payload.channelId,
+ "messages",
+ action.payload.id,
+ action.payload,
+ );
+ break;
+ case MessageActionTypes.UPDATE_MESSAGE_START:
+ updateMessage(action.payload.id, action.payload.text);
+ break;
+ case MessageActionTypes.UPDATE_MESSAGE_FINISH:
+ setState("message", "message", action.payload);
+ setState(
+ "channel",
+ "channels",
+ action.payload.channelId,
+ action.payload,
+ );
+ break;
+ case MessageActionTypes.REMOVE_MESSAGE_START:
+ removeMessage(action.payload);
+ break;
+ case MessageActionTypes.REMOVE_MESSAGE_FINISH:
+ break;
+ }
+}
+
+export { messageReducer };
diff --git a/src/store/message/types.ts b/src/store/message/types.ts
new file mode 100644
index 0000000..825a759
--- /dev/null
+++ b/src/store/message/types.ts
@@ -0,0 +1,15 @@
+interface IMessageState {
+ message?: IMessage;
+}
+
+interface IMessage {
+ id: string;
+ text: string;
+ editHistory?: string[];
+ edited: boolean;
+ ownerId: string;
+ channelId?: string;
+ creationDate: number;
+}
+
+export { type IMessageState, type IMessage };
diff --git a/src/store/reducers.ts b/src/store/reducers.ts
index ca6376c..3c3a8c8 100644
--- a/src/store/reducers.ts
+++ b/src/store/reducers.ts
@@ -8,6 +8,7 @@ import { ChannelAction, channelReducer } from "./channel";
import { RoleAction, roleReducer } from "./role";
import { SessionAction, sessionReducer } from "./session";
import { InviteAction, inviteReducer } from "./invite";
+import { MessageAction, messageReducer } from "./message";
function reducer(state: IState, action: Action) {
appReducer(state.app, action as AppAction);
@@ -18,6 +19,7 @@ function reducer(state: IState, action: Action) {
roleReducer(state.role, action as RoleAction);
sessionReducer(state.session, action as SessionAction);
inviteReducer(state.invite, action as InviteAction);
+ messageReducer(state.message, action as MessageAction);
}
export { reducer };
diff --git a/src/store/role/actions.ts b/src/store/role/actions.ts
index 6376028..f33d464 100644
--- a/src/store/role/actions.ts
+++ b/src/store/role/actions.ts
@@ -1,6 +1,7 @@
import { IFetchCommunityRole } from "../../api/community";
import {
ICreateRoleRequest,
+ IUpdateRoleRequest,
IFetchRoleResponse,
ICreateRoleResponse,
IUpdateRoleResponse,
@@ -34,7 +35,7 @@ type RoleAction =
type: RoleActionTypes.CREATE_ROLE_FINISH;
payload: ICreateRoleResponse;
}
- | { type: RoleActionTypes.UPDATE_ROLE_START; payload: string }
+ | { type: RoleActionTypes.UPDATE_ROLE_START; payload: IUpdateRoleRequest }
| {
type: RoleActionTypes.UPDATE_ROLE_FINISH;
payload: IUpdateRoleResponse;
diff --git a/src/store/role/role.ts b/src/store/role/role.ts
index 7428257..383eb2c 100644
--- a/src/store/role/role.ts
+++ b/src/store/role/role.ts
@@ -8,7 +8,7 @@ import { setState } from "../state";
import { RoleActionTypes, RoleAction } from "./actions";
import { IRoleState } from "./types";
-function roleReducer(state: IRoleState, action: RoleAction) {
+function roleReducer(_state: IRoleState, action: RoleAction) {
switch (action.type) {
case RoleActionTypes.SET_ROLE:
setState("role", "roles", action.payload.id, action.payload);
@@ -26,7 +26,7 @@ function roleReducer(state: IRoleState, action: RoleAction) {
setState("role", "roles", action.payload.id, action.payload);
break;
case RoleActionTypes.UPDATE_ROLE_START:
- updateRole(action.payload);
+ updateRole(action.payload.id, action.payload.name);
break;
case RoleActionTypes.UPDATE_ROLE_FINISH:
setState("role", "roles", action.payload.id, action.payload);
diff --git a/src/store/session/session.ts b/src/store/session/session.ts
index a3133d2..f99d218 100644
--- a/src/store/session/session.ts
+++ b/src/store/session/session.ts
@@ -3,7 +3,7 @@ import { setState } from "../state";
import { SessionActionTypes, SessionAction } from "./actions";
import { ISessionState } from "./types";
-function sessionReducer(state: ISessionState, action: SessionAction) {
+function sessionReducer(_state: ISessionState, action: SessionAction) {
switch (action.type) {
case SessionActionTypes.SET_SESSION:
setState("session", "sessions", action.payload.id, action.payload);
diff --git a/src/store/state.ts b/src/store/state.ts
index 4710d2f..536fa65 100644
--- a/src/store/state.ts
+++ b/src/store/state.ts
@@ -9,9 +9,11 @@ const [state, setState] = createStore({
dialogsOpen: {
settingsOpen: false,
addCommunityOpen: false,
+ communitySettingsOpen: false,
},
},
auth: {
+ loggedIn: undefined,
session: undefined,
},
user: {
@@ -33,6 +35,9 @@ const [state, setState] = createStore({
invite: {
invites: {},
},
+ message: {
+ message: undefined,
+ },
});
function dispatch(action: Action) {
diff --git a/src/store/types.ts b/src/store/types.ts
index e0e7ced..fe85706 100644
--- a/src/store/types.ts
+++ b/src/store/types.ts
@@ -6,6 +6,7 @@ import { IChannelState } from "./channel";
import { IRoleState } from "./role";
import { ISessionState } from "./session";
import { IInviteState } from "./invite";
+import { IMessageState } from "./message";
interface IState {
app: IAppState;
@@ -16,6 +17,7 @@ interface IState {
role: IRoleState;
session: ISessionState;
invite: IInviteState;
+ message: IMessageState;
}
export { type IState };
diff --git a/src/store/user/user.ts b/src/store/user/user.ts
index c8511b0..884e576 100644
--- a/src/store/user/user.ts
+++ b/src/store/user/user.ts
@@ -8,7 +8,7 @@ import { setState } from "../state";
import { UserActionTypes, UserAction } from "./actions";
import { IUserState } from "./types";
-function userReducer(state: IUserState, action: UserAction) {
+function userReducer(_state: IUserState, action: UserAction) {
switch (action.type) {
case UserActionTypes.SET_USER:
setState("user", "users", action.payload.id, action.payload);
diff --git a/src/views/MainView/MainView.tsx b/src/views/AppView/AppView.tsx
similarity index 80%
rename from src/views/MainView/MainView.tsx
rename to src/views/AppView/AppView.tsx
index 0b609d8..27a44b7 100644
--- a/src/views/MainView/MainView.tsx
+++ b/src/views/AppView/AppView.tsx
@@ -8,8 +8,12 @@ import { AuthActionTypes } from "../../store/auth";
import { HomeView } from "../HomeView";
import { CommunityView } from "../CommunityView";
import { ModalView } from "../ModalView";
+import { useNavigate } from "@solidjs/router";
+import { connectWs } from "../../services/websocket";
+
+const AppView: Component = () => {
+ const navigate = useNavigate();
-const MainView: Component = () => {
onMount(() => {
dispatch({
type: AuthActionTypes.FETCH_REFRESH_START,
@@ -31,6 +35,14 @@ const MainView: Component = () => {
}
});
+ createEffect(() => {
+ if (state.auth.loggedIn === false) {
+ navigate("/login");
+ } else {
+ connectWs();
+ }
+ });
+
return (
@@ -50,4 +62,4 @@ const MainView: Component = () => {
);
};
-export { MainView };
+export { AppView };
diff --git a/src/views/AppView/index.ts b/src/views/AppView/index.ts
new file mode 100644
index 0000000..93fb631
--- /dev/null
+++ b/src/views/AppView/index.ts
@@ -0,0 +1 @@
+export * from "./AppView";
diff --git a/src/views/ChannelView/ChannelView.tsx b/src/views/ChannelView/ChannelView.tsx
index edf21ab..694c034 100644
--- a/src/views/ChannelView/ChannelView.tsx
+++ b/src/views/ChannelView/ChannelView.tsx
@@ -4,6 +4,7 @@ import { CommunityActionTypes, ICommunity } from "../../store/community";
import { ChannelActionTypes } from "../../store/channel";
import { Channel } from "../../components/Channel";
import { CommunityBar } from "../../components/CommunityBar";
+import { AppActionTypes } from "../../store/app";
const ChannelView: Component = () => {
const channelIds = createMemo(() => {
@@ -34,6 +35,13 @@ const ChannelView: Component = () => {
}
});
+ const onCommunitySettingsClick = () => {
+ dispatch({
+ type: AppActionTypes.SET_ADD_COMMUNITY_SETTINGS_OPEN,
+ payload: true,
+ });
+ };
+
const onChannelClick = (id: string) => {
dispatch({
type: ChannelActionTypes.FETCH_CHANNEL_START,
@@ -70,6 +78,7 @@ const ChannelView: Component = () => {
avatar={
"https://img.daisyui.com/images/profile/demo/yellingcat@192.webp"
}
+ onSettingsClick={onCommunitySettingsClick}
/>