-
Social Media 만들기 - 10)Status, create post 창 만들기NODE.JS 2021. 7. 10. 19:44
home 화면에 post, status가 보이도록 설정하자 .
import React from 'react' import { useSelector } from 'react-redux' import Header from '../component/Haader' import Status from '../component/Status' import Post from '../component/Post' function HomePage(props) { const userLogin = useSelector(state => state.userLogin) const userInfo = userLogin if(!userInfo){ props.history.push('/login') } return ( <div className="home row mx-0"> <div className="col-md-8"> <Status/> <Post /> </div> <div className="col-md-4"> </div> </div> ) } export default HomePage
post, status.js component들을 만들어준다.
status.js
import React from 'react' import { useDispatch, useSelector } from 'react-redux' import { STATUS } from '../_constants/globalConstants' import Avatar from './Avatar' function Status() { const userLogin = useSelector(state => state.userLogin) const {userInfo} = userLogin const dispatch = useDispatch() return ( <div className="status my-3 d-flex"> <Avatar src={userInfo.user.avatar} size="big-avatar"/> <button className="statusBtn flex-fill" onClick={()=>dispatch({type:STATUS, payload:true})}> {userInfo.user.username}, what are you thinking? </button> </div> ) } export default Status
status라는 새로운 상수, 리듀서를 만들어서 status값에 따라서 post를 생성하는 창이 뜨도록 설정하자.
globalConstants.js
export const STATUS = 'STATUS'
새로운 statusReducer를 생성해준다.
import { STATUS } from "../_constants/globalConstants"; export const statusReducer = (state=false, action)=>{ switch(action.type){ case STATUS: return action.payload default: return state } }
store.js에 추가해준다.
status:statusReducer,
app.js에 만약 status스토어가 true라면 화면에 StatusModal이 뜨도록 설정하자.
App.js
const status = useSelector(state => state.status) return ( <BrowserRouter> <input type="checkbox" id="theme"/> <div className="App"> <div className="main"> {userInfo && <Header/>} {status && <StatusModal/>}
StatusModal을 작성하자.
여기서는 포스트를 업로드하는 컴포넌트를 만들 것이다.
캡쳐된 화면을 저장하는캔버스를 만드록, 화면을 저장하고,저장된 화면의 URL로 변환해서 저장된 화면을 이미지목록에 추가해준다.
import React, { useRef, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import { ALERT, STATUS } from '../_constants/globalConstants' import Alert from './Alert' function StatusModal() { const userLogin = useSelector(state => state.userLogin) const {userInfo} = userLogin const theme = useSelector(state => state.theme) const [content, setcontent] = useState('') const dispatch = useDispatch() const [Images, setImages] = useState([]) const [stream, setStream] = useState(false) const [tracks, setTracks] = useState('') const videoRef = useRef() const canvasRef = useRef() const handleChangeImages=(e)=>{ const files = [...e.target.files] let newImages= [] let err = '' files.forEach(file=>{ if(!file) return err = "File doesn't exist." if(file.type !== 'image/jpeg' && file.type !=='image/png'){ return err = "Image format is incorrect." } return newImages.push(file) }) if(err) dispatch({type:ALERT, payload:{error:err}}) setImages([...Images, ...newImages]) } const deleteImage=(index)=>{ const newArr = [...Images] newArr.splice(index, 1) setImages(newArr) } const handleStream= () =>{ setStream(true) // navigator.getWebcam = (navigator.getUserMedia || navigator.webKitGetUserMedia || navigator.moxGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia); if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia){ navigator.mediaDevices.getUserMedia({video:true}) .then(mediastream=>{ videoRef.current.srcObject = mediastream videoRef.current.play() const track = mediastream.getTracks() setTracks(track[0]) }).catch(err=>console.log(err)) } // else{ // navigator.getWebcam({video:true}, // function(stream){ // videoRef.current.srcObject = stream // videoRef.current.play() // const track = stream.getTracks() // setTracks(track[0]) // }, function(){ // console.log("Web cam is not accesible.") // }) // } } const handleCapture= () =>{ const width = videoRef.current.clientWidth; const height = videoRef.current.clientHeight; canvasRef.current.setAttribute("width", width) canvasRef.current.setAttribute("height", height) const ctx = canvasRef.current.getContext('2d') ctx.drawImage(videoRef.current, 0, 0, width, height) let URL = canvasRef.current.toDataURL() setImages([...Images, {camera: URL}]) } const handleStopStream= () =>{ tracks.stop() setStream(false) } return ( <div className="status_modal"> <form> <div className="status_header"> <h5 className="m-0">Create Post</h5> <span onClick={()=>dispatch({type:STATUS, payload:false})}>×</span> </div> <div className="status_body"> <textarea name="content" value = {content} placeholder={`${userInfo.user.username}, what are you thinking?`} onChange={(e)=>setcontent(e.target.value)} /> <div className="show_images"> { Images && Images.map((image, index)=>( <div key={index} id="file_img"> <img src={image.camera? image.camera : URL.createObjectURL(image)} alt="images" className="img-thumbnail rounded" style={{filter:theme? 'invert(1)':'inver(0)'}} /> <span onClick={()=>deleteImage(index)}>×</span> </div> )) } </div> { stream && <div className="stream position-relative"> <video autoPlay muted style={{filter:theme? 'invert(1)':'inver(0)'}} ref={videoRef} width='100%' height='100%'></video> <span onClick={handleStopStream}>×</span> <canvas ref={canvasRef} style={{display:'none'}}></canvas> </div> } <div className="input_images"> { stream ? <i className="fas fa-camera" onClick={handleCapture}></i> : <> <i className="fas fa-camera" onClick={handleStream}></i> <div className="file_upload"> <i className="fas fa-image"></i> <input type="file" name="file" id="file_up" multiple accept="image/*" onChange={handleChangeImages}/> </div> </> } </div> </div> <div className="statue_footer"> <button className="btn btn-secondary w-100" type="submit">Post</button> </div> </form> </div> ) } export default StatusModal
만약 카메라가 작동하지 않는다면,
여길 참고해보자.
'NODE.JS' 카테고리의 다른 글
req.body 가 undefined으로 뜰 때 (2) 2021.07.11 Social Media 만들기 - 11)createPost 작성하기 (0) 2021.07.11 Social Media 만들기 - 9) following, followers 보여주기 (0) 2021.07.10 Cast to ObjectId failed for value "" at path "_id" 오류 (0) 2021.07.10 Social Media 만들기 - 8) follow, unfollow 기능 만들기 (0) 2021.07.10