Skip to content

Commit 739302c

Browse files
committed
unfinished img
1 parent 8be6f81 commit 739302c

File tree

19 files changed

+468
-30
lines changed

19 files changed

+468
-30
lines changed

client/src/Hooks/http.hook.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export const useHttp = () => {
2222
if (body) {
2323
body = JSON.stringify(body)
2424
headers['Content-Type'] = 'application/json'
25+
headers['Content-Length'] = String(Number(String(body).length) + 100)
2526
}
2627
/**отправка запроса */
2728
const response = await fetch(url, { method, body, headers })

client/src/Hooks/useFetchNotes.hook.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,20 @@ function useFetchNotes(token) {
1818
*/
1919
async function fetchNotes(url = "", method = "GET", body = null, resCallback = () => { }) {
2020
try {
21-
/**запрос к серверу с определенными параметрами*/
21+
/**запрос к серверу о заметках с определенными параметрами*/
2222
const fetched = await request(`/api/notes${url ? ("/" + url) : ""}`, method, body, { Authorization: `Bearer ${token}` })
2323
resCallback(tryParce(fetched))
2424
} catch (e) { }
2525
}
2626

27+
async function fetchMedia(url = "", method = "GET", body = null, resCallback = () => { }) {
28+
try {
29+
/**запрос к серверу о медиа с определенными параметрами*/
30+
const fetched = await request(`/api/media${url ? ("/" + url) : ""}`, method, body, { Authorization: `Bearer ${token}` })
31+
resCallback(tryParce(fetched))
32+
} catch (e) { }
33+
}
34+
2735
function tryParce(str) {
2836
try {
2937
return JSON.parse(str);
@@ -32,7 +40,7 @@ function useFetchNotes(token) {
3240
}
3341
}
3442

35-
return { loading, fetchNotes, error, clearError }
43+
return { loading, fetchNotes, fetchMedia, error, clearError }
3644
}
3745

3846
export default useFetchNotes

client/src/NoteComponents/ModalNoteEdit.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import NotesContext from '../Context/NotesContext'
66
import TextareaAutosize from 'react-textarea-autosize'
77
import Modal, { ModalProps } from "../Shared/Components/Modal/Modal"
88
import Palette from './palette/palette'
9+
import Media from './media/media'
910

1011
/**расчет числа строк */
1112
function calcMaxRows() {
@@ -25,7 +26,7 @@ function calcMaxRows() {
2526
*/
2627
function ModalNoteEdit() {
2728
/**получение контекста */
28-
const { removeNote, changeNoteColor, unsetEditNoteId, editNoteContent, getNoteById, editNoteId } = React.useContext(NotesContext)
29+
const { removeNote, changeNoteColor, unsetEditNoteId, editNoteMedia, editNoteContent, getNoteById, editNoteId } = React.useContext(NotesContext)
2930

3031
/** обьект заметки */
3132
const note = getNoteById(editNoteId)
@@ -76,6 +77,14 @@ function ModalNoteEdit() {
7677
changeNoteColor(editNoteId, color)
7778
}
7879

80+
/**
81+
* Изменение медиа заметки
82+
* @param {*} media
83+
*/
84+
function trySetNoteMedia(media) {
85+
editNoteMedia(editNoteId, media)
86+
}
87+
7988
/**
8089
* удаление
8190
*/
@@ -144,6 +153,14 @@ function ModalNoteEdit() {
144153
disabled={!note}
145154
setColor={tryChangeColor}
146155
></Palette>
156+
<Media
157+
className="btn btn-light mx-1"
158+
style={{ boxShadow: "none" }}
159+
disabled={!note}
160+
mediaList={note ? note.media || [] : []}
161+
setNoteMedia={trySetNoteMedia}
162+
noteId={note ? note.id : null}
163+
></Media>
147164
<button
148165
className="btn btn-light"
149166
style={{ boxShadow: "none" }}
@@ -153,7 +170,7 @@ function ModalNoteEdit() {
153170
</div>
154171
{/**Индикатор номера заметки */}
155172
<div className="mx-auto">
156-
<span style={{ color: "lightgray", fontWeight: "400" }}>{note && note.order}</span>
173+
<span style={{ color: "lightgray", fontWeight: "400" }}>{note && String(note.order)}</span>
157174
</div>
158175
{/**Зактрытие окна */}
159176
<div>

client/src/NoteComponents/NoteItem.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ function fixLineBreaks(mdStr) {
1919
*/
2020
function NoteItem({ note }) {
2121
/**Подключение контекста */
22-
const { setEditNoteId, editNoteOrder } = useContext(NotesContext)
22+
const { setEditNoteId, editNoteOrder, getMediaById } = useContext(NotesContext)
2323

2424
const lineClip = 12
25-
const bgColor = note.color
25+
const bgColor = note.color || "#f8f9fa"
26+
const mediaList = note.media ? note.media || [] : []
2627

2728
const footerBtn = {
2829
className: `btn btn-light p-0 text-secondary item-footer-btn`,
@@ -37,6 +38,15 @@ function NoteItem({ note }) {
3738
return (
3839
<div className="p-1" >
3940
<div className="card" style={{ backgroundColor: bgColor }} >
41+
42+
{/**Изображение заметки*/}
43+
{Array.isArray(mediaList) ? (mediaList.map((imgId) => {
44+
const media = getMediaById(imgId)
45+
const src = typeof media === "object" && media && media.data
46+
return (
47+
<img key={imgId} onClick={() => setEditNoteId(note.id)} className="card-img-top" src={src} alt="note img"></img>
48+
)
49+
})) : null}
4050
{/**Заголовок и текст заметки с обработчиками отображения markdown*/}
4151
<div className="card-body" onClick={() => setEditNoteId(note.id)} >
4252
<div
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.media-btn:focus {
2+
box-shadow: 0 0 0 0.2rem rgb(216 217 219 / 50%) !important;
3+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/**
2+
* @file media.js
3+
*/
4+
import React, { useContext } from "react"
5+
import PropTypes from 'prop-types'
6+
import "./media.css"
7+
import NotesContext from "../../Context/NotesContext"
8+
import Modal, { ModalProps } from "../../Shared/Components/Modal/Modal"
9+
10+
const MAX_PAYLOAD_SIZE = 100 * 1024
11+
12+
/**
13+
* компонент палитры
14+
* @param {*} param0
15+
*
16+
*/
17+
function Media({ setNoteMedia, mediaList = [], style, className, disabled, noteId }) {
18+
const { addMedia, removeMedia, getMediaById, getNoteById } = useContext(NotesContext)
19+
20+
const limited = getNoteById(noteId).media.length >= 3
21+
22+
/**хук состояния формы */
23+
const [showForm, setShowForm] = React.useState(false)
24+
25+
/**создание параметров модального окна*/
26+
const modalProps = new ModalProps()
27+
modalProps.isOpen = showForm
28+
modalProps.setOpenState = setShowForm
29+
modalProps.sideClose = true
30+
31+
/**открытие окна */
32+
function open() {
33+
setShowForm(true)
34+
}
35+
36+
/**закрытие окна */
37+
function close() {
38+
setShowForm(false)
39+
}
40+
41+
function encodeImageFileAsURLAndPost(e) {
42+
var file = e.target.files[0]
43+
var reader = new FileReader()
44+
45+
reader.onloadend = function () {
46+
const res = reader.result
47+
if (res.length < MAX_PAYLOAD_SIZE) {
48+
console.log("readed suc", res.length)
49+
const mediaId = addMedia(res, noteId)
50+
Array.isArray(mediaList) ? mediaList.push(mediaId) : (mediaList = [mediaId])
51+
setNoteMedia(mediaList)
52+
} else {
53+
console.error("readed unsuc", res.length)
54+
}
55+
e.target.value = null
56+
}
57+
58+
if (file !== undefined) reader.readAsDataURL(file)
59+
}
60+
61+
function delImg(imgId, index) {
62+
removeMedia(imgId)
63+
mediaList.splice(index, 1)
64+
setNoteMedia(mediaList)
65+
}
66+
67+
return (
68+
<React.Fragment>
69+
{/**Кнопка вызова media */}
70+
<button
71+
disabled={disabled}
72+
className={`btn ${className}`}
73+
style={style}
74+
type="button"
75+
onClick={open}
76+
>
77+
<i className="bi bi-image" ></i>
78+
</button>
79+
80+
{/**Форма media */}
81+
<Modal {...modalProps.bind()} >
82+
<div className="p-1 d-flex flex-row flex-wrap justify-content-center align-items-center">
83+
84+
<div className="form-group container d-flex flex-row flex-wrap mb-0">
85+
{Array.isArray(mediaList) ? (mediaList.map((imgId, index) => {
86+
const media = getMediaById(imgId)
87+
const src = typeof media === "object" && media && media.data
88+
return (
89+
<div className="card p-1 m-1" key={imgId} style={{ position: "relative" }}>
90+
<img style={{ maxWidth: "8em", maxHeight: "8em" }} src={src} alt="note img"></img>
91+
<button
92+
style={{ position: "absolute", bottom: "0", right: "0", lineHeight: "1em", padding: "0.05em" }}
93+
className={`btn btn-danger m-1`}
94+
onClick={() => delImg(imgId, index)}
95+
>&#10007;</button>
96+
</div>
97+
)
98+
})) : null}
99+
</div>
100+
101+
<div className="form-group container d-flex flex-wrap justify-content-between mb-0">
102+
<div className="custom-file mb-0 m-1" style={{ maxWidth: "14em" }}>
103+
<input disabled={limited} onChange={encodeImageFileAsURLAndPost} type="file" className="custom-file-input" id="noteImgFile" accept=".jpg, .jpeg, .png" />
104+
<label className="custom-file-label" htmlFor="noteImgFile">{"Img - 100Kb max"}</label>
105+
</div>
106+
<button
107+
className="btn btn-light m-1"
108+
style={{ boxShadow: "none" }}
109+
onClick={close}
110+
>Close</button>
111+
</div>
112+
113+
</div>
114+
</Modal>
115+
116+
</React.Fragment>
117+
);
118+
}
119+
120+
// Валидация
121+
Media.propTypes = {
122+
setNoteMedia: PropTypes.func,
123+
style: PropTypes.object,
124+
className: PropTypes.string,
125+
}
126+
127+
export default Media;
128+
129+
130+
131+
132+
133+

client/src/NoteComponents/palette/palette.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@ function Palette({ setColor, style, className, disabled }) {
3232
className={`btn ${className}`}
3333
style={style}
3434
type="button"
35-
id="dropdownMenuButton"
35+
id="dropdownMenuButtonPalette"
3636
data-toggle="dropdown"
3737
aria-haspopup="true"
3838
aria-expanded="false"
3939
>
4040
<i className="bi bi-palette" ></i>
4141
</button>
4242
{/**Форма выбора цвета */}
43-
<div className="dropdown-menu tab-content mt-1" aria-labelledby="dropdownMenuButton">
43+
<div className="dropdown-menu tab-content mt-1" aria-labelledby="dropdownMenuButtonPalette">
4444
<form>
4545
<div className="d-flex flex-row flex-wrap justify-content-center">
4646
{colors.map((color, key) => (

0 commit comments

Comments
 (0)