diff --git a/electron.js b/electron.js
index 3261d669da..bc31ef8897 100644
--- a/electron.js
+++ b/electron.js
@@ -200,6 +200,10 @@ function createWindow () {
ipcMain.on('exit', (e, relaunch) => {
exit(relaunch);
});
+
+ ipcMain.on('update', (e) => {
+ checkUpdate();
+ });
ipcMain.on('urlOpen', async (e, url) => {
shell.openExternal(url).catch((error) => {
diff --git a/src/json/error.json b/src/json/error.json
index 9e09688bad..b59c2677a3 100644
--- a/src/json/error.json
+++ b/src/json/error.json
@@ -1,5 +1,10 @@
{
"AccountCreate": {
"900": "Invite code is invalid"
+ },
+
+ "Code": {
+ "ANYTYPE_NEEDS_UPGRADE": 10,
+ "ANOTHER_ANYTYPE_PROCESS_IS_RUNNING": 108
}
}
\ No newline at end of file
diff --git a/src/json/text.json b/src/json/text.json
index ee01f9efdc..f272114ca7 100644
--- a/src/json/text.json
+++ b/src/json/text.json
@@ -1,6 +1,8 @@
{
"progress0": { "en": "Copying files %s/%s" },
+ "confirmUpdateText": { "en": "Anytype needs upgrade
Your account contains the data created with a newer version of anytype.
Please upgrade to the latest version via the built-in update mechanism." },
+
"authInviteTitle": { "en": "Welcome to Anytype" },
"authInviteLabel": { "en": "Enter your invitation code. If you don't have one just go to anytype.io and sign up to the waiting list. We are inviting people on the rolling bases." },
"authInvitePlaceholder": { "en": "Code" },
diff --git a/src/scss/popup/confirm.scss b/src/scss/popup/confirm.scss
new file mode 100644
index 0000000000..2992851d4f
--- /dev/null
+++ b/src/scss/popup/confirm.scss
@@ -0,0 +1,10 @@
+@import "~scss/_vars";
+
+.popups {
+ .popup.popupConfirm {
+ .innerWrap { width: 448px; padding: 16px; }
+ .label { margin-bottom: 16px; }
+ .button { height: 32px; line-height: 32px; margin-right: 10px; }
+ .button.last-child { margin: 0px; }
+ }
+}
\ No newline at end of file
diff --git a/src/ts/app.tsx b/src/ts/app.tsx
index bc1da6e04b..b7eab108c5 100644
--- a/src/ts/app.tsx
+++ b/src/ts/app.tsx
@@ -71,6 +71,7 @@ import 'scss/popup/prompt.scss';
import 'scss/popup/preview.scss';
import 'scss/popup/new.scss';
import 'scss/popup/feedback.scss';
+import 'scss/popup/confirm.scss';
import 'scss/popup/editor/page.scss';
import 'emoji-mart/css/emoji-mart.css';
diff --git a/src/ts/component/editor/page.tsx b/src/ts/component/editor/page.tsx
index eabdd739ad..c0a64dd62a 100644
--- a/src/ts/component/editor/page.tsx
+++ b/src/ts/component/editor/page.tsx
@@ -21,6 +21,7 @@ interface State {
const { ipcRenderer } = window.require('electron');
const Constant = require('json/constant.json');
+const Errors = require('json/error.json');
const $ = require('jquery');
const THROTTLE = 20;
@@ -141,13 +142,10 @@ class EditorPage extends React.Component {
componentDidMount () {
this._isMounted = true;
-
- const { rootId } = this.props;
const win = $(window);
keyboard.disableBack(true);
this.unbind();
-
this.open();
win.on('mousemove.editor', throttle((e: any) => { this.onMouseMove(e); }, THROTTLE));
@@ -238,7 +236,13 @@ class EditorPage extends React.Component {
C.BlockOpen(this.id, (message: any) => {
if (message.error.code) {
- history.push('/main/index');
+ if (message.error.code == Errors.Code.ANYTYPE_NEEDS_UPGRADE) {
+ Util.onErrorUpdate(() => {
+ history.push('/main/index');
+ });
+ } else {
+ history.push('/main/index');
+ };
return;
};
diff --git a/src/ts/component/page/auth/setup.tsx b/src/ts/component/page/auth/setup.tsx
index b7a590b060..b7ebeefcd0 100644
--- a/src/ts/component/page/auth/setup.tsx
+++ b/src/ts/component/page/auth/setup.tsx
@@ -140,7 +140,6 @@ class PageAuthSetup extends React.Component {
C.AccountCreate(authStore.name, authStore.icon, authStore.code, (message: any) => {
if (message.error.code) {
const error = Errors.AccountCreate[message.error.code] || message.error.description;
-
this.setError(error);
} else
if (message.account) {
diff --git a/src/ts/component/popup/archive.tsx b/src/ts/component/popup/archive.tsx
index af6c38f9d8..11862bf9a0 100644
--- a/src/ts/component/popup/archive.tsx
+++ b/src/ts/component/popup/archive.tsx
@@ -1,8 +1,8 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Icon, Title, Smile, Loader } from 'ts/component';
-import { I, C } from 'ts/lib';
-import { commonStore, blockStore } from 'ts/store';
+import { I, C, Util } from 'ts/lib';
+import { blockStore } from 'ts/store';
import { observer } from 'mobx-react';
interface Props extends I.Popup {
@@ -14,6 +14,7 @@ interface State {
};
const $ = require('jquery');
+const Errors = require('json/error.json');
@observer
class PopupArchive extends React.Component {
@@ -80,6 +81,9 @@ class PopupArchive extends React.Component {
this.setState({ loading: true });
C.BlockOpen(archive, (message: any) => {
+ if (message.error.code == Errors.Code.ANYTYPE_NEEDS_UPGRADE) {
+ Util.onErrorUpdate();
+ };
this.setState({ loading: false });
});
diff --git a/src/ts/component/popup/confirm.tsx b/src/ts/component/popup/confirm.tsx
new file mode 100644
index 0000000000..69651f9ae1
--- /dev/null
+++ b/src/ts/component/popup/confirm.tsx
@@ -0,0 +1,51 @@
+import * as React from 'react';
+import { Label, Button } from 'ts/component';
+import { I } from 'ts/lib';
+import { observer } from 'mobx-react';
+
+interface Props extends I.Popup {};
+
+@observer
+class PopupConfirm extends React.Component {
+
+ constructor(props: any) {
+ super(props);
+
+ this.onConfirm = this.onConfirm.bind(this);
+ this.onCancel = this.onCancel.bind(this);
+ };
+
+ render() {
+ const { param } = this.props;
+ const { data } = param;
+ const { text } = data;
+
+ return (
+
+
+
+
+
+ );
+ };
+
+ onConfirm (e: any) {
+ const { id, param } = this.props;
+ const { data } = param;
+ const { onConfirm } = data;
+
+ e.preventDefault();
+ this.props.close();
+
+ if (onConfirm) {
+ onConfirm();
+ };
+ };
+
+ onCancel (e: any) {
+ this.props.close();
+ };
+
+};
+
+export default PopupConfirm;
\ No newline at end of file
diff --git a/src/ts/component/popup/index.tsx b/src/ts/component/popup/index.tsx
index 68424da5c8..36f9b8d732 100644
--- a/src/ts/component/popup/index.tsx
+++ b/src/ts/component/popup/index.tsx
@@ -12,6 +12,7 @@ import PopupPrompt from './prompt';
import PopupPreview from './preview';
import PopupEditorPage from './editor/page';
import PopupFeedback from './feedback';
+import PopupConfirm from './confirm';
interface Props extends I.Popup {
history: any;
@@ -38,6 +39,7 @@ class Popup extends React.Component {
settings: PopupSettings,
archive: PopupArchive,
navigation: PopupNavigation,
+ confirm: PopupConfirm,
prompt: PopupPrompt,
new: PopupNew,
preview: PopupPreview,
diff --git a/src/ts/component/popup/prompt.tsx b/src/ts/component/popup/prompt.tsx
index 34f7b94123..712ebdfdac 100644
--- a/src/ts/component/popup/prompt.tsx
+++ b/src/ts/component/popup/prompt.tsx
@@ -49,7 +49,7 @@ class PopupPrompt extends React.Component {
const { onChange } = data;
e.preventDefault();
- commonStore.popupClose(id);
+ this.props.close();
if (onChange) {
onChange(this.refValue.getValue());
diff --git a/src/ts/lib/command.tsx b/src/ts/lib/command.tsx
index f332fe28b5..0e7ae33c79 100644
--- a/src/ts/lib/command.tsx
+++ b/src/ts/lib/command.tsx
@@ -1,9 +1,10 @@
-import { I, M, Util, Mark, dispatcher, Encode, Mapper } from 'ts/lib';
-import { blockStore } from 'ts/store';
+import { I, Util, Mark, dispatcher, Encode, Mapper } from 'ts/lib';
+import { commonStore } from 'ts/store';
-const Constant = require('json/constant.json');
+const Errors = require('json/error.json');
const Commands = require('lib/pb/protos/commands_pb');
const Model = require('lib/vendor/github.com/anytypeio/go-anytype-library/pb/model/protos/models_pb.js');
+const { ipcRenderer } = window.require('electron');
const Rpc = Commands.Rpc;
const VersionGet = (callBack?: (message: any) => void) => {
diff --git a/src/ts/lib/datautil.tsx b/src/ts/lib/datautil.tsx
index 794ebcbc24..655548cd0a 100644
--- a/src/ts/lib/datautil.tsx
+++ b/src/ts/lib/datautil.tsx
@@ -1,7 +1,8 @@
-import { I, C, keyboard, Storage, crumbs, translate } from 'ts/lib';
+import { I, C, keyboard, Storage, crumbs, translate, Util } from 'ts/lib';
import { commonStore, blockStore } from 'ts/store';
const Constant = require('json/constant.json');
+const Errors = require('json/error.json');
class DataUtil {
@@ -132,12 +133,20 @@ class DataUtil {
if (message.profileBlockId) {
blockStore.profileSet(message.profileBlockId);
- C.BlockOpen(message.profileBlockId);
+ C.BlockOpen(message.profileBlockId, (message: any) => {
+ if (message.error.code == Errors.Code.ANYTYPE_NEEDS_UPGRADE) {
+ Util.onErrorUpdate();
+ };
+ });
};
crumbs.init();
C.BlockOpen(root, (message: any) => {
+ if (message.error.code == Errors.Code.ANYTYPE_NEEDS_UPGRADE) {
+ Util.onErrorUpdate();
+ return;
+ };
if (callBack) {
callBack();
};
diff --git a/src/ts/lib/util.tsx b/src/ts/lib/util.tsx
index e7032f9c7b..8809ef038b 100644
--- a/src/ts/lib/util.tsx
+++ b/src/ts/lib/util.tsx
@@ -1,6 +1,7 @@
import { I, keyboard } from 'ts/lib';
import { commonStore } from 'ts/store';
import { v4 as uuidv4 } from 'uuid';
+import { translate } from '.';
const escapeStringRegexp = require('escape-string-regexp');
const { ipcRenderer } = window.require('electron');
@@ -11,6 +12,7 @@ const fs = window.require('fs');
const readChunk = window.require('read-chunk');
const fileType = window.require('file-type');
const Constant = require('json/constant.json');
+const Errors = require('json/error.json');
const os = window.require('os');
const sprintf = require('sprintf-kit')({
d: require('sprintf-kit/modifiers/d'),
@@ -520,11 +522,34 @@ class Util {
};
checkError (code: number) {
+ if (!code) {
+ return;
+ };
+
// App is already working
- if (code == 108) {
+ if (code == Errors.Code.ANOTHER_ANYTYPE_PROCESS_IS_RUNNING) {
alert('You have another instance of anytype running on this machine. Closing...');
ipcRenderer.send('exit', false);
};
+
+ // App needs update
+ if (code == Errors.Code.ANYTYPE_NEEDS_UPGRADE) {
+ this.onErrorUpdate();
+ };
+ };
+
+ onErrorUpdate (onConfirm?: () => void) {
+ commonStore.popupOpen('confirm', {
+ data: {
+ text: translate('confirmUpdateText'),
+ onConfirm: () => {
+ ipcRenderer.send('update');
+ if (onConfirm) {
+ onConfirm();
+ };
+ },
+ },
+ });
};
};