diff --git a/src/assets/images/chat.png b/src/assets/images/chat.png index f2711a5..5a09360 100644 Binary files a/src/assets/images/chat.png and b/src/assets/images/chat.png differ diff --git a/src/assets/images/chat3.png b/src/assets/images/chat3.png new file mode 100644 index 0000000..f2711a5 Binary files /dev/null and b/src/assets/images/chat3.png differ diff --git a/src/index.scss b/src/index.scss index 82fe352..52b5b2a 100644 --- a/src/index.scss +++ b/src/index.scss @@ -31,6 +31,15 @@ code { font-family: IRANSansNumeralBold; src: url(assets/IRANSans/Farsi_numerals/Bold.ttf); } +.fontLight { + font-family: 'IRANSansNumeralLight' !important; +} +.rtl { + direction: rtl !important; +} +.ltr { + direction: ltr !important; +} .MuiInputBase-input { font-family: IRANSansNumeralLight !important; } diff --git a/src/views/Auth/Auth.js b/src/views/Auth/Auth.js index 1adb3b0..096686e 100644 --- a/src/views/Auth/Auth.js +++ b/src/views/Auth/Auth.js @@ -1,8 +1,9 @@ import React, { Component } from 'react'; -import {ToastContainer} from 'react-toastify'; +import { ToastContainer } from 'react-toastify'; import Logo from './Logo/Logo'; import Bio from './Bio/Bio'; import Login from './Login/Login'; +import Snackbar from '@material-ui/core/Snackbar'; import './Auth.scss'; export default class Auth extends Component { @@ -13,17 +14,34 @@ export default class Auth extends Component { page: 'logo', }; } + state = { toastView: false }; setPage = (val) => { this.setState({ page: val, }); }; + toastClose = () => { + this.setState({ toastView: false }); + }; + toast = (toastText) => { + this.setState({ toastView: true, toastText }); + }; + componentDidMount() { + window.toast = this.tosat; + } render() { + const { toastView, toastText } = this.state; return (
{this.state.page === 'logo' ? : null} {this.state.page === 'bio' ? : null} {this.state.page === 'login' ? : null} + @@ -80,7 +81,7 @@ export default class ChatInputs extends Component {
) : null} {message !== '' || file !== null ? ( -
sendMessage()}> +
addcounter()}> - {suggest.map((row, i) => ( - + {options.map((row, i) => ( + ))}
); } -const Row = ({ row }) => { +const Row = ({ row, action }) => { return (
- {/* */} {row.map((item, i) => ( - + ))}
); }; -const Suggest = ({ item }) => { - console.log(item.text); - return
{item.text}
; +const KeyboardItem = ({ item, action }) => { + return ( +
action(item)}> + {item.text} +
+ ); }; diff --git a/src/views/ChatRoom/Body/Message/Inline/index.js b/src/views/ChatRoom/Body/Message/Inline/index.js index a7b283f..bd27cf7 100644 --- a/src/views/ChatRoom/Body/Message/Inline/index.js +++ b/src/views/ChatRoom/Body/Message/Inline/index.js @@ -10,10 +10,11 @@ export default class Message2D extends Component { if (this.props.isActive) { this.setState({ value: id }); toast.success('ثبت شد'); + this.props.action(); } } render() { - const { message, user, isSelf, isActive } = this.props; + const { message, user, isSelf, isActive, action } = this.props; return (
diff --git a/src/views/ChatRoom/Body/Message/Normal/index.js b/src/views/ChatRoom/Body/Message/Normal/index.js index c8a7ac5..4fcf848 100644 --- a/src/views/ChatRoom/Body/Message/Normal/index.js +++ b/src/views/ChatRoom/Body/Message/Normal/index.js @@ -16,6 +16,19 @@ import ForwardIcon from '@material-ui/icons/Forward'; import DeleteIcon from '@material-ui/icons/Delete'; import FavoriteIcon from '@material-ui/icons/Favorite'; import TextsmsIcon from '@material-ui/icons/Textsms'; +import ScheduleIcon from '@material-ui/icons/Schedule'; +const file = (fileId) => `${window.baseURL}/file/download/${fileId}`; +const menu = [ + { text: 'پسند', icon: FavoriteIcon, onClick: () => {} }, + { text: 'تبادل نظر', icon: TextsmsIcon, onClick: () => {} }, + { text: 'پاسخ', icon: ReplyIcon, onClick: () => {} }, + { text: 'باز ارسال', icon: ForwardIcon, onClick: () => {} }, +]; +const selfMenu = [ + { text: 'باز ارسال', icon: ForwardIcon, onClick: () => {} }, + { text: 'ویرایش', icon: EditIcon, onClick: () => {} }, + { text: 'حذف', icon: DeleteIcon, onClick: () => {} }, +]; export default class NormalMessage extends Component { state = { messageMenu: null }; handleClose = () => { @@ -64,11 +77,7 @@ export default class NormalMessage extends Component { >
- {message.voice === null && - message.video === null && - message.image === null && - message.music === null && - message.document === null ? ( -
+
+ +
+ this.handleClose()} + className="rtl fontLight" > -
- -
- this.handleClose()} - style={{ direction: 'rtl', fontFamily: 'IRANSansNumeralLight' }} - > + {(isSelf ? selfMenu : menu).map((e) => ( this.handleClose()} + className="fontLight" + onClick={() => { + this.handleClose(); + e.onClick(); + }} > - - پاسخ + + {e.text} + ))} + + {hasavatar &&
{user.name}
} +
- this.handleClose()} - > - - باز ارسال به - - this.handleClose()} - > - - ویرایش - - this.handleClose()} - > - - حذف - - - {hasavatar &&
{user.name}
} -
+ {message.type == 'text' ? ( +

{message.text}

) : null} - - {message.text !== null && - message.video === null && - message.image === null && - message.music === null && - message.document === null ? ( -

- {message.text} -

+ {message.type == 'voice' ? ( + ) : null} - {message.voice !== null ? : null} - {message.image !== null ? ( -
{ - console.log(refElem); - }} - > - - + {message.type == 'image' ? ( +
+ + -

- {message.text} -

+

{message.text}

) : null} - {message.video !== null ? ( + {message.type == 'video' ? (
- - + + -

- {message.text} -

+

{message.text}

) : null} - {message.music !== null ? : null} - {message.document !== null ? ( + {message.type == 'audio' ? ( +
+ +

{message.text}

+
+ ) : null} + {message.type == 'document' ? ( -
{message.document.name}
+
{message.text}
) : null} -
+
- {message.status == 1 && } - {message.status == 2 && } - {message.updatedAt ? ( + {message.updatedAt != message.createdAt ? ( <> ویرایش در @@ -220,22 +185,43 @@ export default class NormalMessage extends Component { moment(message.createdAt).format('hh:mm') )} + + {isSelf && message.status == 0 && } + {isSelf && message.status == 1 && } + {isSelf && message.status == 2 && } +
-
- - {10} -
- - {/*
- - {10} -
-
- {'+5 اعتماد به نفس'} -
*/} + {!isSelf ? ( + <> + {' '} +
+ + {10} +
+
+ + {10} +
+ + ) : ( + <> +
+ + +5 +
+ خلاقیت +
+
+ + )}
{ - if (this.props.isActive) - this.setState({ - value: newValue, - }); + state = { + value: this.props.message.value, + }; + handleRadioChange = (value) => { + if (this.props.isActive) this.setState({ value }); }; render() { - const { message, user, isSelf, isActive } = this.props; + const { message, user, isSelf, isActive, action } = this.props; + const { value } = this.state; return (
{message.options.map((row) => ( - + ))}
{isActive && ( - )}
diff --git a/src/views/ChatRoom/Body/Message/Slider/index.js b/src/views/ChatRoom/Body/Message/Slider/index.js index 03b2ee4..5458515 100644 --- a/src/views/ChatRoom/Body/Message/Slider/index.js +++ b/src/views/ChatRoom/Body/Message/Slider/index.js @@ -6,85 +6,54 @@ import ArrowRightAltIcon from '@material-ui/icons/ArrowRightAlt'; import Avatar from '@material-ui/core/Avatar'; import { toast } from 'react-toastify'; export default class SliderMessage extends Component { - constructor(props) { - super(props); - this.state = { - value: 10, - }; - } - - handleSliderChange = (event, newValue) => { - if (this.props.isActive) - this.setState({ - value: newValue, - }); + state = { + value: this.props.message.value || 0, }; - - handleInputChange = (event) => { - if (this.props.isActive) - this.setState({ - value: event.target.value === '' ? '' : Number(event.target.value), - }); + onChange = (value) => { + if (!this.props.isActive || !value) return; + const [min, max, step] = this.props.message.options[0] || [0, 100, 1]; + this.setState({ value: Math.min(max, Math.max(min, parseFloat(value))) }); }; - handleBlur = () => { - if (this.props.isActive) - if (this.state.value < 0) { - this.setState({ value: 0 }); - } else if (this.state.value > 20) { - this.setState({ value: 20 }); - } - }; render() { - const { message, user, isSelf, isActive } = this.props; + const { message, isActive, action } = this.props; + const [min, max, step] = message.options[0] || [0, 100, 1]; + const { value } = this.state; return ( -
+
this.onChange(value)} aria-labelledby="input-slider" - style={{ marginTop: 10 }} - min={0} - max={20} - step={0.1} + min={min} + max={max} + step={step} /> this.handleInputChange(e)} - onBlur={() => this.handleBlur()} + onChange={(e) => this.onChange(e.target.value)} + onBlur={() => this.onChange(value)} inputProps={{ - step: 0.1, - min: 0, - max: 20, + step: step, + min: min, + max: max, type: 'number', 'aria-labelledby': 'input-slider', }} - style={{ - width: 42, - borderBottom: '2px solid #000099', - paddingLeft: 10, - marginBottom: 18, - color: '#000099', - }} /> {isActive && ( - )}
diff --git a/src/views/ChatRoom/Body/Message/Slider/index.scss b/src/views/ChatRoom/Body/Message/Slider/index.scss index e69de29..a5ed48b 100644 --- a/src/views/ChatRoom/Body/Message/Slider/index.scss +++ b/src/views/ChatRoom/Body/Message/Slider/index.scss @@ -0,0 +1,13 @@ +.sliderBox { + margin-top: 2px; + .slider { + margin-top: 10px; + } + input { + width: 42px; + border-bottom: 2px solid #000099; + padding-left: 10px; + margin-bottom: 18px; + color: #000099; + } +} diff --git a/src/views/ChatRoom/Body/Message/Sort/index.js b/src/views/ChatRoom/Body/Message/Sort/index.js index 6f16693..99df8c5 100644 --- a/src/views/ChatRoom/Body/Message/Sort/index.js +++ b/src/views/ChatRoom/Body/Message/Sort/index.js @@ -18,15 +18,15 @@ export default class DraggableMessage extends Component { }; render() { - const { message, user, isSelf, isActive } = this.props; + const { message, user, isSelf, isActive, action } = this.props; return (
{isActive && ( - )}
diff --git a/src/views/ChatRoom/Body/Message/Tap/index.js b/src/views/ChatRoom/Body/Message/Tap/index.js new file mode 100644 index 0000000..78a8195 --- /dev/null +++ b/src/views/ChatRoom/Body/Message/Tap/index.js @@ -0,0 +1,26 @@ +import React, { Component } from 'react'; +import arrayMove from 'array-move'; + +export default class DraggableMessage extends Component { + constructor(props) { + super(props); + this.state = this.props.message; + } + onSortEnd = ({ oldIndex, newIndex }) => { + if (this.props.isActive) + this.setState(({ options }) => ({ + options: arrayMove(options, oldIndex, newIndex), + })); + }; + + render() { + const { message, user, isSelf, isActive } = this.props; + if (!isActive) return null; + return
; + } + a = ( + + ); +} diff --git a/src/views/ChatRoom/Body/Message/Tap/index.scss b/src/views/ChatRoom/Body/Message/Tap/index.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/views/ChatRoom/Body/Message/index.js b/src/views/ChatRoom/Body/Message/index.js index 150487f..4b13c79 100644 --- a/src/views/ChatRoom/Body/Message/index.js +++ b/src/views/ChatRoom/Body/Message/index.js @@ -5,30 +5,42 @@ import Sort from './Sort'; import Slider from './Slider'; import Select from './Select'; import MultiSelect from './MultiSelect'; +import Tap from './Tap'; +import ArrowRightAltIcon from '@material-ui/icons/ArrowRightAlt'; + import './index.scss'; const types = { - normal: <>, sort: Sort, inline: Inline, - silder: Slider, + slider: Slider, select: Select, multiselect: MultiSelect, + tap: Tap, }; export default class Message extends Component { render() { - const { message, user, isSelf, file, document, prevUserId, isActive } = this.props; - const Key = types[message.type]; + const { message, user, isSelf, file, document, prevUserId, isActive, addcounter } = this.props; + const Action = types[message.action]; return (
- + {Action ? ( + + ) : null} + {/* {isActive && ( + + )} */}
); diff --git a/src/views/ChatRoom/Body/Message/index.scss b/src/views/ChatRoom/Body/Message/index.scss index 4fc619f..a0d5ff8 100644 --- a/src/views/ChatRoom/Body/Message/index.scss +++ b/src/views/ChatRoom/Body/Message/index.scss @@ -2,4 +2,13 @@ .Message { margin-top: 2px; } + .tapbox { + z-index: 500; + position: absolute; + top: 0; + left: 0; + background-color: #fff; + width: 100%; + height: 100%; + } } diff --git a/src/views/ChatRoom/Body/index.js b/src/views/ChatRoom/Body/index.js index 8098b37..a7f1577 100644 --- a/src/views/ChatRoom/Body/index.js +++ b/src/views/ChatRoom/Body/index.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import Message from './Message'; import ChatInputs from './Input'; -import ChatSuggest from './Keyboard'; +import Keyboard from './Keyboard'; import { RecordState } from 'audio-react-recorder'; import ReactPlayer from 'react-player'; import ReactAudioPlayer from 'react-audio-player'; @@ -9,11 +9,13 @@ import { ToastContainer } from 'react-toastify'; import { list, send, sendKeys } from '../../../Redux/actions/message'; import { info, bio } from '../../../Redux/actions/chat'; import { connect } from 'react-redux'; + import './index.scss'; class List extends Component { constructor(props) { super(props); this.state = { + counter: 1, id: window.location.href.split('/').pop() * 1, data: {}, message: '', @@ -23,16 +25,11 @@ class List extends Component { video: null, music: null, document: null, - footer: 'normal', - suggest: [ - [{ id: 0, text: 'سلام' }], - [{ id: 1, text: 'وقت بخیر' }], - [{ id: 2, text: 'لطفا بامن تماس بگیر' }], - [{ id: 3, text: 'متشکرم' }], - ], }; } - + addcounter() { + this.setState({ counter: this.state.counter + 1 }); + } start = () => { this.setState({ voice: RecordState.START, @@ -346,11 +343,17 @@ class List extends Component { return color; } render() { - const { setPage, chatInfo, messageList, userId } = this.props; - const userIdx = {}; - chatInfo.users.map((e) => (userIdx[e.id] = { ...e, color: this.randomColor() })); + const { setPage, chatInfo, messageList: msaster, userId } = this.props; //last + const messageList = msaster.slice(0, this.state.counter); + const last = messageList.slice(-1)[0] || {}; + const userIdx = this.userIdx || {}; + if (Object.keys(userIdx).length == 0) { + chatInfo.users.map((e) => (userIdx[e.id] = { ...e, color: this.randomColor() })); + this.userIdx = userIdx; + } + return ( -
+
setPage('info')}>

{chatInfo.title}

{chatInfo.subTitle}

@@ -362,23 +365,24 @@ class List extends Component { paddingTop: 10, overflowX: 'hidden', overflowY: this.state.file !== null ? 'hidden' : 'scroll', - paddingBottom: this.state.footer === 'suggest' ? 150 : 40, + paddingBottom: last.action === 'keyboard' ? 150 : 75, }} > {chatInfo.users && - messageList.map((item, i) => + messageList.map((message, i) => this.state.image === null && this.state.music === null && this.state.video === null ? ( this.addcounter()} + isActive={message.id == last.id} prevUserId={i > 0 ? messageList[i - 1].userId : 0} - isSelf={1 == item.userId} - key={i} + isSelf={1 == message.userId} + key={message.id} file={this.state.image} document={this.state.document} - message={{ ...item, value: 1 }} - user={userIdx[item.userId] || { id: 0, fileId: 0, name: 'null' }} + message={message} + user={userIdx[message.userId] || { id: 0, fileId: 0, name: 'null' }} /> ) : null )} @@ -414,8 +418,9 @@ class List extends Component { ) : null}
- {this.state.footer === 'normal' ? ( + {last.action == 'text' ? ( this.addcounter()} onStop={this.onStop} stop={this.stop} start={this.start} @@ -428,10 +433,12 @@ class List extends Component { file={this.state.file} /> ) : null} - {this.state.footer === 'suggest' ? : null} + {last.action === 'keyboard' ? ( + this.addcounter()} /> + ) : null}