Skip to content

Commit

Permalink
Refactor AppReminder to NewsPopup (golos_news)
Browse files Browse the repository at this point in the history
  • Loading branch information
1aerostorm committed Jul 30, 2024
1 parent 8553fc3 commit 47d5c9e
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 18 deletions.
18 changes: 2 additions & 16 deletions app/components/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { createGlobalStyle } from 'styled-components';
import AppPropTypes from 'app/utils/AppPropTypes';
import Header from 'app/components/modules/Header';
import Footer from 'app/components/modules/Footer';
import AppReminder from 'app/components/elements/app/AppReminder'
import NewsPopups from 'app/components/elements/NewsPopups'
import URLLoader from 'app/components/elements/app/URLLoader';
import TooltipManager from 'app/components/elements/common/TooltipManager';
import user from 'app/redux/User';
Expand All @@ -32,8 +32,6 @@ import { APP_ICON, VEST_TICKER, } from 'app/client_config';
import session from 'app/utils/session'
import libInfo from 'app/JsLibHash.json'

const APP_REMINDER_INTERVAL = 60*24*60*60*1000

const GlobalStyle = createGlobalStyle`
body {
fill: currentColor;
Expand Down Expand Up @@ -80,16 +78,6 @@ class App extends React.Component {
);
}

showAppReminder = () => {
if (process.env.IS_APP) {
return
}
const now = Date.now()
let reminded = localStorage.getItem('app_reminder') || 0
reminded = parseInt(reminded)
return !reminded || (now - reminded > APP_REMINDER_INTERVAL)
}

constructor(props) {
super(props)
}
Expand Down Expand Up @@ -296,8 +284,6 @@ class App extends React.Component {
const noHeader = isApp
const noFooter = isApp || location.pathname.startsWith('/submit')

const reminder = this.showAppReminder() ? <AppReminder /> : null

return (
<div
className={
Expand All @@ -319,7 +305,7 @@ class App extends React.Component {
<ChainFailure />
{children}
{noFooter ? null : <Footer />}
{reminder}
<NewsPopups />
<ScrollButton />
</div>
<Dialogs />
Expand Down
2 changes: 1 addition & 1 deletion app/components/all.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
@import "./elements/Userpic";
@import "./elements/VerticalMenu";
@import "./elements/WitnessSettings";
@import "./elements/app/AppReminder";
@import "./elements/NewsPopups";
@import "./elements/common/Button/index";
@import "./elements/common/Input/index";
@import "./elements/common/RadioButton/index";
Expand Down
199 changes: 199 additions & 0 deletions app/components/elements/NewsPopups.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import React from 'react'
import tt from 'counterpart'
import { connect } from 'react-redux'
import { api } from 'golos-lib-js'

import CloseButton from 'react-foundation-components/lib/global/close-button'

import user from 'app/redux/User'

const APP_REMINDER_INTERVAL = 60*24*60*60*1000

const MAX_NEWS_PER_TIME = 2

const shuffleArray = (arr) => {
arr.sort(() => 0.5 - Math.random())
}

class NewsPopups extends React.Component {
state = {
hidden: false,
hiddenNews: []
}

checkNews = async () => {
if (typeof(localStorage) === 'undefined') {
this.setState({ news: [] })
return
}
try {
let news_read = localStorage.getItem('news_read_wlt') || ''
news_read = news_read.split(',')
const { golos_news: { accounts } } = $STM_Config
if (accounts) {
let news_to_load = []
for (const [acc, opts] of Object.entries(accounts)) {
if (!opts) continue

let entries = await api.getBlogEntriesAsync(acc, 0, 5, ['fm-'], {})
shuffleArray(entries)

let count = 0
for (const post of entries) {
const { author, hashlink, reblog_on } = post
if (reblog_on.startsWith('19')) continue

if (news_read.includes(hashlink) || count > 0) {
continue
}
++count
news_to_load.push({
author,
hashlink
})
}

if (news_to_load.length > MAX_NEWS_PER_TIME) {
shuffleArray(news_to_load)
news_to_load = news_to_load.slice(0, MAX_NEWS_PER_TIME)
}
}
if (news_to_load.length) {
const news = await api.getContentPreviewsAsync(news_to_load)
this.setState({
news
})
return
}
}
this.setState({
news: []
})
} catch (err) {
console.error('NewsPopups', err)
this.setState({
news: []
})
}
}

componentDidMount() {
this.checkNews()
}

hideMe = (i) => {
if (i) {
let { hiddenNews } = this.state
hiddenNews = [...hiddenNews]
hiddenNews.push(i)
this.setState({
hiddenNews
})
let news_read = localStorage.getItem('news_read_wlt') || ''
news_read = news_read.split(',')
news_read.push(i)
localStorage.setItem('news_read_wlt', news_read.join(','))
return
}
const now = Date.now()
localStorage.setItem('app_reminder', now)
this.setState({
hidden: true
})
}

openNew = (e, i, url) => {
e.preventDefault()
this.hideMe(i)
window.open(url, '_blank')
}

showModal = (e) => {
e.preventDefault()
this.props.showModal()
this.hideMe()
}

showAppReminder = () => {
if (process.env.IS_APP || typeof(localStorage) === 'undefined') {
return false
}
const now = Date.now()
let reminded = localStorage.getItem('app_reminder') || 0
reminded = parseInt(reminded)
return !reminded || (now - reminded > APP_REMINDER_INTERVAL)
}

render() {
const { news,hiddenNews } = this.state

let appReminder = null
if (news && this.showAppReminder() && !this.state.hidden) {
appReminder = <span className='NewsPopups callout primary' onClick={this.showModal}>
<CloseButton
onClick={(e) => {
e.stopPropagation()
this.hideMe()
}}
/>
{tt('app_reminder.text')}
</span>
}

let newItems = []
if (news) {
let newCount = 0
for (const ne of news) {
if (hiddenNews.includes(ne.hashlink)) {
continue
}
newCount++
}
newCount -= 1
for (const ne of news) {
if (hiddenNews.includes(ne.hashlink)) {
continue
}
let title = ne.title
if (title.length > 100) {
title = title.substring(0, 100) + '...'
}
let bottom = newCount * 65
if (appReminder) {
bottom += 65
} else {
bottom += 2
}
newItems.push(<a key={ne.hashlink} href={ne.url} onClick={e => this.openNew(e, ne.hashlink, ne.url)} target='_blank' rel='noopener noreferrer nofollow'>
<span style={{ bottom: bottom + 'px' }} className='NewsPopups callout primary'>
<CloseButton
onClick={(e) => {
e.stopPropagation()
e.preventDefault()
this.hideMe(ne.hashlink)
}}
/>
{title}
</span>
</a>)
--newCount
}
}

return <div>
{appReminder}
{newItems}
</div>
}
}

export default connect(
state => {
return {}
},
dispatch => ({
showModal: () => {
dispatch(user.actions.showAppDownload())
}
})
)(NewsPopups)
16 changes: 16 additions & 0 deletions app/components/elements/NewsPopups.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.NewsPopups {
@include themify($themes) {
background-color: themed('modalReminder') !important;
}
color: #333;
border-radius: 5px;
position: fixed;
left: 20px;
bottom: 1px;
padding-right: 5rem;
cursor: pointer;

.close-button {
margin-top: 4px;
}
}
8 changes: 7 additions & 1 deletion config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@
"host": "https://devapi-dex.golos.app",
"host_local": "https://devapi-dex.golos.app"
},
"golos_news": {
"accounts": {
"progolos": true,
"ecurrex-ru": true
}
},
"hidden_assets": {
"RUDEX": true,
"PRIZM": true,
Expand All @@ -61,4 +67,4 @@
"YMWMZ": true,
"YMBTC": true
}
}
}
3 changes: 3 additions & 0 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ global.$STM_Config = {
notify_service: config.get('notify_service'),
messenger_service: config.get('messenger_service'),
apidex_service: config.get('apidex_service'),
golos_news: config.has('golos_news') ? config.get('golos_news') : {
accounts: {}
},
blogs_service: config.get('blogs_service'),
hidden_assets: config.get('hidden_assets'),
ui_version: version || '1.0-unknown',
Expand Down

0 comments on commit 47d5c9e

Please sign in to comment.