You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-08-24 20:19:10 +02:00
Compare commits
3 Commits
android-v3
...
alt_instan
Author | SHA1 | Date | |
---|---|---|---|
|
04666be15f | ||
|
64d0bec2c5 | ||
|
ab28f2a794 |
@@ -4,15 +4,12 @@ import AutoUpdaterService, { defaultUpdateInterval, initialUpdateStartup } from
|
||||
import type ShimType from '@joplin/lib/shim';
|
||||
const shim: typeof ShimType = require('@joplin/lib/shim').default;
|
||||
import { isCallbackUrl } from '@joplin/lib/callbackUrlUtils';
|
||||
|
||||
import { BrowserWindow, Tray, WebContents, screen } from 'electron';
|
||||
import { BrowserWindow, Tray, WebContents, screen, App, Event, dialog, ipcMain } from 'electron';
|
||||
import bridge from './bridge';
|
||||
const url = require('url');
|
||||
const path = require('path');
|
||||
const { dirname } = require('@joplin/lib/path-utils');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
import { dialog, ipcMain } from 'electron';
|
||||
import { _ } from '@joplin/lib/locale';
|
||||
import restartInSafeModeFromMain from './utils/restartInSafeModeFromMain';
|
||||
import handleCustomProtocols, { CustomProtocolHandler } from './utils/customProtocols/handleCustomProtocols';
|
||||
@@ -36,8 +33,7 @@ interface SecondaryWindowData {
|
||||
|
||||
export default class ElectronAppWrapper {
|
||||
private logger_: Logger = null;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
private electronApp_: any;
|
||||
private electronApp_: App;
|
||||
private env_: string;
|
||||
private isDebugMode_: boolean;
|
||||
private profilePath_: string;
|
||||
@@ -48,8 +44,7 @@ export default class ElectronAppWrapper {
|
||||
private secondaryWindows_: Map<SecondaryWindowId, SecondaryWindowData> = new Map();
|
||||
|
||||
private willQuitApp_ = false;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
private tray_: any = null;
|
||||
private tray_: Tray = null;
|
||||
private buildDir_: string = null;
|
||||
private rendererProcessQuitReply_: RendererProcessQuitReply = null;
|
||||
|
||||
@@ -57,14 +52,15 @@ export default class ElectronAppWrapper {
|
||||
private updaterService_: AutoUpdaterService = null;
|
||||
private customProtocolHandler_: CustomProtocolHandler = null;
|
||||
private updatePollInterval_: ReturnType<typeof setTimeout>|null = null;
|
||||
private isAltInstance_: boolean;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
public constructor(electronApp: any, env: string, profilePath: string|null, isDebugMode: boolean, initialCallbackUrl: string) {
|
||||
public constructor(electronApp: App, env: string, profilePath: string|null, isDebugMode: boolean, initialCallbackUrl: string, isAltInstance: boolean) {
|
||||
this.electronApp_ = electronApp;
|
||||
this.env_ = env;
|
||||
this.isDebugMode_ = isDebugMode;
|
||||
this.profilePath_ = profilePath;
|
||||
this.initialCallbackUrl_ = initialCallbackUrl;
|
||||
this.isAltInstance_ = isAltInstance;
|
||||
}
|
||||
|
||||
public electronApp() {
|
||||
@@ -87,6 +83,10 @@ export default class ElectronAppWrapper {
|
||||
return BrowserWindow.getFocusedWindow() ?? this.win_;
|
||||
}
|
||||
|
||||
public isAltInstance() {
|
||||
return this.isAltInstance_;
|
||||
}
|
||||
|
||||
public windowById(joplinId: string) {
|
||||
if (joplinId === defaultWindowId) {
|
||||
return this.mainWindow();
|
||||
@@ -538,6 +538,7 @@ export default class ElectronAppWrapper {
|
||||
|
||||
public ensureSingleInstance() {
|
||||
if (this.env_ === 'dev') return false;
|
||||
if (this.isAltInstance_) return false;
|
||||
|
||||
const gotTheLock = this.electronApp_.requestSingleInstanceLock();
|
||||
|
||||
@@ -548,8 +549,7 @@ export default class ElectronAppWrapper {
|
||||
}
|
||||
|
||||
// Someone tried to open a second instance - focus our window instead
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
this.electronApp_.on('second-instance', (_e: any, argv: string[]) => {
|
||||
this.electronApp_.on('second-instance', (_event: Event, argv: string[], _workingDirectory: string) => {
|
||||
const win = this.mainWindow();
|
||||
if (!win) return;
|
||||
if (win.isMinimized()) win.restore();
|
||||
|
@@ -617,10 +617,11 @@ class Application extends BaseApplication {
|
||||
clipperLogger.addTarget(TargetType.Console);
|
||||
|
||||
ClipperServer.instance().initialize(actionApi);
|
||||
ClipperServer.instance().setEnabled(!Setting.value('isAltInstance'));
|
||||
ClipperServer.instance().setLogger(clipperLogger);
|
||||
ClipperServer.instance().setDispatch(this.store().dispatch);
|
||||
|
||||
if (Setting.value('clipperServer.autoStart')) {
|
||||
if (ClipperServer.instance().enabled() && Setting.value('clipperServer.autoStart')) {
|
||||
void ClipperServer.instance().start();
|
||||
}
|
||||
|
||||
|
@@ -24,6 +24,7 @@ class ClipperConfigScreenComponent extends React.Component {
|
||||
}
|
||||
|
||||
private enableClipperServer_click() {
|
||||
if (!ClipperServer.instance().enabled()) return;
|
||||
Setting.setValue('clipperServer.autoStart', true);
|
||||
void ClipperServer.instance().start();
|
||||
}
|
||||
@@ -70,6 +71,8 @@ class ClipperConfigScreenComponent extends React.Component {
|
||||
|
||||
const webClipperStatusComps = [];
|
||||
|
||||
const clipperEnabled = ClipperServer.instance().enabled();
|
||||
|
||||
if (this.props.clipperServerAutoStart) {
|
||||
webClipperStatusComps.push(
|
||||
<p key="text_1" style={theme.textStyle}>
|
||||
@@ -94,14 +97,23 @@ class ClipperConfigScreenComponent extends React.Component {
|
||||
{_('Disable Web Clipper Service')}
|
||||
</button>,
|
||||
);
|
||||
} else {
|
||||
if (!clipperEnabled) {
|
||||
webClipperStatusComps.push(
|
||||
<p key="text_4" style={theme.textStyle}>
|
||||
{_('The web clipper service cannot be enabled in this instance of Joplin.')}
|
||||
</p>,
|
||||
);
|
||||
} else {
|
||||
webClipperStatusComps.push(
|
||||
<p key="text_4" style={theme.textStyle}>
|
||||
{_('The web clipper service is not enabled.')}
|
||||
</p>,
|
||||
);
|
||||
}
|
||||
|
||||
webClipperStatusComps.push(
|
||||
<button key="enable_button" style={buttonStyle} onClick={this.enableClipperServer_click}>
|
||||
<button key="enable_button" style={buttonStyle} onClick={this.enableClipperServer_click} disabled={!clipperEnabled}>
|
||||
{_('Enable Web Clipper Service')}
|
||||
</button>,
|
||||
);
|
||||
|
@@ -40,6 +40,7 @@ Logger.fsDriver_ = new FsDriverNode();
|
||||
const env = envFromArgs(process.argv);
|
||||
const profileFromArgs = getProfileFromArgs(process.argv);
|
||||
const isDebugMode = !!process.argv && process.argv.indexOf('--debug') >= 0;
|
||||
const isAltInstance = !!process.argv && process.argv.indexOf('--is-alt-instance') >= 0;
|
||||
|
||||
// We initialize all these variables here because they are needed from the main process. They are
|
||||
// then passed to the renderer process via the bridge.
|
||||
@@ -65,7 +66,7 @@ void registerCustomProtocols();
|
||||
|
||||
const initialCallbackUrl = process.argv.find((arg) => isCallbackUrl(arg));
|
||||
|
||||
const wrapper = new ElectronAppWrapper(electronApp, env, rootProfileDir, isDebugMode, initialCallbackUrl);
|
||||
const wrapper = new ElectronAppWrapper(electronApp, env, rootProfileDir, isDebugMode, initialCallbackUrl, isAltInstance);
|
||||
|
||||
initBridge(wrapper, appId, appName, rootProfileDir, autoUploadCrashDumps);
|
||||
|
||||
|
@@ -21,7 +21,7 @@ const restartInSafeModeFromMain = async () => {
|
||||
shimInit({});
|
||||
|
||||
const startFlags = await processStartFlags(bridge().processArgv());
|
||||
const { rootProfileDir } = determineBaseAppDirs(startFlags.matched.profileDir, appName);
|
||||
const { rootProfileDir } = determineBaseAppDirs(startFlags.matched.profileDir, appName, Setting.value('isAltInstance'));
|
||||
const { profileDir } = await initProfile(rootProfileDir);
|
||||
|
||||
// We can't access the database, so write to a file instead.
|
||||
|
@@ -687,7 +687,7 @@ export default class BaseApplication {
|
||||
// https://immerjs.github.io/immer/docs/freezing
|
||||
setAutoFreeze(initArgs.env === 'dev');
|
||||
|
||||
const { rootProfileDir, homeDir } = determineProfileAndBaseDir(options.rootProfileDir ?? initArgs.profileDir, appName);
|
||||
const { rootProfileDir, homeDir } = determineProfileAndBaseDir(options.rootProfileDir ?? initArgs.profileDir, appName, initArgs.isAltInstance);
|
||||
const { profileDir, profileConfig, isSubProfile } = await initProfile(rootProfileDir);
|
||||
this.profileConfig_ = profileConfig;
|
||||
|
||||
@@ -806,6 +806,8 @@ export default class BaseApplication {
|
||||
Setting.setValue('sync.interval', 3600);
|
||||
}
|
||||
|
||||
Setting.setValue('isAltInstance', initArgs.isAltInstance);
|
||||
|
||||
Setting.setValue('firstStart', false);
|
||||
} else {
|
||||
Setting.applyDefaultMigrations();
|
||||
|
@@ -23,6 +23,7 @@ export default class ClipperServer {
|
||||
private api_: Api = null;
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types -- Old code before rule was applied
|
||||
private dispatch_: Function;
|
||||
private enabled_ = true;
|
||||
|
||||
private static instance_: ClipperServer = null;
|
||||
|
||||
@@ -40,6 +41,18 @@ export default class ClipperServer {
|
||||
return this.api_;
|
||||
}
|
||||
|
||||
public enabled() {
|
||||
return this.enabled_;
|
||||
}
|
||||
|
||||
public setEnabled(v: boolean) {
|
||||
this.enabled_ = v;
|
||||
|
||||
if (!this.enabled_ && this.isRunning()) {
|
||||
void this.stop();
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
public initialize(actionApi: any = null) {
|
||||
this.api_ = new Api(() => {
|
||||
@@ -106,6 +119,8 @@ export default class ClipperServer {
|
||||
}
|
||||
|
||||
public async start() {
|
||||
if (!this.enabled()) throw new Error('Cannot start clipper server because it is disabled');
|
||||
|
||||
this.setPort(null);
|
||||
|
||||
this.setStartState(StartState.Starting);
|
||||
@@ -251,8 +266,10 @@ export default class ClipperServer {
|
||||
}
|
||||
|
||||
public async stop() {
|
||||
if (this.server_) {
|
||||
this.server_.destroy();
|
||||
this.server_ = null;
|
||||
}
|
||||
this.setStartState(StartState.Idle);
|
||||
this.setPort(null);
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { homedir } from 'os';
|
||||
import { toSystemSlashes } from './path-utils';
|
||||
|
||||
export default (profileFromArgs: string, appName: string) => {
|
||||
export default (profileFromArgs: string, appName: string, isAltInstance: boolean) => {
|
||||
let profileDir = '';
|
||||
let homeDir = '';
|
||||
|
||||
@@ -12,7 +12,8 @@ export default (profileFromArgs: string, appName: string) => {
|
||||
profileDir = `${process.env.PORTABLE_EXECUTABLE_DIR}/JoplinProfile`;
|
||||
homeDir = process.env.PORTABLE_EXECUTABLE_DIR;
|
||||
} else {
|
||||
profileDir = `${homedir()}/.config/${appName}`;
|
||||
const suffix = isAltInstance ? '-alt' : '';
|
||||
profileDir = `${homedir()}/.config/${appName}${suffix}`;
|
||||
homeDir = homedir();
|
||||
}
|
||||
|
||||
|
@@ -62,6 +62,16 @@ const builtInMetadata = (Setting: typeof SettingType) => {
|
||||
type: SettingItemType.String,
|
||||
public: false,
|
||||
},
|
||||
|
||||
'isAltInstance': {
|
||||
value: false,
|
||||
type: SettingItemType.Bool,
|
||||
public: false,
|
||||
appTypes: [AppType.Desktop],
|
||||
storage: SettingStorage.File,
|
||||
isGlobal: true,
|
||||
},
|
||||
|
||||
'editor.codeView': {
|
||||
value: true,
|
||||
type: SettingItemType.Bool,
|
||||
|
@@ -13,6 +13,7 @@ export interface MatchedStartFlags {
|
||||
logLevel?: LogLevel;
|
||||
allowOverridingDnsResultOrder?: boolean;
|
||||
devPlugins?: string[];
|
||||
isAltInstance?: boolean;
|
||||
}
|
||||
|
||||
// Handles the initial flags passed to main script and
|
||||
@@ -181,6 +182,12 @@ const processStartFlags = async (argv: string[], setDefaults = true) => {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--is-alt-instance') {
|
||||
matched.isAltInstance = true;
|
||||
argv.splice(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.length && arg[0] === '-') {
|
||||
throw new JoplinError(_('Unknown flag: %s', arg), 'flagError');
|
||||
} else {
|
||||
|
@@ -89,6 +89,7 @@ export default function versionInfo(packageInfo: PackageInfo, plugins: Plugins)
|
||||
_('Sync Version: %s', Setting.value('syncVersion')),
|
||||
_('Profile Version: %s', reg.db().version()),
|
||||
_('Keychain Supported: %s', keychainSupported ? _('Yes') : _('No')),
|
||||
_('Is alternative instance: %s', Setting.value('isAltInstance') ? _('Yes') : _('No')),
|
||||
];
|
||||
|
||||
if (gitInfo) {
|
||||
|
Reference in New Issue
Block a user