From 47d5c9e032b563debf89623c5ec789f696f4024a Mon Sep 17 00:00:00 2001 From: 1aerostorm Date: Tue, 30 Jul 2024 20:26:08 +0300 Subject: [PATCH] Refactor AppReminder to NewsPopup (golos_news) --- app/components/App.jsx | 18 +-- app/components/all.scss | 2 +- app/components/elements/NewsPopups.jsx | 199 ++++++++++++++++++++++++ app/components/elements/NewsPopups.scss | 16 ++ config/default.json | 8 +- server/index.js | 3 + 6 files changed, 228 insertions(+), 18 deletions(-) create mode 100644 app/components/elements/NewsPopups.jsx create mode 100644 app/components/elements/NewsPopups.scss diff --git a/app/components/App.jsx b/app/components/App.jsx index 2393581..efefe5c 100644 --- a/app/components/App.jsx +++ b/app/components/App.jsx @@ -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'; @@ -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; @@ -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) } @@ -296,8 +284,6 @@ class App extends React.Component { const noHeader = isApp const noFooter = isApp || location.pathname.startsWith('/submit') - const reminder = this.showAppReminder() ? : null - return (
{children} {noFooter ? null :
} - {reminder} +
diff --git a/app/components/all.scss b/app/components/all.scss index cd47ce9..2f6d124 100644 --- a/app/components/all.scss +++ b/app/components/all.scss @@ -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"; diff --git a/app/components/elements/NewsPopups.jsx b/app/components/elements/NewsPopups.jsx new file mode 100644 index 0000000..9896233 --- /dev/null +++ b/app/components/elements/NewsPopups.jsx @@ -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 = + { + e.stopPropagation() + this.hideMe() + }} + /> + {tt('app_reminder.text')} + + } + + 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( this.openNew(e, ne.hashlink, ne.url)} target='_blank' rel='noopener noreferrer nofollow'> + + { + e.stopPropagation() + e.preventDefault() + this.hideMe(ne.hashlink) + }} + /> + {title} + + ) + --newCount + } + } + + return
+ {appReminder} + {newItems} +
+ } +} + +export default connect( + state => { + return {} + }, + dispatch => ({ + showModal: () => { + dispatch(user.actions.showAppDownload()) + } + }) +)(NewsPopups) diff --git a/app/components/elements/NewsPopups.scss b/app/components/elements/NewsPopups.scss new file mode 100644 index 0000000..fe5c9b2 --- /dev/null +++ b/app/components/elements/NewsPopups.scss @@ -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; + } +} diff --git a/config/default.json b/config/default.json index 52465c1..f8e97eb 100644 --- a/config/default.json +++ b/config/default.json @@ -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, @@ -61,4 +67,4 @@ "YMWMZ": true, "YMBTC": true } -} +} \ No newline at end of file diff --git a/server/index.js b/server/index.js index 2cf3ef4..d701d68 100755 --- a/server/index.js +++ b/server/index.js @@ -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',