1
0
Fork 0
mirror of https://github.com/anyproto/anytype-ts.git synced 2025-06-08 05:57:02 +09:00

fix window opening, authorization flow and preloader

This commit is contained in:
Andrew Simachev 2022-07-01 15:34:05 +03:00
parent e8b55ebcc6
commit 11218ed00a
10 changed files with 116 additions and 84 deletions

View file

@ -13,6 +13,7 @@ const remote = require('@electron/remote/main');
const userPath = app.getPath('userData');
const tmpPath = path.join(userPath, 'tmp');
const logPath = path.join(userPath, 'logs');
const binPath = fixPathForAsarUnpack(path.join(__dirname, 'dist', `anytypeHelper${is.windows ? '.exe' : ''}`));
const Api = require('./electron/js/api.js');
@ -61,6 +62,7 @@ if (app.isPackaged && !app.requestSingleInstanceLock()) {
storage.setDataPath(userPath);
Util.mkDir(tmpPath);
Util.mkDir(logPath);
if (process.env.ANYTYPE_USE_SIDE_SERVER) {
// use the grpc server started from the outside
@ -86,7 +88,7 @@ nativeTheme.on('updated', () => {
});
function createMainWindow () {
mainWindow = WindowManager.createMain({ withState: true, route: Util.getRouteFromUrl(deeplinkingUrl) });
mainWindow = WindowManager.createMain({ withState: true, route: Util.getRouteFromUrl(deeplinkingUrl), isChild: false });
if (process.env.ELECTRON_DEV_EXTENSIONS) {
BrowserWindow.addDevToolsExtension(

View file

@ -12,14 +12,24 @@ const KEYTAR_SERVICE = 'Anytype';
class Api {
account = null;
appOnLoad (win) {
Util.send(win, 'init', Util.dataPath(), ConfigManager.config, Util.isDarkTheme());
Util.send(win, 'init', Util.dataPath(), ConfigManager.config, Util.isDarkTheme(), {
isChild: win.isChild,
route: win.route,
account: this.account,
});
};
setConfig (win, config) {
ConfigManager.set(config, (err) => { Util.send(win, 'config', ConfigManager.config); });
};
setAccount (win, account) {
this.account = account;
};
keytarSet (win, key, value) {
if (key && value) {
keytar.setPassword(KEYTAR_SERVICE, key, value);
@ -57,7 +67,11 @@ class Api {
};
windowOpen (win, route) {
WindowManager.createMain({ withState: false, route: route });
WindowManager.createMain({
route: route,
withState: false,
isChild: true
});
};
urlOpen (win, url) {

View file

@ -18,7 +18,9 @@ class WindowManager {
list = new Set();
create (param) {
create (options, param) {
const { route, isChild } = options;
param = Object.assign({
backgroundColor: Util.getBgColor(),
icon: path.join(Util.imagePath(), 'icon.png'),
@ -27,12 +29,15 @@ class WindowManager {
webPreferences: {},
}, param);
param.webPreferences = Object.assign({
nodeIntegration: true,
}, param.webPreferences);
param.webPreferences = Object.assign({ nodeIntegration: true }, param.webPreferences);
let win = new BrowserWindow(param);
win.isChild = isChild;
win.route = route;
this.list.add(win);
win.on('closed', () => {
this.list.delete(win);
win = null;
@ -42,13 +47,11 @@ class WindowManager {
win.on('enter-full-screen', () => { Util.send(win, 'enter-full-screen'); });
win.on('leave-full-screen', () => { Util.send(win, 'leave-full-screen'); });
this.list.add(win);
return win;
};
createMain (options) {
const { withState, route } = options;
const { withState, route, isChild } = options;
const image = nativeImage.createFromPath(path.join(Util.imagePath(), 'icon512x512.png'));
let state = {};
@ -60,7 +63,6 @@ class WindowManager {
webPreferences: {
nativeWindowOpen: true,
nodeIntegration: true,
contextIsolation: false,
spellcheck: false
},
@ -94,7 +96,7 @@ class WindowManager {
});
};
const win = this.create(param);
const win = this.create(options, param);
remote.enable(win.webContents);
@ -103,16 +105,16 @@ class WindowManager {
};
if (is.development) {
win.loadURL(`http://localhost:${port}#${route}`);
win.loadURL(`http://localhost:${port}`);
win.toggleDevTools();
} else {
win.loadFile(`./dist/index.html#${route}`);
win.loadURL('file://' + path.join(Util.appPath, 'dist', 'index.html'));
};
return win;
};
createAbout () {
const win = this.create({ width: 400, height: 400, useContentSize: true });
const win = this.create({}, { width: 400, height: 400, useContentSize: true });
win.loadURL('file://' + path.join(Util.electronPath(), 'about', `index.html?version=${version}&theme=${Util.getTheme()}`));
win.setMenu(null);

View file

@ -40,8 +40,10 @@ input, textarea, select { font-family: 'Inter'; }
#drag {
.sides { display: none; }
}
#root > #loader { position: fixed; width: 100%; height: 100%; left: 0px; top: 0px; }
#root > #loader {
#root-loader {
position: fixed; width: 100%; height: 100%; left: 0px; top: 0px; background: #fff; z-index: 1000; transition: opacity 0.5s ease-in-out;
}
#root-loader {
.logo {
width: 120px; height: 24px; background: url('~img/logo/color.svg') no-repeat; background-size: 100% 100%;
position: absolute; left: 50%; top: 50%; margin: -12px 0px 0px -60px; transition: opacity 0.5s ease-in-out;

View file

@ -12,7 +12,7 @@ html.themeDark {
a { color: $colorPrimary; }
a:hover { color: $colorOrange; }
#root > #loader { background: $colorBlack; }
#root-loader { background: $colorBlack; }
::selection { color: $colorBlack; }

View file

@ -6,7 +6,7 @@ import { Provider } from 'mobx-react';
import { enableLogging } from 'mobx-logger';
import { Page, SelectionProvider, DragProvider, Progress, Tooltip, Preview, Icon, ListPopup, ListMenu } from './component';
import { commonStore, authStore, blockStore, detailStore, dbStore, menuStore, popupStore } from './store';
import { I, C, Util, FileUtil, keyboard, Storage, analytics, dispatcher, translate, Action, Renderer } from 'ts/lib';
import { I, C, Util, FileUtil, keyboard, Storage, analytics, dispatcher, translate, Action, Renderer, DataUtil } from 'ts/lib';
import * as Sentry from '@sentry/browser';
import { configure } from 'mobx';
@ -263,6 +263,7 @@ class App extends React.Component<Props, State> {
constructor (props: any) {
super(props);
this.onInit = this.onInit.bind(this);
this.onImport = this.onImport.bind(this);
this.onProgress = this.onProgress.bind(this);
this.onCommand = this.onCommand.bind(this);
@ -281,7 +282,7 @@ class App extends React.Component<Props, State> {
<Provider {...rootStore}>
<div>
{loading ? (
<div id="loader" className="loaderWrapper">
<div id="root-loader" className="loaderWrapper">
<div id="logo" className="logo" />
</div>
) : ''}
@ -331,6 +332,7 @@ class App extends React.Component<Props, State> {
analytics.init();
this.registerIpcEvents();
Renderer.send('appOnLoad');
$(window).off('beforeunload').on('beforeunload', (e: any) => {
if (!authStore.token) {
@ -352,40 +354,14 @@ class App extends React.Component<Props, State> {
const cover = Storage.get('cover');
const lastSurveyTime = Number(Storage.get('lastSurveyTime')) || 0;
const redirect = Storage.get('redirect');
const accountId = Storage.get('accountId');
const phrase = Storage.get('phrase');
const restoreKeys = [
'pinTime', 'defaultType', 'autoSidebar',
];
const hash = window.location.hash.replace(/^#/, '');
// Check auth phrase with keytar
if (accountId) {
Renderer.send('keytarGet', accountId);
Renderer.on('keytarGet', (e: any, key: string, value: string) => {
if (accountId && (key == accountId)) {
if (phrase) {
value = phrase;
Renderer.send('keytarSet', accountId, phrase);
Storage.delete('phrase');
};
if (value) {
authStore.phraseSet(value);
Util.route('/auth/setup/init', true);
} else {
Storage.logout();
};
};
});
};
const restoreKeys = [ 'pinTime', 'defaultType', 'autoSidebar' ];
if (!lastSurveyTime) {
Storage.set('lastSurveyTime', Util.time());
};
if (hash || redirect) {
commonStore.redirectSet(hash || redirect);
if (redirect) {
commonStore.redirectSet(redirect);
Storage.delete('redirect');
};
@ -415,32 +391,28 @@ class App extends React.Component<Props, State> {
};
registerIpcEvents () {
const node = $(ReactDOM.findDOMNode(this));
const logo = node.find('#logo');
const logsDir = path.join(userPath, 'logs');
const logPath = path.join(userPath, 'logs');
try { fs.mkdirSync(logsDir); } catch (err) {};
Renderer.on('init', this.onInit);
Renderer.send('appOnLoad');
Renderer.on('keytarGet', (e: any, key: string, value: string) => {
const accountId = Storage.get('accountId');
const phrase = Storage.get('phrase');
Renderer.on('init', (e: any, dataPath: string, config: any, isDark: boolean) => {
authStore.walletPathSet(dataPath);
authStore.accountPathSet(dataPath);
if (accountId && (key == accountId)) {
if (phrase) {
value = phrase;
Renderer.send('keytarSet', accountId, phrase);
Storage.delete('phrase');
};
Storage.init(dataPath);
this.initStorage();
commonStore.nativeThemeSet(isDark);
commonStore.configSet(config, true);
commonStore.themeSet(config.theme);
this.initTheme(config.theme);
window.setTimeout(() => {
logo.css({ opacity: 0 });
window.setTimeout(() => { this.setState({ loading: false }); }, 600);
}, 2000);
if (value) {
authStore.phraseSet(value);
Util.route('/auth/setup/init', true);
} else {
Storage.logout();
};
};
});
Renderer.on('route', (e: any, route: string) => {
@ -589,9 +561,9 @@ class App extends React.Component<Props, State> {
Renderer.on('debugTree', (e: any) => {
const rootId = keyboard.getRootId();
C.DebugTree(rootId, logsDir, (message: any) => {
C.DebugTree(rootId, logPath, (message: any) => {
if (!message.error.code) {
Renderer.send('pathOpen', logsDir);
Renderer.send('pathOpen', logPath);
};
});
});
@ -620,6 +592,43 @@ class App extends React.Component<Props, State> {
Renderer.send('pathOpen', logsDir);
};
onInit (e: any, dataPath: string, config: any, isDark: boolean, windowData: any) {
console.log('INIT', dataPath, config, isDark, windowData);
const node = $(ReactDOM.findDOMNode(this));
const loader = node.find('#root-loader');
const logo = loader.find('#logo');
const accountId = Storage.get('accountId');
if (accountId) {
if (windowData.isChild) {
if (windowData.route) {
commonStore.redirectSet(windowData.route);
};
DataUtil.onAuth(windowData.account);
} else {
Renderer.send('keytarGet', accountId);
};
};
this.initStorage();
this.initTheme(config.theme);
authStore.walletPathSet(dataPath);
authStore.accountPathSet(dataPath);
commonStore.nativeThemeSet(isDark);
commonStore.configSet(config, true);
commonStore.themeSet(config.theme);
window.setTimeout(() => {
logo.css({ opacity: 0 });
window.setTimeout(() => { loader.css({ opacity: 0 }); }, 500);
window.setTimeout(() => { loader.remove(); }, 1000);
}, 2000);
};
onCommand (e: any, key: string) {
let rootId = keyboard.getRootId();
let options: any = {};

View file

@ -42,6 +42,10 @@ class Dispatcher {
};
listenEvents () {
if (!authStore.token) {
return;
};
const request = new Commands.StreamRequest();
request.setToken(authStore.token);

View file

@ -15,15 +15,15 @@ class Renderer {
send (...args: any[]) {
const cmd = args[0];
if (Api[cmd]) {
args.shift();
args.unshift(remote.getCurrentWindow());
Api[cmd].apply(null, args);
} else {
const renderer = this.get();
renderer.send.apply(renderer, args);
if (!Api[cmd]) {
return;
};
args.shift();
args.unshift(remote.getCurrentWindow());
Api[cmd].apply(null, args);
};
on (event: string, callBack: any) {

View file

@ -6,9 +6,6 @@ class Storage {
this.storage = localStorage;
};
init (dataPath: string) {
};
get (key: string): any {
let o = String(this.storage[key] || '');
if (!o) {

View file

@ -1,5 +1,5 @@
import { observable, action, computed, set, makeObservable } from 'mobx';
import { I, M, Storage, analytics } from 'ts/lib';
import { I, M, Storage, analytics, Renderer } from 'ts/lib';
import { blockStore, detailStore, commonStore, dbStore } from 'ts/store';
import * as Sentry from '@sentry/browser';
import { keyboard } from 'ts/lib';
@ -130,6 +130,8 @@ class AuthStore {
if (account.id) {
Storage.set('accountId', account.id);
Renderer.send('setAccount', this.accountItem);
Sentry.setUser({ id: account.id });
};
};