Skip to content

Commit

Permalink
Desktop: Resolves laurent22#5168: Add support for callback URLs (lau…
Browse files Browse the repository at this point in the history
  • Loading branch information
roman-r-m authored Oct 16, 2021
1 parent 4322acc commit 6879481
Show file tree
Hide file tree
Showing 13 changed files with 243 additions and 15 deletions.
9 changes: 6 additions & 3 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -693,9 +693,6 @@ packages/app-desktop/services/commands/stateToWhenClauseContext.js.map
packages/app-desktop/services/commands/types.d.ts
packages/app-desktop/services/commands/types.js
packages/app-desktop/services/commands/types.js.map
packages/app-desktop/services/e2ee.d.ts
packages/app-desktop/services/e2ee.js
packages/app-desktop/services/e2ee.js.map
packages/app-desktop/services/plugins/PlatformImplementation.d.ts
packages/app-desktop/services/plugins/PlatformImplementation.js
packages/app-desktop/services/plugins/PlatformImplementation.js.map
Expand Down Expand Up @@ -945,6 +942,12 @@ packages/lib/TaskQueue.js.map
packages/lib/array.d.ts
packages/lib/array.js
packages/lib/array.js.map
packages/lib/callbackUrlUtils.d.ts
packages/lib/callbackUrlUtils.js
packages/lib/callbackUrlUtils.js.map
packages/lib/callbackUrlUtils.test.d.ts
packages/lib/callbackUrlUtils.test.js
packages/lib/callbackUrlUtils.test.js.map
packages/lib/commands/historyBackward.d.ts
packages/lib/commands/historyBackward.js
packages/lib/commands/historyBackward.js.map
Expand Down
9 changes: 6 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -676,9 +676,6 @@ packages/app-desktop/services/commands/stateToWhenClauseContext.js.map
packages/app-desktop/services/commands/types.d.ts
packages/app-desktop/services/commands/types.js
packages/app-desktop/services/commands/types.js.map
packages/app-desktop/services/e2ee.d.ts
packages/app-desktop/services/e2ee.js
packages/app-desktop/services/e2ee.js.map
packages/app-desktop/services/plugins/PlatformImplementation.d.ts
packages/app-desktop/services/plugins/PlatformImplementation.js
packages/app-desktop/services/plugins/PlatformImplementation.js.map
Expand Down Expand Up @@ -928,6 +925,12 @@ packages/lib/TaskQueue.js.map
packages/lib/array.d.ts
packages/lib/array.js
packages/lib/array.js.map
packages/lib/callbackUrlUtils.d.ts
packages/lib/callbackUrlUtils.js
packages/lib/callbackUrlUtils.js.map
packages/lib/callbackUrlUtils.test.d.ts
packages/lib/callbackUrlUtils.test.js
packages/lib/callbackUrlUtils.test.js.map
packages/lib/commands/historyBackward.d.ts
packages/lib/commands/historyBackward.js
packages/lib/commands/historyBackward.js.map
Expand Down
18 changes: 16 additions & 2 deletions Joplin_install_and_update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ if command -v lsb_release &> /dev/null; then
# Linux Mint 4 Debbie is based on Debian 10 and requires the same param handling.
if [[ $DISTVER =~ Debian1. ]] || [ "$DISTVER" = "Linuxmint4" ] && [ "$DISTCODENAME" = "debbie" ] || [ "$DISTVER" = "CentOS" ] && [[ "$DISTMAJOR" =~ 6|7 ]]
then
SANDBOXPARAM=" --no-sandbox"
SANDBOXPARAM="--no-sandbox"
fi
fi

Expand All @@ -206,7 +206,21 @@ then

# On some systems this directory doesn't exist by default
mkdir -p ~/.local/share/applications
echo -e "[Desktop Entry]\nEncoding=UTF-8\nName=Joplin\nComment=Joplin for Desktop\nExec=${HOME}/.joplin/Joplin.AppImage${SANDBOXPARAM}\nIcon=joplin\nStartupWMClass=Joplin\nType=Application\nCategories=Office;" >> ~/.local/share/applications/appimagekit-joplin.desktop

# Tabs specifically, and not spaces, are needed for indentation with Bash heredocs
cat >> ~/.local/share/applications/appimagekit-joplin.desktop <<-EOF
[Desktop Entry]
Encoding=UTF-8
Name=Joplin
Comment=Joplin for Desktop
Exec=${HOME}/.joplin/Joplin.AppImage ${SANDBOXPARAM}
Icon=joplin
StartupWMClass=Joplin
Type=Application
Categories=Office;
MimeType=x-scheme-handler/joplin;
EOF

