diff --git a/app/MainApp.js b/app/MainApp.js
index 88ab8e230..c541122a4 100644
--- a/app/MainApp.js
+++ b/app/MainApp.js
@@ -50,18 +50,20 @@ async function initState() {
}
}
+ let splashTimeout = setTimeout(() => {
+ closeSplash()
+ showNodeError()
+ }, 30000)
+
try {
$STM_Config.add_notify_site = await checkUpdates()
} catch (err) {
console.error('Cannot check updates', err)
+ clearTimeout(splashTimeout)
+ closeSplash()
alert('Cannot check updates' + err)
}
- let splashTimeout = setTimeout(() => {
- closeSplash()
- showNodeError()
- }, 30000)
-
let onchain
let nodeError = null
try {
diff --git a/app/assets/images/app/linux.png b/app/assets/images/app/linux.png
new file mode 100644
index 000000000..fc1ffd38d
Binary files /dev/null and b/app/assets/images/app/linux.png differ
diff --git a/app/assets/images/app/windows.png b/app/assets/images/app/windows.png
new file mode 100644
index 000000000..193679ffb
Binary files /dev/null and b/app/assets/images/app/windows.png differ
diff --git a/app/components/App.jsx b/app/components/App.jsx
index 51fa84ded..582272a79 100644
--- a/app/components/App.jsx
+++ b/app/components/App.jsx
@@ -12,6 +12,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 URLLoader from 'app/components/elements/app/URLLoader';
import TooltipManager from 'app/components/elements/common/TooltipManager';
import user from 'app/redux/User';
@@ -32,6 +33,8 @@ import { APP_ICON, VEST_TICKER, } from 'app/client_config';
import session from 'app/utils/session'
import { loadGrayHideSettings } from 'app/utils/ContentAccess'
+const APP_REMINDER_INTERVAL = 30*24*60*60*1000
+
const GlobalStyle = createGlobalStyle`
body {
fill: currentColor;
@@ -97,6 +100,16 @@ class App extends React.Component {
}
}
+ 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)
+ }
+
constructor(props) {
super(props)
if (process.env.BROWSER) {
@@ -367,6 +380,8 @@ 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 31428c46c..c898a4044 100644
--- a/app/components/all.scss
+++ b/app/components/all.scss
@@ -39,6 +39,7 @@
@import "./elements/VerticalMenu";
@import "./elements/VotesAndComments";
@import "./elements/Voting";
+@import "./elements/app/AppReminder";
@import "./elements/common/YoutubePlayer/YoutubePlayer";
@import "./elements/common/TelegramPlayer/TelegramPlayer";
@import "./elements/common/Button/index";
diff --git a/app/components/elements/app/AppReminder.jsx b/app/components/elements/app/AppReminder.jsx
new file mode 100644
index 000000000..7043fc288
--- /dev/null
+++ b/app/components/elements/app/AppReminder.jsx
@@ -0,0 +1,53 @@
+import React from 'react'
+import tt from 'counterpart'
+import { connect } from 'react-redux'
+
+import CloseButton from 'react-foundation-components/lib/global/close-button'
+
+import user from 'app/redux/User'
+
+class AppReminder extends React.Component {
+ state = {
+ hidden: false
+ }
+
+ hideMe = () => {
+ const now = Date.now()
+ localStorage.setItem('app_reminder', now)
+ this.setState({
+ hidden: true
+ })
+ }
+
+ showModal = (e) => {
+ e.preventDefault()
+ this.props.showModal()
+ this.hideMe()
+ }
+
+ render() {
+ if (this.state.hidden) {
+ return null
+ }
+ return
+ {
+ e.stopPropagation()
+ this.hideMe()
+ }}
+ />
+ {tt('app_reminder.text')}
+
+ }
+}
+
+export default connect(
+ state => {
+ return {}
+ },
+ dispatch => ({
+ showModal: () => {
+ dispatch(user.actions.showAppDownload())
+ }
+ })
+)(AppReminder)
diff --git a/app/components/elements/app/AppReminder.scss b/app/components/elements/app/AppReminder.scss
new file mode 100644
index 000000000..a704683d9
--- /dev/null
+++ b/app/components/elements/app/AppReminder.scss
@@ -0,0 +1,14 @@
+.AppReminder {
+ background-color: #d0edff !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/app/components/modules/Modals.jsx b/app/components/modules/Modals.jsx
index 781ad920a..de745b5b9 100644
--- a/app/components/modules/Modals.jsx
+++ b/app/components/modules/Modals.jsx
@@ -10,6 +10,7 @@ import Donate from 'app/components/modules/Donate'
import SignUp from 'app/components/modules/SignUp'
import ChangeAccount from 'app/components/modules/ChangeAccount'
import AddAccount from 'app/components/modules/AddAccount'
+import AppDownload from 'app/components/modules/app/AppDownload'
import user from 'app/redux/User';
import tr from 'app/redux/Transaction';
import shouldComponentUpdate from 'app/utils/shouldComponentUpdate';
@@ -25,11 +26,13 @@ class Modals extends React.Component {
show_promote_post_modal: PropTypes.bool,
show_change_account_modal: PropTypes.bool,
show_add_account_modal: PropTypes.bool,
+ show_app_download_modal: PropTypes.bool,
hideLogin: PropTypes.func.isRequired,
hideConfirm: PropTypes.func.isRequired,
hideSignUp: PropTypes.func.isRequired,
hideDonate: PropTypes.func.isRequired,
hidePromotePost: PropTypes.func.isRequired,
+ hideAppDownload: PropTypes.func.isRequired,
notifications: PropTypes.object,
removeNotification: PropTypes.func,
};
@@ -53,12 +56,14 @@ class Modals extends React.Component {
show_signup_modal,
show_change_account_modal,
show_add_account_modal,
+ show_app_download_modal,
hideLogin,
hideDonate,
hideConfirm,
hideSignUp,
hideChangeAccount,
hideAddAccount,
+ hideAppDownload,
notifications,
removeNotification,
} = this.props;
@@ -96,6 +101,10 @@ class Modals extends React.Component {
}
+ {show_app_download_modal &&
+
+
+ }
);
}
@@ -114,6 +123,7 @@ export default connect(
show_signup_modal: state.user.get('show_signup_modal'),
show_change_account_modal: state.user.get('show_change_account_modal'),
show_add_account_modal: state.user.get('show_add_account_modal'),
+ show_app_download_modal: state.user.get('show_app_download_modal'),
notifications: state.app.get('notifications'),
}
},
@@ -146,6 +156,10 @@ export default connect(
if (e) e.preventDefault();
dispatch(user.actions.hideAddAccount())
},
+ hideAppDownload: e => {
+ if (e) e.preventDefault()
+ dispatch(user.actions.hideAppDownload())
+ },
// example: addNotification: ({key, message}) => dispatch({type: 'ADD_NOTIFICATION', payload: {key, message}}),
removeNotification: (key) => dispatch({type: 'REMOVE_NOTIFICATION', payload: {key}}),
diff --git a/app/components/modules/app/AppDownload.jsx b/app/components/modules/app/AppDownload.jsx
new file mode 100644
index 000000000..850c3edae
--- /dev/null
+++ b/app/components/modules/app/AppDownload.jsx
@@ -0,0 +1,26 @@
+import React from 'react'
+import tt from 'counterpart'
+
+class AppDownload extends React.Component {
+ componentDidMount() {
+ }
+
+ render() {
+ const updaterHost = 'https://files.golos.app'
+ const winUrl = new URL('/api/exe/desktop/windows/latest', updaterHost)
+ const linuxUrl = new URL('/api/exe/desktop/linux/latest', updaterHost)
+ return
+ }
+}
+
+export default AppDownload
diff --git a/app/locales/en.json b/app/locales/en.json
index 08223f114..35ef47ad9 100644
--- a/app/locales/en.json
+++ b/app/locales/en.json
@@ -1056,6 +1056,12 @@
"mention_comment": " mentioned you in their comment",
"message": " sent you a private message"
},
+ "app_download": {
+ "title": "Download Golos Desktop"
+ },
+ "app_reminder": {
+ "text": "Install desktop application for Windows or Linux to receive data directly from blockchain"
+ },
"app_goto_url": {
"goto": "Goto",
"wrong_domain_DOMAINS": "This address is not belong to GOLOS Blogs.\nGOLOS Blogs domains are: %(DOMAINS)s\nThis address will be opened in external browser."
diff --git a/app/locales/ru-RU.json b/app/locales/ru-RU.json
index 4a86d6f3d..d0fa3383b 100644
--- a/app/locales/ru-RU.json
+++ b/app/locales/ru-RU.json
@@ -1123,6 +1123,13 @@
"mention_comment": " упомянул вас в комментарии",
"message": " написал вам сообщение"
},
+ "app_download": {
+ "title": "Скачать Golos Desktop",
+ "download_for": "Скачать для"
+ },
+ "app_reminder": {
+ "text": "Установите десктоп-приложение для Windows или Linux и получайте информацию напрямую с блокчейна"
+ },
"app_goto_url": {
"goto": "Перейти",
"wrong_domain_DOMAINS": "Похоже, эта ссылка не с GOLOS Блогов.\nДомены GOLOS Блогов: %(DOMAINS)s\nЭта ссылка будет открыта во внешнем браузере."
diff --git a/app/redux/FetchDataSaga.js b/app/redux/FetchDataSaga.js
index 5b41f058a..5b51a4aaa 100644
--- a/app/redux/FetchDataSaga.js
+++ b/app/redux/FetchDataSaga.js
@@ -540,6 +540,7 @@ export function* fetchData(action) {
args[0].select_authors = [accountname];
} else if (order === 'by_author') {
call_name = 'getDiscussionsByBlogAsync';
+ args[0].filter_tags = args[0].filter_tags.filter(tag => tag !== 'onlyblog')
delete args[0].select_tags;
delete args[0].select_categories;
delete args[0].prefs
diff --git a/app/redux/User.js b/app/redux/User.js
index e93493851..24bf2fa97 100644
--- a/app/redux/User.js
+++ b/app/redux/User.js
@@ -14,6 +14,7 @@ const defaultState = fromJS({
show_open_orders_modal: false,
show_change_account_modal: false,
show_add_account_modal: false,
+ show_app_download_modal: false,
pub_keys_used: null,
locale: DEFAULT_LANGUAGE,
nightmodeEnabled: false,
@@ -86,6 +87,8 @@ export default createModule({
{ action: 'HIDE_CHANGE_ACCOUNT', reducer: state => state.set('show_change_account_modal', false) },
{ action: 'SHOW_ADD_ACCOUNT', reducer: state => state.set('show_add_account_modal', true) },
{ action: 'HIDE_ADD_ACCOUNT', reducer: state => state.set('show_add_account_modal', false) },
+ { action: 'SHOW_APP_DOWNLOAD', reducer: state => state.set('show_app_download_modal', true) },
+ { action: 'HIDE_APP_DOWNLOAD', reducer: state => state.set('show_app_download_modal', false) },
{
action: 'USERNAME_PASSWORD_LOGIN',
reducer: state => state, // saga