prva verzija
This commit is contained in:
45
src/App.js
Normal file
45
src/App.js
Normal file
@@ -0,0 +1,45 @@
|
||||
// ./src/App.js
|
||||
|
||||
import React, { Component } from 'react'
|
||||
import UsernameForm from './UsernameForm'
|
||||
import Chat from './Chat'
|
||||
|
||||
class App extends Component {
|
||||
state = {
|
||||
currentUsername: null,
|
||||
currentId: null,
|
||||
currentScreen: 'usernameForm'
|
||||
}
|
||||
|
||||
onUsernameSubmitted = username => {
|
||||
fetch('http://localhost:3001/users', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ username })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
this.setState({
|
||||
currentId: data.id,
|
||||
currentUsername: data.name,
|
||||
currentScreen: 'chat'
|
||||
})
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error', error)
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.currentScreen === 'usernameForm') {
|
||||
return <UsernameForm handleSubmit={this.onUsernameSubmitted} />
|
||||
}
|
||||
|
||||
if (this.state.currentScreen === 'chat') {
|
||||
return <Chat currentId={this.state.currentId} />
|
||||
}
|
||||
}
|
||||
}
|
||||
export default App;
|
||||
202
src/Chat.js
Normal file
202
src/Chat.js
Normal file
@@ -0,0 +1,202 @@
|
||||
// ./src/Chat.js
|
||||
|
||||
import React, { Component } from 'react'
|
||||
import { ChatManager, TokenProvider } from '@pusher/chatkit'
|
||||
import MessageList from './MessageList'
|
||||
import SendMessageForm from './SendMessageForm'
|
||||
import OnlineList from './OnlineList'
|
||||
//import libsignal from 'libsignal'
|
||||
import axios from "axios"
|
||||
|
||||
|
||||
class Chat extends Component {
|
||||
state = {
|
||||
currentUser: null,
|
||||
currentRoom: {},
|
||||
poruka: "",
|
||||
messages: [],
|
||||
receiverStore: null,
|
||||
receiverAdress: null,
|
||||
}
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
const chatkit = new ChatManager({
|
||||
instanceLocator: 'v1:us1:366480cc-91f1-4cbd-8c04-68dc96e8ccdf',
|
||||
userId: this.props.currentId,
|
||||
tokenProvider: new TokenProvider({
|
||||
url:
|
||||
'https://us1.pusherplatform.io/services/chatkit_token_provider/v1/366480cc-91f1-4cbd-8c04-68dc96e8ccdf/token'
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
chatkit
|
||||
.connect()
|
||||
.then(currentUser => {
|
||||
this.setState({ currentUser })
|
||||
console.log('Bleep bloop 🤖 You are connected to Chatkit')
|
||||
return currentUser.subscribeToRoom({
|
||||
roomId: 19377131, // Replace with YOUR ROOM ID
|
||||
messageLimit: 100,
|
||||
hooks: {
|
||||
onNewMessage: message => {
|
||||
//dekodiranje
|
||||
if (message != "") {
|
||||
console.log(message)
|
||||
this.onDeCryptingMessage(message)
|
||||
|
||||
}
|
||||
},
|
||||
OnUserCameOnline: () => this.forceUpdate(),
|
||||
onUserWentOffline: () => this.forceUpdate(),
|
||||
onUserJoined: () => this.forceUpdate()
|
||||
|
||||
}
|
||||
})
|
||||
})
|
||||
.then(currentRoom => {
|
||||
this.setState({ currentRoom })
|
||||
})
|
||||
.catch(error => console.error('error', error))
|
||||
}
|
||||
|
||||
|
||||
onDeCryptingMessage = message => {
|
||||
|
||||
console.log("DEKRIPCIJA");
|
||||
fetch('http://localhost:3001/decryptMessage2', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
data: {
|
||||
senderAdress: "xxxxxxxxx",
|
||||
receiverAdress: "yyyyyyyyyyyyy",
|
||||
receiverPreKeyId: 1337,
|
||||
receiverSignedKeyId: 1,
|
||||
message: message
|
||||
}
|
||||
})
|
||||
})
|
||||
.then(response => { console.log("REPSONSE:", response); return response.json(); })
|
||||
.then(data => {
|
||||
console.log("DATA:", data.data)
|
||||
this.setState({
|
||||
message: data.data.message
|
||||
})
|
||||
this.setState({
|
||||
messages: [...this.state.messages, message]
|
||||
})
|
||||
return data.data.message
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error', error)
|
||||
}).catch(error => {
|
||||
console.error('error', error)
|
||||
})
|
||||
}
|
||||
|
||||
onCryptingMessage = message => {
|
||||
fetch('http://localhost:3001/cryptMessage', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
data: {
|
||||
senderAdress: "xxxxxxxxx",
|
||||
receiverAdress: "yyyyyyyyyyyyy",
|
||||
receiverPreKeyId: 1337,
|
||||
receiverSignedKeyId: 1,
|
||||
message: message
|
||||
}
|
||||
})
|
||||
})
|
||||
.then(response => { console.log("REPSONSE:", response); return response.json(); })
|
||||
.then(data => {
|
||||
console.log("DATA:", data.data)
|
||||
this.setState({
|
||||
receiverStore: data.data.receiverStore,
|
||||
senderAdress: data.data.senderAdress,
|
||||
poruka: data.data.message
|
||||
})
|
||||
|
||||
this.onSend(data.data.message.data.toString())
|
||||
return data.data.message
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error', error)
|
||||
}).catch(error => {
|
||||
console.error('error', error)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
onSend = text => {
|
||||
//ubaceno
|
||||
fetch('http://localhost:3001/cryptMessage', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
data: {
|
||||
senderAdress: "xxxxxxxxx",
|
||||
receiverAdress: "yyyyyyyyyyyyy",
|
||||
receiverPreKeyId: 1337,
|
||||
receiverSignedKeyId: 1,
|
||||
message: text
|
||||
}
|
||||
})
|
||||
})
|
||||
.then(response => { console.log("REPSONSE:", response); return response.json(); })
|
||||
.then(data => {
|
||||
|
||||
this.state.poruka = data.data.message.data.toString();
|
||||
this.setState({
|
||||
receiverStore: data.data.receiverStore,
|
||||
senderAdress: data.data.senderAdress
|
||||
})
|
||||
|
||||
this.state.currentUser.sendMessage({
|
||||
text: this.state.poruka ,
|
||||
roomId: this.state.currentRoom.id
|
||||
})
|
||||
return data.data.message
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('error', error)
|
||||
}).catch(error => {
|
||||
console.error('error', error)
|
||||
})
|
||||
|
||||
|
||||
//kraj
|
||||
|
||||
/*this.state.currentUser.sendMessage({
|
||||
text,
|
||||
roomId: this.state.currentRoom.id
|
||||
})*/
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className="wrapper">
|
||||
<div>
|
||||
<OnlineList
|
||||
currentUser={this.state.currentUser}
|
||||
users={this.state.currentRoom.users}
|
||||
/>
|
||||
</div>
|
||||
<div className="chat">
|
||||
<MessageList messages={this.state.messages} />
|
||||
<SendMessageForm onSend={this.onSend} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Chat
|
||||
39
src/MessageList.js
Normal file
39
src/MessageList.js
Normal file
@@ -0,0 +1,39 @@
|
||||
// ./src/MessageList.js
|
||||
|
||||
import React, { Component } from 'react'
|
||||
import {
|
||||
ListView,
|
||||
ListViewSection,
|
||||
ListViewSectionHeader,
|
||||
ListViewRow,
|
||||
Text
|
||||
} from 'react-desktop/macOs'
|
||||
|
||||
class MessageList extends Component {
|
||||
render() {
|
||||
return (
|
||||
<ListView>
|
||||
<ListViewSection>
|
||||
{this.props.messages.map((message, index) =>
|
||||
this.renderItem(message)
|
||||
)}
|
||||
</ListViewSection>
|
||||
</ListView>
|
||||
)
|
||||
}
|
||||
|
||||
renderItem(message) {
|
||||
return (
|
||||
<ListViewRow key={message.id}>
|
||||
<Text color="#414141" size="13" bold>
|
||||
{message.sender.name}:
|
||||
</Text>
|
||||
<Text color="#414141" size="13">
|
||||
{message.text}
|
||||
</Text>
|
||||
</ListViewRow>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default MessageList
|
||||
51
src/OnlineList.js
Normal file
51
src/OnlineList.js
Normal file
@@ -0,0 +1,51 @@
|
||||
// ./src/OnlineList.js
|
||||
|
||||
import React, { Component } from 'react'
|
||||
import {
|
||||
ListView,
|
||||
ListViewSection,
|
||||
ListViewSectionHeader,
|
||||
ListViewRow,
|
||||
Text
|
||||
} from 'react-desktop/macOs'
|
||||
|
||||
class OnlineList extends Component {
|
||||
render() {
|
||||
return (
|
||||
<ListView className="online-list">
|
||||
<ListViewSection>
|
||||
{this.props.users &&
|
||||
this.props.users.map((user, index) => {
|
||||
if (user.id === this.props.currentUser.id) {
|
||||
return this.renderItem(
|
||||
`${user.name} (You)`,
|
||||
user.id,
|
||||
user.presence.state
|
||||
)
|
||||
}
|
||||
return this.renderItem(user.name, user.id, user.presence.state)
|
||||
})}
|
||||
</ListViewSection>
|
||||
</ListView>
|
||||
)
|
||||
}
|
||||
|
||||
renderItem(name, id, status) {
|
||||
const itemStyle = {}
|
||||
return (
|
||||
<ListViewRow key={id}>
|
||||
<div
|
||||
className="online-list-item"
|
||||
style={{
|
||||
background: status === 'online' ? '#6BD761' : 'gray'
|
||||
}}
|
||||
/>
|
||||
<Text color="#414141" size="13">
|
||||
{name}{' '}
|
||||
</Text>{' '}
|
||||
</ListViewRow>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default OnlineList
|
||||
43
src/SendMessageForm.js
Normal file
43
src/SendMessageForm.js
Normal file
@@ -0,0 +1,43 @@
|
||||
// ./src/SendMessageForm.js
|
||||
|
||||
import React, { Component } from 'react'
|
||||
import { Button, TextInput } from 'react-desktop/macOs'
|
||||
|
||||
class SendMessageForm extends Component {
|
||||
state = {
|
||||
text: ''
|
||||
}
|
||||
|
||||
onSubmit = e => {
|
||||
e.preventDefault()
|
||||
this.props.onSend(this.state.text)
|
||||
this.setState({ text: '' })
|
||||
}
|
||||
|
||||
onChange = e => {
|
||||
this.setState({ text: e.target.value })
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange()
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="send-message-form-container">
|
||||
<form onSubmit={this.onSubmit} className="send-message-form">
|
||||
<TextInput
|
||||
type="text"
|
||||
onChange={this.onChange}
|
||||
value={this.state.text}
|
||||
className="message-input"
|
||||
/>
|
||||
<Button color="blue" type="submit">
|
||||
Send
|
||||
</Button>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default SendMessageForm
|
||||
47
src/UsernameForm.js
Normal file
47
src/UsernameForm.js
Normal file
@@ -0,0 +1,47 @@
|
||||
// ./src/UsernameForm.js
|
||||
|
||||
import React, { Component } from 'react'
|
||||
import { TextInput } from 'react-desktop/macOs'
|
||||
import { Button } from 'react-desktop/macOs'
|
||||
|
||||
class UsernameForm extends Component {
|
||||
constructor() {
|
||||
super()
|
||||
this.state = {
|
||||
username: ''
|
||||
}
|
||||
}
|
||||
//19374147
|
||||
handleSubmit = e => {
|
||||
e.preventDefault()
|
||||
this.props.handleSubmit(this.state.username)
|
||||
}
|
||||
|
||||
handleChange = e => {
|
||||
this.setState({ username: e.target.value })
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="username-form">
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<div>
|
||||
<TextInput
|
||||
label="Username:"
|
||||
placeholder="For example, @bookercodes"
|
||||
value={this.state.username}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Button color="blue" type="submit">
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default UsernameForm
|
||||
24
src/electron-react.js
Normal file
24
src/electron-react.js
Normal file
@@ -0,0 +1,24 @@
|
||||
const net = require('net')
|
||||
const port = process.env.PORT ? process.env.PORT - 100 : 3002
|
||||
|
||||
process.env.ELECTRON_START_URL = `http://localhost:${port}`
|
||||
|
||||
const client = new net.Socket()
|
||||
|
||||
let startedElectron = false
|
||||
const tryConnection = () =>
|
||||
client.connect({ port: port }, () => {
|
||||
client.end()
|
||||
if (!startedElectron) {
|
||||
console.log('starting electron')
|
||||
startedElectron = true
|
||||
const exec = require('child_process').exec
|
||||
exec('npm run electron')
|
||||
}
|
||||
})
|
||||
|
||||
tryConnection()
|
||||
|
||||
client.on('error', error => {
|
||||
setTimeout(tryConnection, 1000)
|
||||
})
|
||||
39
src/electron-starter.js
Normal file
39
src/electron-starter.js
Normal file
@@ -0,0 +1,39 @@
|
||||
const electron = require('electron')
|
||||
const app = electron.app
|
||||
const BrowserWindow = electron.BrowserWindow
|
||||
|
||||
const path = require('path')
|
||||
const url = require('url')
|
||||
|
||||
let mainWindow
|
||||
|
||||
function createWindow() {
|
||||
mainWindow = new BrowserWindow({ width: 800, height: 600 })
|
||||
|
||||
const startUrl =
|
||||
process.env.ELECTRON_START_URL ||
|
||||
url.format({
|
||||
pathname: path.join(__dirname, '/../build/index.html'),
|
||||
protocol: 'file:',
|
||||
slashes: true
|
||||
})
|
||||
mainWindow.loadURL(startUrl)
|
||||
|
||||
mainWindow.on('closed', function() {
|
||||
mainWindow = null
|
||||
})
|
||||
}
|
||||
|
||||
app.on('ready', createWindow)
|
||||
|
||||
app.on('window-all-closed', function() {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
|
||||
app.on('activate', function() {
|
||||
if (mainWindow === null) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
56
src/index.css
Normal file
56
src/index.css
Normal file
@@ -0,0 +1,56 @@
|
||||
/* ./src/index.css */
|
||||
|
||||
body {
|
||||
font-family: BlinkMacSystemFont, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.username-form {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.username-form button {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
|
||||
}
|
||||
|
||||
.online-list {
|
||||
/* box-shadow: 0 -8px 20px 2px #DEDEE3; */
|
||||
background: #F9F9FB;
|
||||
}
|
||||
|
||||
.chat {
|
||||
/* background: #F4FAFE; */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
|
||||
.send-message-form{
|
||||
padding: 10px 15px 10px 15px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.send-message-form div {
|
||||
flex: 1;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
|
||||
.online-list-item {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
li span {
|
||||
padding-right: 5px;
|
||||
}
|
||||
6
src/index.js
Normal file
6
src/index.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
import './index.css'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('app'))
|
||||
Reference in New Issue
Block a user