Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"react-scripts": "4.0.3",
"react-stack-grid": "^0.7.1",
"react-textarea-autosize": "^8.3.3",
"react-use-websocket": "^2.7.1",
"remark-gfm": "^1.0.0",
"web-vitals": "^0.2.4",
"workbox-background-sync": "^5.1.4",
Expand Down
37 changes: 0 additions & 37 deletions client/src/Hooks/useDebouncedEffect.hook.js

This file was deleted.

23 changes: 23 additions & 0 deletions client/src/Hooks/useDebouncedFunction.hook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/** @file useDebouncedFunction.hook.js */
import { useEffect, useReducer } from 'react';

/**
* Хук Debounced Function
* @param {(arg)=>void} callback
* @param {number} delayms
*/
function useDebouncedFunction(callback, delayms) {
const [state, debounced] = useReducer((state, arg) => {
return { count: state.count + 1, arg: arg }
}, { count: 0, arg: undefined })
useEffect(() => {
const handler = setTimeout(() => {
if (state.count) callback(state.arg)
}, delayms)
return () => clearTimeout(handler)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [state])
return debounced
}

export default useDebouncedFunction
81 changes: 81 additions & 0 deletions client/src/Hooks/useUpdaterSocket.hook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**@file useUpdaterSocket.hook.js */
import { useCallback } from "react"
import useWebSocket from 'react-use-websocket'
import useDebouncedFunction from "./useDebouncedFunction.hook"
import { useHttp } from "./http.hook"

const WS_PORT = process.env.WS_PORT || 3030

/**
* Хук веб-сокета обновления данных
* @param {void} updateData
* @param {*} auth
*/
function useUpdaterSocket(updateData, auth) {
const { request } = useHttp()

/**дебонсированный обработчик входящего обновления */
const debouncedUpdate = useDebouncedFunction(updateData, 200)

/**колбек для получения url сокета */
const getSocketUrl = useCallback(async () => {
return new Promise(resolve => {
request("/getIp")
.then((data) => {
const ip = data.ip
const socketAddress = "ws://" + (ip || "localhost") + ":" + WS_PORT
console.log("socketAddress", socketAddress)
resolve(socketAddress)
})
.catch((err) => console.log(err))
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

/**опции обработки событий сокета */
const socketOptions = {
onOpen: (e) => {
sendRegisterMsg()
console.log("ws open")
},
onClose: (e) => {
console.error("ws close")
},
onMessage: (e) => {
console.log("ws update message")
debouncedUpdate()
},
onError: (e) => {
console.error("ws error", e)
},
}

/**подключение WebSocket */
const { sendMessage } = useWebSocket(getSocketUrl, socketOptions)

/**дебонсированный обработчик отсылаемого обновления */
const sendUpdateMsgDebounced = useDebouncedFunction(sendUpdateMsg, 200)

/** отпрака сообщения сокета */
function sendMsg(target) {
const msg = JSON.stringify({
userId: auth.userId,
target
})
sendMessage(msg)
}

/**отправка отсылаемого обновления */
function sendUpdateMsg() {
sendMsg("update")
}

/**отпрака сообщения регистрации сокета */
function sendRegisterMsg() {
sendMsg("register")
}

return [sendUpdateMsgDebounced]
}

export default useUpdaterSocket
4 changes: 2 additions & 2 deletions client/src/NoteComponents/ModalNoteEdit.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ function calcMaxRows() {
*/
function ModalNoteEdit() {
/**получение контекста */
const { removeNote, changeNoteColor, unsetEditNoteId, editNoteContent, getNoteByIndex, editNoteId } = React.useContext(NotesContext)
const { removeNote, changeNoteColor, unsetEditNoteId, editNoteContent, getNoteById, editNoteId } = React.useContext(NotesContext)

/** обьект заметки */
const note = getNoteByIndex(editNoteId)
const note = getNoteById(editNoteId)
React.useEffect(() => { if (note !== null) open() }, [note])

/**хук состояния формы */
Expand Down
12 changes: 5 additions & 7 deletions client/src/NoteComponents/NoteItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* @file NoteItem.js
*/
import React, { useContext } from 'react'
import PropTypes from 'prop-types'
import NotesContext from '../Context/NotesContext'
import Note, { PropTypeNote } from '../Shared/noteType/Note'
import ReactMarkdown from 'react-markdown'
Expand All @@ -18,7 +17,7 @@ function fixLineBreaks(mdStr) {
* @param {*} param0
*
*/
function NoteItem({ note = new Note(), index }) {
function NoteItem({ note = new Note() }) {
/**Подключение контекста */
const { setEditNoteId, editNoteOrder } = useContext(NotesContext)

Expand All @@ -39,7 +38,7 @@ function NoteItem({ note = new Note(), index }) {
<div className="p-1" >
<div className="card" style={{ backgroundColor: bgColor }} >
{/**Заголовок и текст заметки с обработчиками отображения markdown*/}
<div className="card-body" onClick={() => setEditNoteId(index)} >
<div className="card-body" onClick={() => setEditNoteId(note.id)} >
<div
className="card-title h5"
style={{ overflow: "hidden", display: "-webkit-box", WebkitLineClamp: String(lineClip / 2), WebkitBoxOrient: "vertical" }} >
Expand All @@ -56,14 +55,14 @@ function NoteItem({ note = new Note(), index }) {
<button
className={footerBtn.className}
style={footerBtn.style}
onClick={() => editNoteOrder(index, false)}
onClick={() => editNoteOrder(note.id, false)}
>
<i className="bi bi-chevron-compact-right"></i>
</button>
<button
className={footerBtn.className}
style={footerBtn.style}
onClick={() => editNoteOrder(index, true)}
onClick={() => editNoteOrder(note.id, true)}
>
<i className="bi bi-chevron-compact-left"></i>
</button>
Expand All @@ -75,8 +74,7 @@ function NoteItem({ note = new Note(), index }) {

// Валидация
NoteItem.propTypes = {
note: PropTypeNote.isRequired,
index: PropTypes.number
note: PropTypeNote.isRequired
}

export default NoteItem
Expand Down
4 changes: 2 additions & 2 deletions client/src/NoteComponents/NoteList.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ function NoteList(props) {
{/**Отзывчивая сетка карточек */}
<StackGrid className="container p-0" {...gridSettings}>
{/**Рендер каждой карточки из массива */}
{Array.isArray(props.notes) ? (props.notes.sort(sortByOrder).reverse().map((note, index) => {
{Array.isArray(props.notes) ? (props.notes.sort(sortByOrder).reverse().map((note) => {
return (
<NoteItem note={note} key={note.id} index={index} />
<NoteItem note={note} key={note.id} />
)
})) : null}
</StackGrid>
Expand Down
Loading