script.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. const URL = "http://students.a-level.com.ua:10012"
  2. const delay = ms => new Promise((resolve) => setTimeout(() => resolve(ms), ms));
  3. function createStore(reducer) {
  4. let state = reducer(undefined, {})
  5. let subscribers = []
  6. function dispatch(action) {
  7. if (typeof action === 'function') {
  8. return action(dispatch)
  9. }
  10. const newState = reducer(state, action)
  11. if (state !== newState) {
  12. state = newState
  13. subscribers.forEach(cb => cb())
  14. }
  15. }
  16. return {
  17. getState() {
  18. return state;
  19. },
  20. subscribe(cb) {
  21. subscribers.push(cb)
  22. return () => subscribers = subscribers.filter(c => c !== cb)
  23. },
  24. dispatch
  25. }
  26. }
  27. let btnSend = document.querySelector('#send');
  28. let inputNick = document.querySelector('#nick');
  29. let inputMessage = document.querySelector('#msg');
  30. let lastMessageId =0;
  31. async function getHistory() {
  32. let msg = await jsonPost(
  33. URL, {func: 'getMessages', messageId: lastMessageId})
  34. lastMessageId = msg.nextMessageId
  35. msg.data.forEach(i => showMessage(i.nick, i.message))
  36. }
  37. getHistory().then();
  38. function showMessage(inputNick, inputMessage) {
  39. let divChat = document.querySelector('#chat');
  40. let msgDiv = document.createElement('div');
  41. msgDiv.style.display = 'inline-block';
  42. let nickSpan = document.createElement('span');
  43. nickSpan.innerHTML= '<b/>' + inputNick + ' : '
  44. let messSpan = document.createElement('span');
  45. messSpan.innerHTML= inputMessage
  46. msgDiv.style.cssText = 'border-bottom: 1px solid gray; padding: 5px;'
  47. divChat.prepend(msgDiv);
  48. msgDiv.prepend(messSpan);
  49. msgDiv.prepend(nickSpan);
  50. }
  51. function chatReducer(
  52. state = {
  53. messages: [],
  54. sendStatus: "",
  55. getStatus: "",
  56. nextMessageId: 0
  57. },
  58. {type, messages=[]}) {
  59. if (type === 'SEND_PENDING') {
  60. return {...state, sendStatus: 'PENDING'}
  61. }
  62. if (type === 'SEND_RESOLVED') {
  63. return {...state, sendStatus: 'RESOLVED'}
  64. }
  65. if (type === 'SEND_REJECTED') {
  66. return {...state, sendStatus: 'REJECTED'}
  67. }
  68. if (type === 'SEND_CLEAR') {
  69. return {...state, sendStatus: 'CLEAR'}
  70. }
  71. if (type === 'GET_PENDING') {
  72. return {...state, getStatus: 'PENDING'}
  73. }
  74. if (type === 'GET_RESOLVED') {
  75. return {...state, getStatus: 'PENDING', messages: [...state.messages, ...messages]}
  76. }
  77. if (type === 'GET_REJECTED') {
  78. return {...state, getStatus: 'REJECTED'}
  79. }
  80. return state;
  81. }
  82. const actionSendPending = () => ({type: "SEND_PENDING"})
  83. const actionSendResolved = () => ({type: "SEND_RESOLVED"})
  84. const actionSendRejected = () => ({type: "SEND_REJECTED"})
  85. const actionGetPending = () => ({type: "GET_PENDING"})
  86. const actionGetResolved = (messages, nextMessageId) => ({type: "GET_RESOLVED", messages,nextMessageId})
  87. const actionGetRejected = () => ({type: "GET_REJECTED"})
  88. const actionSendClear = () => ({type: "SEND_CLEAR"})
  89. const store = createStore(chatReducer)
  90. store.subscribe(() => console.log(store.getState()));
  91. store.subscribe(() => {}
  92. // btnSend.disabled = store.getState().sendStatus === "PENDING";
  93. // store.getState().sendStatus === "RESOLVED" && store.dispatch(actionSendClear())}
  94. // store.dispatch(actionSendClear())
  95. )
  96. const actionSend = (nick, message) =>
  97. async dispatch => {
  98. try {
  99. dispatch(actionSendPending())
  100. await jsonPost(
  101. URL,
  102. {
  103. func: 'addMessage',
  104. nick: nick,
  105. message: message
  106. }
  107. )
  108. dispatch(actionSendResolved())
  109. } catch (e) {
  110. dispatch(actionSendRejected(e))
  111. }
  112. }
  113. const actionGet = () =>
  114. async dispatch => {
  115. try {
  116. dispatch(actionGetPending())
  117. let data= await jsonPost(
  118. URL,
  119. {
  120. func: 'getMessages',
  121. messageId: lastMessageId
  122. }
  123. )
  124. dispatch(actionGetResolved(data.data,data.nextMessageId))
  125. lastMessageId = data.nextMessageId;
  126. data.data.forEach(i => showMessage(i.nick, i.message))
  127. } catch (e) {
  128. dispatch(actionGetRejected(e))
  129. }
  130. finally {
  131. // checkLoop().then()
  132. }
  133. }
  134. store.getState()
  135. const sendAndCheck=async()=>{
  136. if(inputNick.value.trim() && inputMessage.value.trim()){
  137. await store.dispatch(actionSend(inputNick.value, inputMessage.value))
  138. await store.dispatch(actionGet())}
  139. }
  140. async function checkLoop() {
  141. while (true) {
  142. store.dispatch(actionGet())
  143. await delay(3000);
  144. // await getMessages();
  145. }
  146. }
  147. checkLoop().then()
  148. store.subscribe(() => {
  149. let currentState = store.getState()
  150. if ("PENDING") {
  151. msg.placeholder = 'enter your message'
  152. spinner.style.display = "inline-block";
  153. } else if (currentState === "REJECTED") {
  154. msg.placeholder = 'error'
  155. msg.style.background='red'
  156. spinner.style.display = "none";
  157. } else if (currentState === "RESOLVED") {
  158. msg.placeholder = 'enter your message'
  159. spinner.style.display = "none";
  160. }
  161. })
  162. btnSend.onclick = () => {store.dispatch(sendAndCheck())
  163. inputMessage.value=''
  164. };
  165. async function jsonPost(url, data) {
  166. let response = await fetch(url, {
  167. method: 'POST',
  168. body: JSON.stringify(data),
  169. });
  170. if (response.status == 200) {
  171. let data2 = await response.json();
  172. return data2;
  173. }
  174. throw new Error('failed');
  175. }