diff --git a/.env.development b/.env.development
index 59709599..2c136720 100644
--- a/.env.development
+++ b/.env.development
@@ -1,4 +1,4 @@
-REACT_APP_VERSION=3.21.1-dev
+REACT_APP_VERSION=3.21.2-dev
REACT_APP_SEARCH_API=https://endpoint.d.buzz/api/v1
REACT_APP_SCRAPE_API=https://endpoint.d.buzz/api/v1/meta
REACT_APP_IMAGE_API=https://endpoint.d.buzz/api/v1/imageservice
diff --git a/src/components/layout/SideBarLeft/index.js b/src/components/layout/SideBarLeft/index.js
index 3f0373de..9ef7181c 100644
--- a/src/components/layout/SideBarLeft/index.js
+++ b/src/components/layout/SideBarLeft/index.js
@@ -318,11 +318,11 @@ const SideBarLeft = (props) => {
setOpenLoginModal(false)
}
- const refreshLatestRouteData = () => {
- if(pathname.match(/^\/latest/)){
- setRefreshRouteStatus("latest",timestamp)
- }
- }
+ // const refreshLatestRouteData = () => {
+ // if(pathname.match(/^\/latest/)){
+ // setRefreshRouteStatus("latest",timestamp)
+ // }
+ // }
const refreshTrendingRouteData = () => {
if(pathname.match(/^\/trending/)){
@@ -356,7 +356,8 @@ const SideBarLeft = (props) => {
path: "/latest",
icon: ,
preventDefault: false,
- onClick: refreshLatestRouteData,
+ // onClick: refreshLatestRouteData,
+ onClick: () => window.location.reload(true),
},
{
name: 'Notifications',
diff --git a/src/components/modals/LoginModal/index.js b/src/components/modals/LoginModal/index.js
index 34492b6d..e1acb516 100644
--- a/src/components/modals/LoginModal/index.js
+++ b/src/components/modals/LoginModal/index.js
@@ -10,7 +10,7 @@ import { authenticateUserRequest } from 'store/auth/actions'
import { Spinner } from 'components/elements'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
-import { pending } from 'redux-saga-thunk'
+// import { pending } from 'redux-saga-thunk'
import classNames from 'classnames'
import { hasCompatibleKeychain } from 'services/helper'
import { FaChrome, FaFirefoxBrowser } from 'react-icons/fa'
@@ -100,7 +100,7 @@ const LoginModal = (props) => {
show,
onHide,
authenticateUserRequest,
- loading,
+ // loading,
fromIntentBuzz,
buzzIntentCallback = () => { },
accounts,
@@ -114,15 +114,16 @@ const LoginModal = (props) => {
const [useKeychain, setUseKeychain] = useState(false)
const [hasInstalledKeychain, setHasInstalledKeychain] = useState(false)
const [hasAuthenticationError, setHasAuthenticationError] = useState(false)
+ const [loading, setLoading] = useState(false)
const onChange = (e) => {
const { target } = e
const { name, value } = target
if (name === 'username') {
- setUsername(value.replace("@", ""))
+ setUsername(value.replace(/[@!#$%^&*()+=/\\~`,;:"'_\s]/gi, ''))
} else if (name === 'password') {
- setPassword(value)
+ setPassword(value.replace(/[\s]/gi, ''))
}
setHasAuthenticationError(false)
}
@@ -142,17 +143,24 @@ const LoginModal = (props) => {
}
const handleClickLogin = () => {
+ setLoading(true)
authenticateUserRequest(username, password, useKeychain)
.then(({ is_authenticated }) => {
if (!is_authenticated) {
setHasAuthenticationError(true)
+ setLoading(false)
} else {
if (fromIntentBuzz && buzzIntentCallback) {
buzzIntentCallback()
+ setLoading(false)
}
onHide()
}
})
+ setTimeout(() => {
+ setHasAuthenticationError(true)
+ setLoading(false)
+ }, 10000)
}
const isDisabled = () => {
@@ -322,7 +330,7 @@ const LoginModal = (props) => {
}
const mapStateToProps = (state) => ({
- loading: pending(state, 'AUTHENTICATE_USER_REQUEST'),
+ // loading: pending(state, 'AUTHENTICATE_USER_REQUEST'),
accounts: state.auth.get('accounts'),
user: state.auth.get('user'),
})
diff --git a/src/components/modals/UpdateFormModal/index.js b/src/components/modals/UpdateFormModal/index.js
index 39930d01..d281a123 100644
--- a/src/components/modals/UpdateFormModal/index.js
+++ b/src/components/modals/UpdateFormModal/index.js
@@ -89,7 +89,6 @@ const useStyles = createUseStyles(theme => ({
},
circle: {
strokeLinecap: 'round',
- color: '#e53935',
},
previewContainer: {
width: '100%',
@@ -142,6 +141,26 @@ const useStyles = createUseStyles(theme => ({
actionWrapper: {
width: '100%',
},
+ characterCounter: {
+ position: 'relative',
+ width: '30px',
+ height: '30px',
+ float: 'right',
+ marginTop: 15,
+ marginRight: 10,
+ },
+ counter: {
+ position: 'absolute',
+ fontWeight: 'bold',
+ fontSize: '0.8em',
+ marginRight: 12,
+ color: '#e61c34',
+ width: 'fit-content',
+ left: '50%',
+ top: '50%',
+ transform: 'translate(-52%,-52%)',
+ animation: 'counterAnimation 350ms',
+ },
}))
const UpdateFormModal = (props) => {
@@ -160,8 +179,6 @@ const UpdateFormModal = (props) => {
uploadFileRequest,
} = props
- const CircularProgressStyle = { float: 'right', marginRight: 5, marginTop: 15 }
-
const { username } = user
const inputRef = useRef(null)
const [content, setContent] = useState('')
@@ -176,6 +193,20 @@ const UpdateFormModal = (props) => {
const inputFile = { display: 'none' }
const replyButtonStyle = { width: 85 }
+ const [counterColor, setCounterColor] = useState('#e53935')
+ const CircularProgressStyle = { float: 'right', color: counterColor, transform: content.length >= 260 && 'scale(1.3)' }
+
+
+ useEffect(() => {
+ if(content.length === 280) {
+ setCounterColor('#E0245E')
+ } else if(content.length >= 260) {
+ setCounterColor('#FFAD1F')
+ } else {
+ setCounterColor('#e53935')
+ }
+ }, [content])
+
useEffect(() => {
if(body && body !== '') {
setContent(body)
@@ -229,11 +260,11 @@ const UpdateFormModal = (props) => {
publishUpdateRequest(permlink, content)
.then((success) => {
if(success) {
- broadcastNotification('success', `Post successfully edited`)
+ broadcastNotification('success', `Buzz successfully edited`)
onSuccess(content)
onClose()
} else {
- broadcastNotification('error', `Post failed to edited`)
+ broadcastNotification('error', `Buzz failed to edited`)
}
})
}
@@ -364,15 +395,19 @@ const UpdateFormModal = (props) => {
onClick={handleClickSubmitUpdate}
disabled={loading || `${content}`.trim() === ''}
/>
-
+
+
+ {content.length >= 260 &&
{280 - content.length}
}
+
diff --git a/src/components/pages/Content/index.js b/src/components/pages/Content/index.js
index 21b63709..bb3f0de5 100644
--- a/src/components/pages/Content/index.js
+++ b/src/components/pages/Content/index.js
@@ -21,7 +21,7 @@ import {
} from 'components'
import { bindActionCreators } from 'redux'
import { pending } from 'redux-saga-thunk'
-import { anchorTop, calculatePayout, invokeTwitterIntent, sendToBerries } from 'services/helper'
+import { anchorTop, calculateOverhead, calculatePayout, invokeTwitterIntent, sendToBerries } from 'services/helper'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import Tooltip from '@material-ui/core/Tooltip'
@@ -41,6 +41,7 @@ import {
import Chip from '@material-ui/core/Chip'
import { useHistory } from 'react-router-dom'
import { truncateBody, censorLinks } from 'services/helper'
+import ReportProblemRoundedIcon from '@material-ui/icons/ReportProblemRounded'
const useStyles = createUseStyles(theme => ({
wrapper: {
@@ -130,6 +131,29 @@ const useStyles = createUseStyles(theme => ({
marginTop: 5,
marginBottom: 5,
},
+ invalidBuzz: {
+ width: '100%',
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ color: '#E61C34',
+ fontWeight: 600,
+ fontSize: '1.2em',
+ gap: 20,
+
+ '@media (max-width: 480px)': {
+ textAlign: 'center',
+
+ '& .errorIcon': {
+ fontSize: '8em !important',
+ },
+ },
+
+ '& .errorIcon': {
+ fontSize: '6em !important',
+ },
+ },
}))
const Content = (props) => {
@@ -161,6 +185,8 @@ const Content = (props) => {
const [openVoteList, setOpenVoteList] = useState(false)
const popoverAnchor = useRef(null)
const history = useHistory()
+ const [overhead, setOverhead] = useState(0)
+ const [invalidBuzz, setInvalidBuzz] = useState(false)
const {
@@ -193,6 +219,19 @@ const Content = (props) => {
let hasUpvoted = false
let payout_at = cashout_time
+ useEffect(() => {
+ const overhead = calculateOverhead(content.body)
+ setOverhead(overhead)
+
+ // check for invalid buzz
+ if(!content.body && !loadingContent && !loadingReplies){
+ setInvalidBuzz(true)
+ } else {
+ setInvalidBuzz(false)
+ }
+ // eslint-disable-next-line
+ }, [content.body])
+
useEffect(() => {
checkHasUpdateAuthorityRequest(username)
.then((result) => {
@@ -406,7 +445,7 @@ const Content = (props) => {
- {depth !== 0 && parent_author !== null && !(body.length > 280) && (
+ {depth !== 0 && parent_author !== null && !(content.body.length - overhead > 280) && (
@@ -454,7 +493,7 @@ const Content = (props) => {
- {(`${stripHtml(body)}`.length > 280) && (
+ {(`${stripHtml(content.body)}`.length - overhead > 280) && (
@@ -565,6 +604,12 @@ const Content = (props) => {
onClose={handleClickOnCloseVoteList}
upvoteList={active_votes || []}
/>
+
+ {invalidBuzz && !loadingContent && !loadingReplies &&
+
+
+ Hmm...this page doesn’t exist. Try searching for something else.
+
}
)
}
diff --git a/src/components/sections/CreateBuzzForm/index.js b/src/components/sections/CreateBuzzForm/index.js
index 7654b4dc..b879df47 100644
--- a/src/components/sections/CreateBuzzForm/index.js
+++ b/src/components/sections/CreateBuzzForm/index.js
@@ -414,7 +414,8 @@ const CreateBuzzForm = (props) => {
// getting the draft post value from browser storage
savePostAsDraft(localStorage.getItem('draft_post'))
- setTags(extractAllHashtags(draftPost || content))
+ buzzThreads && setTags(extractAllHashtags(buzzThreads[1].content))
+ // eslint-disable-next-line
}, [content, draftPost, images, savePostAsDraft])
useEffect(() => {
diff --git a/src/components/sections/PostList/index.js b/src/components/sections/PostList/index.js
index 3897db84..39d6dc05 100644
--- a/src/components/sections/PostList/index.js
+++ b/src/components/sections/PostList/index.js
@@ -202,7 +202,7 @@ const PostList = React.memo((props) => {
title = null,
disableProfileLink = false,
disableUserMenu = false,
- disableUpvote = false,
+ // disableUpvote = false,
openUserDialog,
saveScrollIndex,
scrollIndex,
@@ -274,7 +274,6 @@ const PostList = React.memo((props) => {
}
}, [censorList, author, permlink])
-
useEffect(() => {
if(!isMobile) {
if(width >= 676) {
@@ -431,7 +430,7 @@ const PostList = React.memo((props) => {
- {!muted && !hidden && !opacityActivated && disableOpacity && !isMutedUser() && !isAHiddenBuzz() && (
+ {!isAuthor() && !muted && !hidden && !opacityActivated && disableOpacity && !isMutedUser() && !isAHiddenBuzz() && (
@@ -451,7 +450,7 @@ const PostList = React.memo((props) => {
)}
-
+ {!isAuthor &&
+
}
diff --git a/src/components/sections/ReplyList/index.js b/src/components/sections/ReplyList/index.js
index 83208717..7266c3ea 100644
--- a/src/components/sections/ReplyList/index.js
+++ b/src/components/sections/ReplyList/index.js
@@ -20,7 +20,7 @@ import IconButton from '@material-ui/core/IconButton'
import MuteIcon from '@material-ui/icons/VolumeOff'
import Chip from '@material-ui/core/Chip'
import { Link, useHistory } from 'react-router-dom'
-import { truncateBody } from 'services/helper'
+import { calculateOverhead, truncateBody } from 'services/helper'
import stripHtml from 'string-strip-html'
import { censorLinks } from 'services/helper'
@@ -171,6 +171,28 @@ const useStyles = createUseStyles(theme => ({
muteButton: {
float: 'right',
},
+ seeMoreRepliesButton: {
+ display: 'flex',
+ justifyContent: 'center',
+ padding: '15px 0',
+ width: '100%',
+ fontFamily: 'Segoe-Bold',
+ cursor: 'pointer',
+
+ '&:hover': {
+ background: theme.seeMoreReplies.background,
+ },
+
+ '& span': {
+ display: 'flex',
+ alignItems: 'center',
+ width: 'fit-content',
+ padding: '8px 25px',
+ borderRadius: 8,
+ userSelect: 'none',
+ ...theme.seeMoreReplies,
+ },
+ },
}))
const countReplies = async (replies = []) => {
@@ -200,6 +222,7 @@ const ReplyList = (props) => {
const [replyCounter, setReplyCounter] = useState(0)
const [repliesState, setRepliesState] = useState(replies)
const history = useHistory()
+ const [overhead, setOverhead] = useState(0)
useEffect(() => {
countReplies(replies)
@@ -361,6 +384,11 @@ const ReplyList = (props) => {
openCensorshipDialog(author, permlink, censorCallBack)
}
+ useEffect(() => {
+ const overhead = calculateOverhead(reply.body)
+ setOverhead(overhead)
+ }, [reply.body])
+
useEffect(() => {
if(censorList.length !== 0 && author && permlink) {
const result = censorList.filter((item) => `${item.author}/${item.permlink}` === `${author}/${permlink}`)
@@ -382,9 +410,9 @@ const ReplyList = (props) => {
- {replies.length !== 0 && (
+ {/* {replies.length !== 0 && (
- )}
+ )} */}
@@ -412,7 +440,7 @@ const ReplyList = (props) => {
)}
- {`${stripHtml(content)}`.length > 280 && (
+ {`${stripHtml(reply.body)}`.length - overhead > 280 && (
Reply is truncated because it is over 280 characters
@@ -443,11 +471,14 @@ const ReplyList = (props) => {
{replies.length !== 0 && (
-
- {replies.map((reply, index) => (
-
- ))}
-
+ //
+ // {replies.map((reply, index) => (
+ //
+ // ))}
+ //
+
+ view more replies on this...
+
)}
)
@@ -462,7 +493,7 @@ const ReplyList = (props) => {
)}
- {repliesState.map((reply, index) => (
+ {repliesState.slice(0).reverse().map((reply, index) => (
diff --git a/src/services/helper.js b/src/services/helper.js
index de0d435c..898664c0 100644
--- a/src/services/helper.js
+++ b/src/services/helper.js
@@ -11,7 +11,7 @@ const dmp = new diff_match_patch()
export const getUrls = (text) => {
const regexUrls = /(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[/w@?^=%&/~+#-(a-z)(A-Z)(0-9)])?/gm
- return text.match(regexUrls) !== null ? text.match(regexUrls) : []
+ return text?.match(regexUrls) !== null ? text?.match(regexUrls) : []
}
export const anchorTop = () => {
@@ -254,8 +254,27 @@ export const sendToBerries = (author, theme) => {
window.open(`https://buymeberri.es/!dbuzz${color}/@${author}`, '_blank')
}
+export const calculateOverhead = (content) => {
+ let urls = getUrls(content)
+
+ let overhead = 0
+
+ if(urls?.length > 3) {
+ urls = urls?.slice(0, 2)
+ }
+
+ if(urls){
+ urls.forEach((item) => {
+ overhead += item.length
+ })
+ }
+
+ return overhead
+}
+
export const truncateBody = (body) => {
- const bodyLength = `${stripHtml(body)}`.length
+ const overhead = calculateOverhead(body)
+ const bodyLength = `${stripHtml(body)}`.length - overhead
if(bodyLength > 280) {
body = stripHtml(body)
@@ -367,19 +386,3 @@ export const redirectToUserProfile = () => {
window.location = (`/#/@${account[1].replace("#/", "")}`)
}
}
-
-export const calculateOverhead = (content) => {
- let urls = getUrls(content)
-
- let overhead = 0
-
- if(urls.length > 3) {
- urls = urls.slice(0, 2)
- }
-
- urls.forEach((item) => {
- overhead += item.length
- })
-
- return overhead
-}
diff --git a/src/services/theme.js b/src/services/theme.js
index 5f48c378..884a40f1 100644
--- a/src/services/theme.js
+++ b/src/services/theme.js
@@ -168,6 +168,10 @@ const night = {
color: '#172e3f',
highlight: 'rgb(56 68 77 / 31%)',
},
+ seeMoreReplies: {
+ background: '#192734',
+ color: '#ffffff',
+ },
}
const light = {
@@ -329,6 +333,10 @@ const light = {
},
},
skeleton: { },
+ seeMoreReplies: {
+ background: '#F5F8FA',
+ color: '#778694',
+ },
}
const gray = {
@@ -500,6 +508,10 @@ const gray = {
color: '#2f3136',
highlight: '#36393fed',
},
+ seeMoreReplies: {
+ background: '#282A2D',
+ color: '#ffffff',
+ },
}
export const getTheme = (mode) => {