From ec0551528d09ab35345aba254d5ce9cd8f04f1ab Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Sat, 19 Nov 2022 23:57:21 +0300 Subject: qs -> URLSearchParams --- vnext/package-lock.json | 1 - vnext/package.json | 1 - vnext/src/App.js | 31 ++++++++++++++++--------------- vnext/src/ui/Feeds.js | 28 ++++++++++++---------------- vnext/src/ui/Post.js | 6 ++---- 5 files changed, 30 insertions(+), 37 deletions(-) diff --git a/vnext/package-lock.json b/vnext/package-lock.json index 8257642c..a22ec1d5 100644 --- a/vnext/package-lock.json +++ b/vnext/package-lock.json @@ -22,7 +22,6 @@ "ignore-styles": "^5.0.1", "mailparser": "^3.5.0", "node-pushnotifications": "^2.0.3", - "qs": "^6.11.0", "react": "18.2.0", "react-content-loader": "^6.2.0", "react-cookie": "^4.1.1", diff --git a/vnext/package.json b/vnext/package.json index 2582edf2..6b94ae87 100644 --- a/vnext/package.json +++ b/vnext/package.json @@ -62,7 +62,6 @@ "ignore-styles": "^5.0.1", "mailparser": "^3.5.0", "node-pushnotifications": "^2.0.3", - "qs": "^6.11.0", "react": "18.2.0", "react-content-loader": "^6.2.0", "react-cookie": "^4.1.1", diff --git a/vnext/src/App.js b/vnext/src/App.js index 813fd263..bcd2b169 100644 --- a/vnext/src/App.js +++ b/vnext/src/App.js @@ -1,6 +1,5 @@ -import { useState, useEffect, useRef, Fragment } from 'react'; -import { Route, Link, Routes } from 'react-router-dom'; -import qs from 'qs'; +import { useState, useEffect, useRef, Fragment, useCallback } from 'react'; +import { Route, Link, Routes, useSearchParams } from 'react-router-dom'; import svg4everybody from 'svg4everybody'; @@ -36,22 +35,23 @@ export default function App({ footer }) { const [visitor, setVisitor] = useVisitor(); + const params = useSearchParams(); + useEffect(() => { svg4everybody(); - let params = qs.parse(window.location.search.substring(1)); - if (params.hash) { - setCookie('hash', params.hash, { path: '/' }); - let retpath = params.retpath || `${window.location.protocol}//${window.location.host}${window.location.pathname}`; + if (params['hash']) { + setCookie('hash', params['hash'], { path: '/' }); + let retpath = params['retpath'] || `${window.location.protocol}//${window.location.host}${window.location.pathname}`; window.history.replaceState({}, document.title, retpath); } - }, [setCookie, footer]); + }, [setCookie, footer, params]); - let updateStatus = () => { + let updateStatus = useCallback(() => { // refresh server visitor state (unread counters) me().then(visitor => { setVisitor(visitor); }).catch(console.error); - }; + }, [setVisitor]); const [hash, setHash] = useState(cookie.hash); @@ -66,8 +66,9 @@ export default function App({ footer }) { me().then(visitor => auth(visitor)) .catch(() => setVisitor(anonymousUser)); if ('EventSource' in window) { - const eventParams = { hash: hash }; - let url = new URL(`https://juick.com/api/events?${qs.stringify(eventParams)}`); + const eventParams = new URLSearchParams({ hash: hash }); + let url = new URL(`https://juick.com/api/events?${eventParams.toString()}`); + console.log(url.toString()); es = new EventSource(url.toString()); es.onopen = () => { console.log('online'); @@ -89,7 +90,7 @@ export default function App({ footer }) { es.removeEventListener('msg', updateStatus); } }); - }, [hash]); + }, [hash, setVisitor, updateStatus]); useEffect(() => { const getTrends = async () => { @@ -101,14 +102,14 @@ export default function App({ footer }) { /** * @param {import("./api").SecureUser} visitor */ - let auth = (visitor) => { + let auth = useCallback((visitor) => { setVisitor(prevState => { if (visitor.hash != prevState.hash) { setHash(visitor.hash); } return visitor; }); - }; + }, [setVisitor]); return ( <>
diff --git a/vnext/src/ui/Feeds.js b/vnext/src/ui/Feeds.js index 2019dffd..bd69155f 100644 --- a/vnext/src/ui/Feeds.js +++ b/vnext/src/ui/Feeds.js @@ -1,7 +1,6 @@ import { useState, useEffect } from 'react'; -import { Link, useLocation, useParams, Navigate } from 'react-router-dom'; +import { Link, useLocation, useParams, Navigate, useSearchParams } from 'react-router-dom'; -import qs from 'qs'; import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; dayjs.extend(utc); @@ -46,8 +45,7 @@ function RequireAuth({ children }) { * */ export function Discover() { - const location = useLocation(); - let search = qs.parse(location.search.substring(1)); + const search = useSearchParams(); const query = { baseUrl: '/api/messages', search: search, @@ -86,9 +84,9 @@ export function Discussions() { */ export function Blog() { const { user } = useParams(); - const location = useLocation(); + const params = useSearchParams(); const search = { - ...qs.parse(location.search.substring(1)), + ...params, uname: user }; const query = { @@ -169,24 +167,22 @@ function Feed({ query }) { tag: '' }); const [loading, setLoading] = useState(true); + const filter = useSearchParams(); useEffect(() => { setLoading(true); - const filter = location.search.substring(1); - let getPageParam = (pageParam, lastMessage, filterParams) => { + let getPageParam = (pageParam, lastMessage, /** @type { URLSearchParams } */ filterParams) => { const pageValue = pageParam === 'before_mid' ? lastMessage.mid : pageParam === 'page' ? (Number(filterParams.page) || 0) + 1 : dayjs.utc(lastMessage.updated).valueOf(); - let newFilter = { ...filterParams }; - newFilter[pageParam] = pageValue; - return `?${qs.stringify(newFilter)}`; + filterParams[pageParam] = pageValue; + return `?${filterParams.toString()}`; }; - const filterParams = qs.parse(filter); - let params = Object.assign({}, filterParams || {}, query.search || {}); + let params = { ...Object.fromEntries(filter), ...query.search }; let url = query.baseUrl; getMessages(url, params) .then(response => { const { data } = response; const { pageParam } = query; const lastMessage = data.slice(-1)[0] || {}; - const nextpage = getPageParam(pageParam, lastMessage, filterParams); + const nextpage = getPageParam(pageParam, lastMessage, new URLSearchParams(params)); document.body.scrollTop = 0; document.documentElement.scrollTop = 0; setState((prevState) => { @@ -194,7 +190,7 @@ function Feed({ query }) { ...prevState, msgs: data, nextpage: nextpage, - tag: qs.parse(location.search.substring(1))['tag'] || '' + tag: filter['tag'] || '' }; }); setLoading(false); @@ -206,7 +202,7 @@ function Feed({ query }) { }; }); }); - }, [location.search, query]); + }, [location.search, query, filter]); return (state.msgs.length > 0 ? (
{ diff --git a/vnext/src/ui/Post.js b/vnext/src/ui/Post.js index fbd55675..74b74ffc 100644 --- a/vnext/src/ui/Post.js +++ b/vnext/src/ui/Post.js @@ -1,7 +1,5 @@ import { useState } from 'react'; -import { useLocation, useNavigate } from 'react-router-dom'; - -import qs from 'qs'; +import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'; import Button from './Button'; import MessageInput from './MessageInput'; @@ -19,7 +17,7 @@ export default function Post() { const [visitor] = useVisitor(); let draftMessage = (location.state || {}).data || {}; let [draft, setDraft] = useState(draftMessage.body); - let params = qs.parse(window.location.search.substring(1)); + let params = useSearchParams(); let postMessage = (template) => { const { attach, body } = template; const postAction = draftMessage.mid ? update(draftMessage.mid, 0, body) : post(body, attach); -- cgit v1.2.3