Introduction to the
NextWebChat based on next.js+ React +redux+ ANTd + RScroll and other technologies to develop web version of the chat instance. Next. Js + React emulates wechat’s webchat interface
You can drag and drop pictures to the chat area to send and paste screenshots to send.
Technology stack
- Js + React +Rredux
- UI component library: Antd (Ant Financial React Component Library)
- Font icon: Ali Iconfont icon library
- Popup component: RLayer (React custom dialog)
- Scroll bar component: RScroll (react custom scroll bar)
Get a quick look at next.js
An SSR development framework based on React.js server rendering. Next.js presets various configurations needed to develop server-side rendered applications using react.js. Give your web pages SEO features.
Next: nextjs.org/
Next Chinese website: www.nextjs.cn/
Github address: github.com/vercel/next…
React.js custom scroll bar RScroll
The scroll bar used in this project is based on the React custom beautification scroll bar _rscroll.js_ component.
Rscroll supports native scrolling, automatic hiding of scroll bars, size and color.
React.js custom RLayer dialog box
All dialogs used in the project are based on the React custom popup _rlayer.js_ component.
Rscroll is a lightweight PC desktop pop-up component developed based on react. Supports free configuration of more than **30+** parameters.
You can check out this previous sharing post.
Based on the React. Js web page version of the popup window | React PC components RLayer custom dialog
Common layout template
The Head component configures page information, such as title, keyword, description, and icon.
Function Layout(props) {const router = useRouter() useEffect(() => {//... }, []) return (<> {/* config public head info */} < head > <title>Next. Js chat room </title> <link rel="icon" href="/favicon.ico" /> <meta Name = "keywords" content = "Next. Js | React. Js | Next. | js chat room Next. Js imitation WeChat | React chat instance" > < / meta > < meta name = "description" </meta> </Head> <div className="next__container flexbox flex-alignc flex-justifyc"> <div className={utils.classNames('next__wrapper')} style={{ backgroundImage: ` url (${props. Skin}) `}} > < div className = "next__board flexbox" > {/ * button on the top right corner * /} < WinBar {... Props} /> {/* Sidebar */} <Sidebar {... <div className="nt__mainbox flex1 flexbox flex-col"> {props. Children} </div> </div> </div> </div> </> ) }Copy the code
Chat module
The editor supports the functions of inserting emoticons at the cursor, pasting screenshots and sending pictures by dragging and dropping.
Return (<div ref={editorRef} className="editor" contenteditable ="true") dangerouslySetInnerHTML={{__html: state.editorText}} onClick={handleClicked} onInput={handleInput} onFocus={handleFocus} onBlur={handleBlur} style={{userSelect: 'text', WebkitUserSelect: 'text'}}> </div> ) handlePlayVideo = (item, e) => { rlayer({ content: ( <div className="flexbox flex-col" style={{height: '100%'}}> <div className="ntDrag__head">< I className="iconfont icon-bofang"></ I > Video preview </div> <div className="ntMain__cont Flex1 flexflex "> {/* video */} <video className="vplayer" SRC ={item.videosrc} poster={item.imgsrc} autoPlay preload="auto" controls x5-video-player-fullscreen="true" webkit-playsinline="true" x-webkit-airplay="true" playsInline x5-playsinline="true" style={{height: '100%', width: '100%', objectFit: 'contain', outline: 'none'}} /> </div> </div> ), layerStyle: {background: '#f6f5ef'}, opacity: .2, area: ['550px', '450px'], drag: '.ntDrag__head', resize: true, maximize: true, }) } handleDragEnter = (e) => { e.stopPropagation() e.preventDefault() } handleDragOver = (e) => { e.stopPropagation() e.preventDefault() } handleDrop = (e) => { e.stopPropagation() e.preventDefault() console.log(e.dataTransfer) HandleFileList = (filelist) => {let files = filelist.files If (files.length >= 2) {rlayer.message({icon: 'error', content: 'drag') return false} for(let I = 0; i < files.length; i++) { if(files[i].type ! = '') { this.handleFileAdd(files[i]) }else { rlayer.message({icon: 'error', content: })}} handleFileAdd = (file) => {if(file.type.indexof ('image') == -1) {rlayer.message({icon: 'error', content: })}else {let reader = new FileReader() readAsDataURL(file) reader.onload = function() {let img = function() this.result console.log(img) } } }Copy the code
Edit boxes listen for paste paste events.
@time Andy by 2020-12 * @about Q: 282310962 wx: xy190310 */ import { useState, useRef, forwardRef, useEffect, useImperativeHandle } from 'react' const Editor = forwardRef(({value, onInput, onFocus, onBlur, onPaste}, Ref) => {const [state, setState] = useState({editorText: value, // record last cursor position lastRange: Null}) const editorRef = useRef() useEffect() => {// Editor paste event if(! editorRef.current) return editorRef.current.addEventListener('paste', function(e) { let cbd = e.clipboardData let ua = window.navigator.userAgent if(! (e.clipboardData && e.clipboardData.items)) return if(cbd.items && cbd.items.length === 2 && cbd.items[0].kind === "string" && cbd.items[1].kind === "file" && cbd.types && cbd.types.length === 2 && cbd.types[0] === "text/plain" && cbd.types[1] === "Files" && ua.match(/Macintosh/i) && Number(ua.match(/Chrome\/(\d{2})/i)[1]) < 49){ return; } for(var i = 0; i < cbd.items.length; i++) { var item = cbd.items[i] // console.log(item) // console.log(item.kind) if(item.kind == 'file') { var blob = Var reader = new FileReader() reader.readasdataurl (blob) var reader = new FileReader() readAsDataURL(blob) Reader.onload = function() {var _img = this.result typeof onPaste == 'function' && onPaste(_img)}}}}) } []) / /... }) export default EditorCopy the code
Well, that’s it for the next-js chat introduction. Thank you for reading ~~✍
Finally, a nuxt.js project is attached
Nuxt + Vue chat room | | Nuxt imitation WeChat App interface Nuxt. Js chat instance