add socket.io back, cleanup

Change-Id: I74e043268c23fb45371f1e397ca2931ca177afc3
diff --git a/client/src/components/AccountPreferences.js b/client/src/components/AccountPreferences.js
index ee09094..e14101f 100644
--- a/client/src/components/AccountPreferences.js
+++ b/client/src/components/AccountPreferences.js
@@ -1,13 +1,15 @@
-import React from 'react'
+import React, { useState } from 'react'
 import { makeStyles } from '@material-ui/core/styles'
 import { List, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText, ListSubheader, Switch, Typography, Grid, Paper, CardContent, Card, TableContainer, Table, TableHead, TableRow, TableCell, TableBody, Toolbar, IconButton, ListItemAvatar, Input, TextField } from '@material-ui/core'
-import { PhoneCallbackRounded, GroupRounded, DeleteRounded, AccountCircle, AddCircle } from '@material-ui/icons'
+import { PhoneCallbackRounded, GroupRounded, DeleteRounded, AddCircle } from '@material-ui/icons'
 
 import Account from '../../../model/Account'
 import JamiIdCard from './JamiIdCard'
 import ConversationAvatar from './ConversationAvatar'
 import ConversationsOverviewCard from './ConversationsOverviewCard'
 
+import authManager from '../AuthManager'
+
 const useStyles = makeStyles(theme => ({
   root: {
     minWidth: 275,
@@ -35,6 +37,18 @@
   const isJamiAccount = account.getType() === Account.TYPE_JAMI
   const alias = isJamiAccount ? "Jami account" : "SIP account"
   const moderators = account.getDefaultModerators()
+  const [defaultModeratorUri, setDefaultModeratorUri] = useState('')
+
+  const addModerator = () => {
+    if (defaultModeratorUri) {
+      authManager.fetch(`/api/accounts/${account.getId()}/defaultModerators/${defaultModeratorUri}`, {method: "PUT"})
+      setDefaultModeratorUri('')
+    }
+  }
+
+  const removeModerator = (uri) =>
+    authManager.fetch(`/api/accounts/${account.getId()}/defaultModerators/${uri}`, {method: "DELETE"})
+
   return (
     <React.Fragment>
       <Typography variant="h2" component="h2" gutterBottom>{alias}</Typography>
@@ -98,22 +112,28 @@
           </Toolbar>
           <List>
             <ListItem key="add">
-              <TextField variant="outlined" className={classes.textField} label="Add new default moderator" placeholder="Enter new moderator name or URI" fullWidth />
+              <TextField variant="outlined"
+                className={classes.textField}
+                value={defaultModeratorUri}
+                onChange={e => setDefaultModeratorUri(e.target.value)}
+                label="Add new default moderator"
+                placeholder="Enter new moderator name or URI"
+                fullWidth />
               <ListItemSecondaryAction>
-                <IconButton><AddCircle /></IconButton>
+                <IconButton onClick={addModerator}><AddCircle /></IconButton>
               </ListItemSecondaryAction>
             </ListItem>
-            {moderators.length === 0 ?
+            {!moderators || moderators.length === 0 ?
               <ListItem key="placeholder">
                 <ListItemText primary="No default moderator" /></ListItem> :
               moderators.map((moderator) => (
-                <ListItem key={moderator.name}>
+                <ListItem key={moderator.uri}>
                   <ListItemAvatar>
-                    <ConversationAvatar name={moderator.name} />
+                    <ConversationAvatar name={moderator.getDisplayName()} />
                   </ListItemAvatar>
-                  <ListItemText primary={moderator.name} />
+                  <ListItemText primary={moderator.getDisplayName()} />
                   <ListItemSecondaryAction>
-                    <IconButton><DeleteRounded /></IconButton>
+                    <IconButton onClick={e => removeModerator(moderator.uri)}><DeleteRounded /></IconButton>
                   </ListItemSecondaryAction>
                 </ListItem>
               ))}
diff --git a/client/src/components/ConversationView.js b/client/src/components/ConversationView.js
index 719d3d0..6217905 100644
--- a/client/src/components/ConversationView.js
+++ b/client/src/components/ConversationView.js
@@ -8,7 +8,7 @@
 
 const ConversationView = props => {
   const [state, setState] = useState({
-    loaded:false,
+    loaded: false,
     error: false,
     conversation: undefined
   })
@@ -44,15 +44,26 @@
     })
   }
 
+  const loadMore = () => {
+    authManager.fetch(`/api/accounts/${props.accountId}/conversations/${props.conversationId}/messages`)
+      .then(res => res.json())
+      .then(messages => {
+        console.log(messages)
+        state.conversation.addLoadedMessages(messages)
+        setState(state)
+      })
+  }
+
+  console.log("ConversationView render " + (state.conversation ? state.conversation.getMessages().length : "no conversation"))
   if (state.loaded === false) {
       return <LoadingPage />
   } else if (state.error === true) {
       return <div>Error loding {props.conversationId}</div>
   } else {
-  return <React.Fragment>
-      <MessageList conversation={state.conversation} messages={state.conversation.getMessages()} />
+  return <div className="messenger">
+      <MessageList conversation={state.conversation} loadMore={loadMore} messages={state.conversation.getMessages()} />
       <SendMessageForm onSend={sendMessage} />
-    </React.Fragment>
+    </div>
   }
 }
 
diff --git a/client/src/components/Message.js b/client/src/components/Message.js
index f0aaba8..9054cd7 100644
--- a/client/src/components/Message.js
+++ b/client/src/components/Message.js
@@ -2,10 +2,13 @@
 import React from 'react'
 
 function Message(props) {
+    console.log("Message render")
+    console.log(props.message)
+
     return (
         <div className="message">
-            <div className="message-username">{props.username}</div>
-            <Typography className="message-text">{props.text}</Typography>
+            <div className="message-username">{props.message.author}</div>
+            <Typography className="message-text">{props.message.body}</Typography>
         </div>
     )
 }
diff --git a/client/src/components/MessageList.js b/client/src/components/MessageList.js
index 94947ca..b2fca5e 100644
--- a/client/src/components/MessageList.js
+++ b/client/src/components/MessageList.js
@@ -1,13 +1,21 @@
 import Message from './Message'
-import React from 'react'
+import React, { useEffect } from 'react'
 import { Box, Divider, Typography } from '@material-ui/core'
 import ConversationAvatar from './ConversationAvatar'
+const reverseMap = (arr, f) => arr.map((_, idx, arr) => f(arr[arr.length - 1 - idx ]));
 
 export default function MessageList(props) {
   const displayName = props.conversation.getDisplayName()
+  const messages = props.conversation.getMessages()
+  console.log("MessageList render " + messages.length)
+
+  useEffect(() => {
+    props.loadMore()
+  }, [props.conversation.getId()])
+
   return (
-    <div className="message-list">
-      <Box>
+    <React.Fragment>
+      <Box className="conversation-header">
         <Box style={{ display: 'inline-block', margin: 16, verticalAlign: 'middle' }}>
           <ConversationAvatar displayName={props.conversation.getDisplayNameNoFallback()} />
         </Box>
@@ -15,11 +23,13 @@
           <Typography variant="h6">{displayName}</Typography>
           <Typography variant="subtitle1">{props.conversation.getId()}</Typography>
         </Box>
+        <Divider orientation="horizontal" />
       </Box>
-      <Divider orientation="horizontal" />
-      {props.messages.map((message, index) =>
-        <Message key={index} username={message.senderId} text={message.body} />
-      )}
-    </div>
+      <div className="message-list">
+      <div className="message-list-inner">
+      {reverseMap(messages, (message) => <Message key={message.id} message={message} />)}
+      </div>
+      </div>
+    </React.Fragment>
   )
 }
\ No newline at end of file
diff --git a/client/src/components/SendMessageForm.js b/client/src/components/SendMessageForm.js
index fb06d49..82ee7af 100644
--- a/client/src/components/SendMessageForm.js
+++ b/client/src/components/SendMessageForm.js
@@ -7,7 +7,8 @@
 
 const useStyles = makeStyles((theme) => ({
   root: {
-    margin: 16,
+    marginLeft: 16,
+    marginRight: 16,
     padding: '2px 4px',
     display: 'flex',
     alignItems: 'center',