Skip to content
This repository was archived by the owner on Nov 13, 2024. It is now read-only.

Commit 73bdbd9

Browse files
author
Jeff Moore
committed
Releasing v0.6.0
1 parent 0bbb408 commit 73bdbd9

File tree

88 files changed

+6672
-4671
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+6672
-4671
lines changed

package-lock.json

Lines changed: 5387 additions & 3926 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,31 @@
11
{
22
"name": "team-chat",
3-
"version": "0.5.4",
3+
"version": "0.6.0",
44
"description": "Team Chat - A Reference Application for PubNub with Typescript, React and Redux",
55
"license": "MIT",
66
"private": true,
77
"dependencies": {
88
"@types/emoji-mart": "^2.11.0",
9-
"@types/pubnub": "^4.0.7",
10-
"@types/react": "^16.9.4",
9+
"@types/invariant": "^2.2.31",
10+
"@types/pubnub": "^4.27.2",
11+
"@types/react": "^16.9.23",
1112
"@types/react-dom": "^16.9.1",
1213
"@types/react-redux": "^7.1.2",
13-
"@types/styled-components": "^4.1.19",
14+
"@types/styled-components": "^5.0.1",
1415
"emoji-mart": "^2.11.1",
16+
"framer-motion": "^1.8.4",
17+
"invariant": "^2.2.4",
1518
"polished": "^3.4.1",
16-
"pubnub": "^4.27.0",
17-
"pubnub-react": "^2.0.0-beta.4",
18-
"pubnub-redux": "^0.0.2-beta",
19-
"react": "^16.9.0",
20-
"react-dom": "^16.9.0",
21-
"react-pose": "^4.0.8",
22-
"react-redux": "^7.1.0",
19+
"pubnub": "^4.27.3",
20+
"pubnub-react": "^2.0.0",
21+
"pubnub-redux": "^0.0.5-beta",
22+
"react": "^16.13.0",
23+
"react-dom": "^16.13.0",
24+
"react-redux": "^7.2.0",
2325
"redux": "^4.0.4",
2426
"redux-thunk": "^2.3.0",
2527
"reselect": "^4.0.0",
26-
"styled-components": "^4.4.0"
28+
"styled-components": "^5.0.1"
2729
},
2830
"scripts": {
2931
"start": "node setup/populate.js --quick-test && react-scripts start",
@@ -53,8 +55,7 @@
5355
},
5456
"lint-staged": {
5557
"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
56-
"prettier --write",
57-
"git add"
58+
"prettier --write"
5859
]
5960
},
6061
"babelMacros": {
@@ -64,19 +65,19 @@
6465
"node": ">=8.0.0"
6566
},
6667
"devDependencies": {
67-
"@testing-library/jest-dom": "^4.0.0",
68-
"@testing-library/react": "^9.1.4",
69-
"@types/jest": "24.0.18",
70-
"@types/node": "^12.7.5",
68+
"@testing-library/jest-dom": "^5.1.1",
69+
"@testing-library/react": "^9.4.1",
70+
"@types/jest": "25.1.3",
71+
"@types/node": "^13.7.7",
7172
"cli-progress": "^3.3.1",
72-
"eslint-plugin-react-hooks": "^2.1.1",
73+
"eslint-plugin-react-hooks": "^2.5.0",
7374
"file-system": "^2.2.2",
74-
"husky": "^3.0.8",
75-
"lint-staged": "^9.4.1",
75+
"husky": "^4.2.3",
76+
"lint-staged": "^10.0.8",
7677
"prettier": "^1.18.2",
77-
"react-scripts": "3.2.0",
78+
"react-scripts": "3.4.0",
7879
"readline": "^1.3.0",
7980
"requirejs": "^2.3.6",
80-
"typescript": "3.6.3"
81+
"typescript": "3.8.3"
8182
}
8283
}

public/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<meta name="theme-color" content="#000000" />
88
<meta
99
name="description"
10-
content="Web site created using create-react-app"
10+
content="This is an example of creating a chat application using PubNub"
1111
/>
1212
<link rel="apple-touch-icon" href="logo192.png" />
1313
<!--
@@ -29,7 +29,7 @@
2929
work correctly both with client-side routing and a non-root public URL.
3030
Learn how to configure a non-root public URL by running `npm run build`.
3131
-->
32-
<title>React App</title>
32+
<title>Team Chat Powered by PubNub</title>
3333
</head>
3434
<body>
3535
<noscript>You need to enable JavaScript to run this app.</noscript>