# Update application icons
[[ `command -v update-desktop-database` ]] && update-desktop-database ~/.local/share/applications && update-desktop-database ~/.local/share/icons
print "${COLOR_GREEN}OK${COLOR_RESET}"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ The Web Clipper is a browser extension that allows you to save web pages and scr
- [What is a conflict?](https://github.com/laurent22/joplin/blob/dev/readme/conflict.md)
- [How to enable debug mode](https://github.com/laurent22/joplin/blob/dev/readme/debugging.md)
- [About the Rich Text editor limitations](https://github.com/laurent22/joplin/blob/dev/readme/rich_text_editor.md)
- [External links](https://github.com/laurent22/joplin/blob/dev/readme/external_links.md)
- [FAQ](https://github.com/laurent22/joplin/blob/dev/readme/faq.md)

- Joplin Cloud
Expand Down
30 changes: 27 additions & 3 deletions packages/app-desktop/ElectronAppWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Logger from '@joplin/lib/Logger';
import { PluginMessage } from './services/plugins/PluginRunner';
import shim from '@joplin/lib/shim';
import { isCallbackUrl } from '@joplin/lib/callbackUrlUtils';

const { BrowserWindow, Tray, screen } = require('electron');
const url = require('url');
Expand Down Expand Up @@ -30,12 +31,14 @@ export default class ElectronAppWrapper {
private buildDir_: string = null;
private rendererProcessQuitReply_: RendererProcessQuitReply = null;
private pluginWindows_: PluginWindows = {};
private initialCallbackUrl_: string = null;

constructor(electronApp: any, env: string, profilePath: string, isDebugMode: boolean) {
constructor(electronApp: any, env: string, profilePath: string, isDebugMode: boolean, initialCallbackUrl: string) {
this.electronApp_ = electronApp;
this.env_ = env;
this.isDebugMode_ = isDebugMode;
this.profilePath_ = profilePath;
this.initialCallbackUrl_ = initialCallbackUrl;
}

electronApp() {
Expand All @@ -58,6 +61,10 @@ export default class ElectronAppWrapper {
return this.env_;
}

initialCallbackUrl() {
return this.initialCallbackUrl_;
}

createWindow() {
// Set to true to view errors if the application does not start
const debugEarlyBugs = this.env_ === 'dev' || this.isDebugMode_;
Expand Down Expand Up @@ -236,7 +243,7 @@ export default class ElectronAppWrapper {
async waitForElectronAppReady() {
if (this.electronApp().isReady()) return Promise.resolve();

return new Promise((resolve) => {
return new Promise<void>((resolve) => {
const iid = setInterval(() => {
if (this.electronApp().isReady()) {
clearInterval(iid);
Expand Down Expand Up @@ -323,12 +330,18 @@ export default class ElectronAppWrapper {
}

// Someone tried to open a second instance - focus our window instead
this.electronApp_.on('second-instance', () => {
this.electronApp_.on('second-instance', (_e: any, argv: string[]) => {
const win = this.window();
if (!win) return;
if (win.isMinimized()) win.restore();
win.show();
win.focus();
if (process.platform !== 'darwin') {
const url = argv.find((arg) => isCallbackUrl(arg));
if (url) {
void this.openCallbackUrl(url);
}
}
});

return false;
Expand All @@ -355,6 +368,17 @@ export default class ElectronAppWrapper {
this.electronApp_.on('activate', () => {
this.win_.show();
});

this.electronApp_.on('open-url', (event: any, url: string) => {
event.preventDefault();
void this.openCallbackUrl(url);
});
}

async openCallbackUrl(url: string) {
this.win_.webContents.send('asynchronous-message', 'openCallbackUrl', {
url: url,
});
}

}
19 changes: 19 additions & 0 deletions packages/app-desktop/gui/MainScreen/MainScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import ShareFolderDialog from '../ShareFolderDialog/ShareFolderDialog';
import { ShareInvitation } from '@joplin/lib/services/share/reducer';
import removeKeylessItems from '../ResizableLayout/utils/removeKeylessItems';
import { localSyncInfoFromState } from '@joplin/lib/services/synchronizer/syncInfoUtils';
import { parseCallbackUrl } from '@joplin/lib/callbackUrlUtils';
import ElectronAppWrapper from '../../ElectronAppWrapper';
import { showMissingMasterKeyMessage } from '@joplin/lib/services/e2ee/utils';
import commands from './commands/index';
import invitationRespond from '../../services/share/invitationRespond';
Expand Down Expand Up @@ -154,6 +156,23 @@ class MainScreenComponent extends React.Component<Props, State> {
this.layoutModeListenerKeyDown = this.layoutModeListenerKeyDown.bind(this);

window.addEventListener('resize', this.window_resize);

ipcRenderer.on('asynchronous-message', (_event: any, message: string, args: any) => {
if (message === 'openCallbackUrl') {
this.openCallbackUrl(args.url);
}
});

const initialCallbackUrl = (bridge().electronApp() as ElectronAppWrapper).initialCallbackUrl();
if (initialCallbackUrl) {
this.openCallbackUrl(initialCallbackUrl);
}
}

private openCallbackUrl(url: string) {
console.log(`openUrl ${url}`);
const { command, params } = parseCallbackUrl(url);
void CommandService.instance().execute(command.toString(), params.id);
}

private updateLayoutPluginViews(layout: LayoutItem, plugins: PluginStates) {
Expand Down
21 changes: 21 additions & 0 deletions packages/app-desktop/gui/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Logger from '@joplin/lib/Logger';
import { FolderEntity } from '@joplin/lib/services/database/types';
import stateToWhenClauseContext from '../../services/commands/stateToWhenClauseContext';
import { store } from '@joplin/lib/reducer';
import { getFolderCallbackUrl, getTagCallbackUrl } from '@joplin/lib/callbackUrlUtils';
const { connect } = require('react-redux');
const shared = require('@joplin/lib/components/shared/side-menu-shared.js');
const { themeStyle } = require('@joplin/lib/theme');
Expand All @@ -28,6 +29,7 @@ const Menu = bridge().Menu;
const MenuItem = bridge().MenuItem;
const { substrWithEllipsis } = require('@joplin/lib/string-utils');
const { ALL_NOTES_FILTER_ID } = require('@joplin/lib/reserved-ids');
const { clipboard } = require('electron');

const logger = Logger.create('Sidebar');

Expand Down Expand Up @@ -332,10 +334,29 @@ class SidebarComponent extends React.Component<Props, State> {
);
}

if (itemType === BaseModel.TYPE_FOLDER) {
menu.append(
new MenuItem({
label: _('Copy external link'),
click: () => {
clipboard.writeText(getFolderCallbackUrl(itemId));
},
})
);
}

if (itemType === BaseModel.TYPE_TAG) {
menu.append(new MenuItem(
menuUtils.commandToStatefulMenuItem('renameTag', itemId)
));
menu.append(
new MenuItem({
label: _('Copy external link'),
click: () => {
clipboard.writeText(getTagCallbackUrl(itemId));
},
})
);
}

const pluginViews = pluginUtils.viewsByType(this.pluginsRef.current, 'menuItem');
Expand Down
14 changes: 13 additions & 1 deletion packages/app-desktop/gui/utils/NoteListUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import MenuUtils from '@joplin/lib/services/commands/MenuUtils';
import InteropServiceHelper from '../../InteropServiceHelper';
import { _ } from '@joplin/lib/locale';
import { MenuItemLocation } from '@joplin/lib/services/plugins/api/types';
import { getNoteCallbackUrl } from '@joplin/lib/callbackUrlUtils';

import BaseModel from '@joplin/lib/BaseModel';
const bridge = require('@electron/remote').require('./bridge').default;
const Menu = bridge().Menu;
const MenuItem = bridge().MenuItem;
import Note from '@joplin/lib/models/Note';
import Setting from '@joplin/lib/models/Setting';
const { clipboard } = require('electron');

interface ContextMenuProps {
notes: any[];
Expand Down Expand Up @@ -121,7 +123,6 @@ export default class NoteListUtils {
new MenuItem({
label: _('Copy Markdown link'),
click: async () => {
const { clipboard } = require('electron');
const links = [];
for (let i = 0; i < noteIds.length; i++) {
const note = await Note.load(noteIds[i]);
Expand All @@ -132,6 +133,17 @@ export default class NoteListUtils {
})
);

if (noteIds.length === 1) {
menu.append(
new MenuItem({
label: _('Copy external link'),
click: () => {
clipboard.writeText(getNoteCallbackUrl(noteIds[0]));
},
})
);
}

if ([9, 10].includes(Setting.value('sync.target'))) {
menu.append(
new MenuItem(
Expand Down
7 changes: 6 additions & 1 deletion packages/app-desktop/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const Logger = require('@joplin/lib/Logger').default;
const FsDriverNode = require('@joplin/lib/fs-driver-node').default;
const envFromArgs = require('@joplin/lib/envFromArgs');
const packageInfo = require('./packageInfo.js');
const { isCallbackUrl } = require('@joplin/lib/callbackUrlUtils');

// Electron takes the application name from package.json `name` and
// displays this in the tray icon toolip and message box titles, however in
Expand Down Expand Up @@ -37,7 +38,11 @@ const env = envFromArgs(process.argv);
const profilePath = profileFromArgs(process.argv);
const isDebugMode = !!process.argv && process.argv.indexOf('--debug') >= 0;

const wrapper = new ElectronAppWrapper(electronApp, env, profilePath, isDebugMode);
electronApp.setAsDefaultProtocolClient('joplin');

const initialCallbackUrl = process.argv.find((arg) => isCallbackUrl(arg));

const wrapper = new ElectronAppWrapper(electronApp, env, profilePath, isDebugMode, initialCallbackUrl);

initBridge(wrapper);

Expand Down
14 changes: 12 additions & 2 deletions packages/app-desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,23 @@
"icon": "../../Assets/macOs.icns",
"target": "dmg",
"hardenedRuntime": true,
"entitlements": "./build-mac/entitlements.mac.inherit.plist"
"entitlements": "./build-mac/entitlements.mac.inherit.plist",
"extendInfo": {
"CFBundleURLTypes": [
{
"CFBundleURLSchemes": ["joplin"],
"CFBundleTypeRole": "Editor",
"CFBundleURLName": "org.joplinapp.x-callback-url"
}
]
}
},
"linux": {
"icon": "../../Assets/LinuxIcons",
"category": "Office",
"desktop": {
"Icon": "joplin"
"Icon": "joplin",
"MimeType": "x-scheme-handler/joplin;"
},
"target": "AppImage"
},
Expand Down
Loading

0 comments on commit 6879481

Please sign in to comment.