update data modelling for realtime chat app (#630)

This commit is contained in:
Rishichandra Wawhal 2018-10-04 09:10:17 +05:30 committed by Shahidh K Muhammed
parent 30273d354d
commit ddfd7cd0fe
6 changed files with 45 additions and 192 deletions

View File

@ -3,7 +3,7 @@ import { Subscription } from 'react-apollo';
import gql from 'graphql-tag';
import ChatWrapper from './ChatWrapper';
const subscribeToEvent = gql`
const subscribeToNewMessages = gql`
subscription {
message ( order_by: id_desc limit: 1) {
id
@ -14,21 +14,18 @@ const subscribeToEvent = gql`
`;
const emitOnlineEvent = gql`
mutation ($userId: Int!){
insert_user_online(objects: [
{
user_id: $userId,
mutation ($userId:Int!){
update_user (
_set: {
last_seen: "now()"
}
],
on_conflict: {
constraint: user_online_pkey,
action: update
where: {
id: {
_eq: $userId
}
}
) {
returning {
user_id
}
affected_rows
}
}
`;
@ -63,7 +60,7 @@ class Chat extends React.Component {
}
});
},
1000
3000
);
}
@ -77,7 +74,7 @@ class Chat extends React.Component {
return (
<div>
<Subscription
subscription={subscribeToEvent}
subscription={subscribeToNewMessages}
>
{
({data, error, loading}) => {

View File

@ -1,7 +1,7 @@
import React from 'react';
import RenderMessages from './RenderMessages';
import Textbox from './Textbox'
import OnlineUsers from './OnlineUsersWrapper';
import OnlineUsers from './OnlineUsers';
import "../App.css";
export default class RenderMessagesProxy extends React.Component {

View File

@ -2,15 +2,14 @@ import React from 'react';
import { Subscription } from 'react-apollo';
import moment from 'moment';
import gql from 'graphql-tag';
import UserList from './OnlineUsersList';
const fetchOnlineUsersSubscription = gql`
subscription{
subscription {
user_online (
limit: 1,
order_by: last_seen_desc
){
last_seen
order_by: username_asc
) {
id
username
}
}
`;
@ -25,16 +24,9 @@ class OnlineUsers extends React.Component {
}
}
setRefetch = (refetch) => {
this.setState({
...this.state,
refetch
});
}
render() {
return (
<div>
<div className="onlineUsers">
<Subscription
subscription={fetchOnlineUsersSubscription}
>
@ -44,18 +36,21 @@ class OnlineUsers extends React.Component {
return null;
}
if (error) { return "Error loading online users"; }
if (this.state.refetch) {
this.state.refetch();
}
return null;
return (
<div>
<p className="userListHeading"> Online Users ({!data.user_online ? 0 : data.user_online.length})</p>
<ul className="userList">
{
data.user_online.map((u) => {
return <li key={u.id}>{u.username}</li>
})
}
</ul>
</div>
);
}
}
</Subscription>
<UserList
userId={this.props.userId}
refetch={this.state.refetch}
setRefetch={this.setRefetch}
/>
</div>
);
}

View File

@ -1,95 +0,0 @@
import React from 'react';
import { Query } from 'react-apollo';
import moment from 'moment';
import gql from 'graphql-tag';
const fetchOnlineUsersQuery = gql`
query ($timestamp: timestamptz!, $selfId: Int ) {
user (
where: {
online : {
last_seen: {
_gt: $timestamp
}
}
},
order_by: username_asc
){
id
username
}
}
`;
class UserList extends React.Component {
constructor(props) {
super(props);
this.state = {
time: moment().subtract(10, 'seconds').format(),
refetch: null
}
}
getQueryVariables() {
return {
timestamp: moment().subtract(10, 'seconds').format(),
selfId: this.props.userId
};
}
refetchOnlineUsers = async () => {
if (this.state.refetch) {
const resp = await this.state.refetch(this.getQueryVariables())
if (resp.data) {
this.setState({
...this.state,
users: [ ...resp.data.user]
});
}
}
}
render() {
const { users } = this.state;
if (this.state.refetch && !this.props.refetch) {
this.props.setRefetch(this.refetchOnlineUsers);
}
return (
<div className="onlineUsers">
<p className="userListHeading"> Online Users ({!users ? 0 : users.length})</p>
<Query
query={fetchOnlineUsersQuery}
variables={this.getQueryVariables()}
>
{
({data, error, loading, refetch}) => {
if (loading) {
return null;
}
if (error) { return "Error loading online users"; }
if (!this.state.refetch) {
this.setState({
...this.state,
refetch
});
}
return null;
}
}
</Query>
<div>
<ul className="userList">
{ users ?
users.map((u) => {
return <li key={u.id}>{u.username}</li>
}) :
null
}
</ul>
</div>
</div>
)
}
}
export default UserList

View File

@ -20,21 +20,18 @@ const insertMessage = gql`
`;
const emitTypingEvent = gql`
mutation ($userId: Int!){
insert_user_typing(objects: [
{
user_id: $userId,
mutation ($userId: Int) {
update_user (
_set: {
last_typed: "now()"
}
],
on_conflict: {
constraint: user_typing_pkey,
action: update
where: {
id: {
_eq: $userId
}
}
) {
returning {
user_id
}
affected_rows
}
}
`;

View File

@ -1,55 +1,33 @@
import React from 'react';
import { Subscription } from 'react-apollo';
import moment from 'moment';
import gql from 'graphql-tag';
import '../App.css';
const getUserTyping = gql`
subscription ($timestamp: timestamptz!, $selfId: Int ) {
subscription ($selfId: Int ) {
user_typing (
where: {
_and: {
last_typed: {
_gt: $timestamp
},
user_id: {
_neq: $selfId
}
id: {
_neq: $selfId
}
},
order_by: last_typed_desc,
limit: 1
order_by: last_typed_desc
){
user_id
last_typed
user {
username
}
username
}
}
`;
class TypingIndicator extends React.Component {
constructor(props) {
super(props)
this.state = {
time: moment().subtract(0.5, 'seconds').format(),
}
}
componentDidMount() {
setInterval(
() => this.setState({ time: moment().subtract(2, 'seconds').format()}),
5000
);
}
render() {
return (
<div className="typingIndicator">
<Subscription
subscription={getUserTyping}
variables={{
timestamp: this.state.time,
selfId: this.props.userId
}}
>
@ -57,10 +35,10 @@ class TypingIndicator extends React.Component {
({ data, loading, error}) => {
if (loading) { return ""; }
if (error) { return ""; }
if (data.user_typing.length === 0 || data.user_id === this.props.userId ) {
if (data.user_typing.length === 0) {
return "";
} else {
return `${data.user_typing[0].user.username} is typing ...`;
return `${data.user_typing[0].username} is typing ...`;
}
}
}
@ -68,26 +46,7 @@ class TypingIndicator extends React.Component {
</div>
)
}
};
export default TypingIndicator;