setup/populate.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const PubNub = require('pubnub');
2-
const data = require('./input_data.json');
2+
const data = require('./team-chat-initialization-data.json');
33
const _cliProgress = require('cli-progress');
44
const readline = require("readline");
55
const fs = require('file-system');
File renamed without changes.

src/config/defaultConversation.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"conversationId": "space_ac4e67b98b34b44c4a39466e93e"
3+
}

src/features/authentication/Login/Login.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { login } from "../loginCommand";
1212
import { isLoggingIn } from "../authenticationModel";
1313
import { isUserLoggedIn } from "features/authentication/authenticationModel";
1414
import { useSelector } from "react-redux";
15-
import KnownIds from "./knownUserIds.json";
15+
import KnownIds from "config/knownUserIds.json";
1616

1717
const Login = () => {
1818
const dispatch = useDispatch();

src/features/authentication/authenticationModel.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import { AppState } from "main/storeTypes";
21
import { createSelector } from "reselect";
2+
import invariant from "invariant";
3+
import { AppState } from "main/storeTypes";
34
import { AppActions } from "main/AppActions";
5+
46
export const LOGGING_IN = "LOGGIN_IN";
57
export const LOGIN_SUCCEEDED = "LOGIN_SUCCEEDED";
68

@@ -62,9 +64,10 @@ const getAuthenticationStateSlice = (state: AppState) => state.authentication;
6264
export const getLoggedInUserId = createSelector(
6365
[getAuthenticationStateSlice],
6466
(authenticationState: AuthenticationState): string => {
65-
if (authenticationState.loggedInUserId === undefined) {
66-
throw new Error("Requires loggedInUserId");
67-
}
67+
invariant(
68+
authenticationState.loggedInUserId !== undefined,
69+
"getLoggedInUserId should not be used in components of the application that are rendered while there is no logged in user"
70+
);
6871
return authenticationState.loggedInUserId;
6972
}
7073
);

src/features/chat/Chat/Chat.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import { Wrapper } from "./ChatUI.style";
33
import { Menu } from "features/chat/Menu/Menu";
44
import { CurrentConversation } from "features/currentConversation/CurrentConversation/CurrentConversation";
55
import { ConversationMembers } from "features/conversationMembers/ConversationMembers/ConversationMembers";
6-
import { JoinConversationModal } from "features/joinedConversations/JoinConversationModal/JoinConversationModal";
6+
import { JoinConversationDialog } from "features/joinedConversations/JoinConversationDialog/JoinConversationDialog";
77

88
const ChatUI = () => {
99
return (
1010
<Wrapper>
1111
<Menu />
1212
<CurrentConversation />
1313
<ConversationMembers />
14-
<JoinConversationModal />
14+
<JoinConversationDialog />
1515
</Wrapper>
1616
);
1717
};

src/features/chat/Menu/Menu.style.tsx

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,33 @@
11
import styled from "styled-components/macro";
2-
import posed from "react-pose";
2+
import { motion } from "framer-motion";
33

4-
export const Wrapper = styled.section<{ pose: string }>`
5-
display: ${props => (props.pose === "closed" ? "none" : "flex")};
4+
export const Wrapper = styled(motion.section)`
65
flex-direction: column;
7-
background-color: #ffffff;
86
max-width: 290px;
97
width: 100%;
10-
@media (max-width: 480px) {
8+
@media ${props => props.theme.breakpoint.mediaQuery.small} {
119
max-width: none;
10+
position: absolute;
11+
z-index: 100;
12+
background-color: #ffffff;
1213
}
1314
`;
1415

15-
export const AnimatedWrapper = posed(Wrapper)({
16-
open: { width: "100%", applyAtStart: { display: "flex" } },
17-
closed: { width: "24px", applyAtEnd: { display: "none" } }
18-
});
19-
2016
export const Img = styled.img`
2117
max-width: 100%;
2218
align-self: flex-end;
2319
margin-top: auto;
2420
`;
21+
22+
export const getAnimatedWrapperVariants = (isSmall: boolean) => ({
23+
open: {
24+
width: "100%",
25+
display: "flex"
26+
},
27+
closed: {
28+
width: isSmall ? "100%" : "24px",
29+
transitionEnd: {
30+
display: "none"
31+
}
32+
}
33+
});

src/features/chat/Menu/Menu.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
1-
import React, { useRef } from "react";
1+
import React, { useRef, useContext } from "react";
22
import { useSelector } from "react-redux";
3-
import { Breakpoint } from "features/layout/layoutModel";
4-
import { getPanelStates, getBreakpoint } from "features/layout/selectors";
3+
import { getViewStates } from "features/layout/Selectors";
54
import { MyUserDetails } from "features/currentUser/MyUserDetails/MyUserDetails";
65
import { MyConversations } from "features/joinedConversations/MyConversations/MyConversations";
7-
import { Wrapper, AnimatedWrapper } from "./Menu.style";
6+
import { Wrapper, getAnimatedWrapperVariants } from "./Menu.style";
7+
import { ThemeContext } from "styled-components";
8+
import { useMediaQuery } from "foundations/hooks/useMediaQuery";
89

910
const Menu = () => {
10-
const panel = useRef<HTMLElement>(null);
11-
const panels = useSelector(getPanelStates);
12-
const breakpoint = useSelector(getBreakpoint);
13-
const Panel = breakpoint === Breakpoint.Small ? Wrapper : AnimatedWrapper;
11+
const view = useRef<HTMLElement>(null);
12+
const views = useSelector(getViewStates);
13+
const themeContext = useContext(ThemeContext);
14+
const isSmall = useMediaQuery(themeContext.breakpoint.mediaQuery.small);
1415

1516
return (
16-
<Panel ref={panel} pose={panels.Left ? "open" : "closed"}>
17+
<Wrapper
18+
ref={view}
19+
animate={views.Menu ? "open" : "closed"}
20+
variants={getAnimatedWrapperVariants(isSmall)}
21+
>
1722
<MyUserDetails />
1823
<MyConversations />
19-
</Panel>
24+
</Wrapper>
2025
);
2126
};
2227

src/features/conversationMembers/ConversationMembers/ConversationMembers.style.tsx

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
import styled from "styled-components/macro";
2-
import posed from "react-pose";
2+
import { motion } from "framer-motion";
33

4-
export const Wrapper = styled.section<{ pose: string }>`
4+
export const Wrapper = styled(motion.section)`
55
height: 100%;
6-
display: ${props => (props.pose === "closed" ? "none" : "flex")};
6+
display: none;
77
flex-direction: column;
88
max-width: 290px;
99
width: 100%;
10-
@media (max-width: 480px) {
10+
@media ${props => props.theme.breakpoint.mediaQuery.small} {
1111
margin-left: 0;
1212
max-width: none;
13+
position: fixed;
14+
z-index: 300;
15+
background-color: #ffffff;
1316
}
1417
`;
1518

16-
export const AnimatedWrapper = posed(Wrapper)({
17-
open: { width: "100%", applyAtStart: { display: "flex" } },
18-
closed: { width: "24px", applyAtEnd: { display: "none" } }
19-
});
20-
2119
export const Title = styled.div`
2220
display: flex;
2321
`;
@@ -38,7 +36,7 @@ export const Header = styled.div`
3836

3937
export const CloseIcon = styled.span`
4038
cursor: pointer;
41-
@media (max-width: 480px) {
39+
@media ${props => props.theme.breakpoint.mediaQuery.small} {
4240
display: none;
4341
}
4442
`;
@@ -50,8 +48,21 @@ export const ScrollableView = styled.span`
5048
export const BackIconWrapper = styled.div`
5149
cursor: pointer;
5250
display: none;
53-
@media (max-width: 480px) {
51+
@media ${props => props.theme.breakpoint.mediaQuery.small} {
5452
display: flex;
5553
margin-right: 25px;
5654
}
5755
`;
56+
57+
export const getAnimatedWrapperVariants = (isSmall: boolean) => ({
58+
open: {
59+
width: "100%",
60+
display: "flex"
61+
},
62+
closed: {
63+
width: isSmall ? "100%" : "24px",
64+
transitionEnd: {
65+
display: "none"
66+
}
67+
}
68+
});

src/features/conversationMembers/ConversationMembers/ConversationMembers.tsx

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import React, { useEffect } from "react";
1+
import React, { useEffect, useContext } from "react";
22
import { useSelector, useDispatch } from "react-redux";
33
import { createSelector } from "reselect";
4-
import { getPanelStates, getBreakpoint } from "features/layout/selectors";
5-
import { Breakpoint } from "features/layout/layoutModel";
4+
import { getViewStates } from "features/layout/Selectors";
65
import { UsersIndexedById, getUsersById } from "features/users/userModel";
76
import {
87
getUsersByConversationId,
@@ -14,12 +13,11 @@ import {
1413
} from "features/memberPresence/memberPresenceModel";
1514
import { MemberDescription, UserFragment } from "../MemberDescription";
1615
import { getCurrentConversationId } from "features/currentConversation/currentConversationModel";
17-
import { setLayoutDefault } from "features/layout/actions";
18-
import { Cross as CrossIcon } from "foundations/components/icons/Cross";
19-
import { Back as BackIcon } from "foundations/components/icons/Back";
16+
import { CrossIcon } from "foundations/components/icons/CrossIcon";
17+
import { BackIcon } from "foundations/components/icons/BackIcon";
2018
import {
2119
Wrapper,
22-
AnimatedWrapper,
20+
getAnimatedWrapperVariants,
2321
CloseIcon,
2422
ScrollableView,
2523
Header,
@@ -28,6 +26,9 @@ import {
2826
} from "./ConversationMembers.style";
2927
import { fetchMembers, fetchHereNow } from "pubnub-redux";
3028
import { usePubNub } from "pubnub-react";
29+
import { conversationMembersViewHidden } from "features/layout/LayoutActions";
30+
import { ThemeContext } from "styled-components";
31+
import { useMediaQuery } from "foundations/hooks/useMediaQuery";
3132

3233
export const getCurrentConversationMembers = createSelector(
3334
[
@@ -68,9 +69,9 @@ const ConversationMembers = () => {
6869
const currentConversationId = useSelector(getCurrentConversationId);
6970
const dispatch = useDispatch();
7071
const pubnub = usePubNub();
71-
const panels = useSelector(getPanelStates);
72-
const breakpoint = useSelector(getBreakpoint);
73-
const Panel = breakpoint === Breakpoint.Small ? Wrapper : AnimatedWrapper;
72+
const views = useSelector(getViewStates);
73+
const themeContext = useContext(ThemeContext);
74+
const isSmall = useMediaQuery(themeContext.breakpoint.mediaQuery.small);
7475

7576
useEffect(() => {
7677
if (members.length === 0) {
@@ -94,32 +95,35 @@ const ConversationMembers = () => {
9495
}, [members, currentConversationId, pubnub, dispatch]);
9596

9697
return (
97-
<Panel pose={panels.Right ? "open" : "closed"}>
98+
<Wrapper
99+
animate={views.ConversationMembers ? "open" : "closed"}
100+
variants={getAnimatedWrapperVariants(isSmall)}
101+
>
98102
<Header>
99103
<Title>
100104
<BackIconWrapper
101105
onClick={() => {
102-
dispatch(setLayoutDefault());
106+
dispatch(conversationMembersViewHidden());
103107
}}
104108
>
105-
<BackIcon />
109+
<BackIcon title="back" />
106110
</BackIconWrapper>
107111
Members
108112
</Title>
109113
<CloseIcon
110114
onClick={() => {
111-
dispatch(setLayoutDefault());
115+
dispatch(conversationMembersViewHidden());
112116
}}
113117
>
114-
<CrossIcon />
118+
<CrossIcon title="close members list" />
115119
</CloseIcon>
116120
</Header>
117121
<ScrollableView>
118122
{orderByPresence(members).map(user => (
119123
<MemberDescription user={user} key={user.id} />
120124
))}
121125
</ScrollableView>
122-
</Panel>
126+
</Wrapper>
123127
);
124128
};
125129

0 commit comments

Comments
 (0)