123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- const URL = "http://students.a-level.com.ua:10012"
- const delay = ms => new Promise((resolve) => setTimeout(() => resolve(ms), ms));
- function createStore(reducer) {
- let state = reducer(undefined, {})
- let subscribers = []
- function dispatch(action) {
- if (typeof action === 'function') {
- return action(dispatch)
- }
- const newState = reducer(state, action)
- if (state !== newState) {
- state = newState
- subscribers.forEach(cb => cb())
- }
- }
- return {
- getState() {
- return state;
- },
- subscribe(cb) {
- subscribers.push(cb)
- return () => subscribers = subscribers.filter(c => c !== cb)
- },
- dispatch
- }
- }
- let btnSend = document.querySelector('#send');
- let inputNick = document.querySelector('#nick');
- let inputMessage = document.querySelector('#msg');
- let lastMessageId =0;
- async function getHistory() {
- let msg = await jsonPost(
- URL, {func: 'getMessages', messageId: lastMessageId})
- lastMessageId = msg.nextMessageId
- msg.data.forEach(i => showMessage(i.nick, i.message))
- }
- getHistory().then();
- function showMessage(inputNick, inputMessage) {
- let divChat = document.querySelector('#chat');
- let msgDiv = document.createElement('div');
- msgDiv.style.display = 'inline-block';
- let nickSpan = document.createElement('span');
- nickSpan.innerHTML= '<b/>' + inputNick + ' : '
- let messSpan = document.createElement('span');
- messSpan.innerHTML= inputMessage
- msgDiv.style.cssText = 'border-bottom: 1px solid gray; padding: 5px;'
- divChat.prepend(msgDiv);
- msgDiv.prepend(messSpan);
- msgDiv.prepend(nickSpan);
- }
- function chatReducer(
- state = {
- messages: [],
- sendStatus: "",
- getStatus: "",
- nextMessageId: 0
- },
- {type, messages=[]}) {
- if (type === 'SEND_PENDING') {
- return {...state, sendStatus: 'PENDING'}
- }
- if (type === 'SEND_RESOLVED') {
- return {...state, sendStatus: 'RESOLVED'}
- }
- if (type === 'SEND_REJECTED') {
- return {...state, sendStatus: 'REJECTED'}
- }
- if (type === 'SEND_CLEAR') {
- return {...state, sendStatus: 'CLEAR'}
- }
- if (type === 'GET_PENDING') {
- return {...state, getStatus: 'PENDING'}
- }
- if (type === 'GET_RESOLVED') {
- return {...state, getStatus: 'PENDING', messages: [...state.messages, ...messages]}
- }
- if (type === 'GET_REJECTED') {
- return {...state, getStatus: 'REJECTED'}
- }
- return state;
- }
- const actionSendPending = () => ({type: "SEND_PENDING"})
- const actionSendResolved = () => ({type: "SEND_RESOLVED"})
- const actionSendRejected = () => ({type: "SEND_REJECTED"})
- const actionGetPending = () => ({type: "GET_PENDING"})
- const actionGetResolved = (messages, nextMessageId) => ({type: "GET_RESOLVED", messages,nextMessageId})
- const actionGetRejected = () => ({type: "GET_REJECTED"})
- const actionSendClear = () => ({type: "SEND_CLEAR"})
- const store = createStore(chatReducer)
- store.subscribe(() => console.log(store.getState()));
- store.subscribe(() => {}
- // btnSend.disabled = store.getState().sendStatus === "PENDING";
- // store.getState().sendStatus === "RESOLVED" && store.dispatch(actionSendClear())}
- // store.dispatch(actionSendClear())
- )
- const actionSend = (nick, message) =>
- async dispatch => {
- try {
- dispatch(actionSendPending())
- await jsonPost(
- URL,
- {
- func: 'addMessage',
- nick: nick,
- message: message
- }
- )
- dispatch(actionSendResolved())
- } catch (e) {
- dispatch(actionSendRejected(e))
- }
- }
- const actionGet = () =>
- async dispatch => {
- try {
- dispatch(actionGetPending())
- let data= await jsonPost(
- URL,
- {
- func: 'getMessages',
- messageId: lastMessageId
- }
- )
- dispatch(actionGetResolved(data.data,data.nextMessageId))
- lastMessageId = data.nextMessageId;
- data.data.forEach(i => showMessage(i.nick, i.message))
- } catch (e) {
- dispatch(actionGetRejected(e))
- }
- finally {
- // checkLoop().then()
- }
- }
- store.getState()
- const sendAndCheck=async()=>{
- if(inputNick.value.trim() && inputMessage.value.trim()){
- await store.dispatch(actionSend(inputNick.value, inputMessage.value))
- await store.dispatch(actionGet())}
- }
- async function checkLoop() {
- while (true) {
- store.dispatch(actionGet())
- await delay(3000);
- // await getMessages();
- }
- }
- checkLoop().then()
- store.subscribe(() => {
- let currentState = store.getState()
- if ("PENDING") {
- msg.placeholder = 'enter your message'
- spinner.style.display = "inline-block";
- } else if (currentState === "REJECTED") {
- msg.placeholder = 'error'
- msg.style.background='red'
- spinner.style.display = "none";
- } else if (currentState === "RESOLVED") {
- msg.placeholder = 'enter your message'
- spinner.style.display = "none";
- }
- })
- btnSend.onclick = () => {store.dispatch(sendAndCheck())
- inputMessage.value=''
- };
- async function jsonPost(url, data) {
- let response = await fetch(url, {
- method: 'POST',
- body: JSON.stringify(data),
- });
- if (response.status == 200) {
- let data2 = await response.json();
- return data2;
- }
- throw new Error('failed');
- }
|