You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-08-30 20:39:46 +02:00
Compare commits
19 Commits
android-v1
...
cli-v1.3.1
Author | SHA1 | Date | |
---|---|---|---|
|
6d5d9323bd | ||
|
76063a6284 | ||
|
4119924e57 | ||
|
537336754c | ||
|
06f73919bd | ||
|
3f3e46081c | ||
|
68e4b4eaad | ||
|
9dcb4b51e5 | ||
|
8543849ea1 | ||
|
6ce5240e12 | ||
|
5bc25aefce | ||
|
b737ca7471 | ||
|
a5d7366f94 | ||
|
98f822d89c | ||
|
c33a8250ee | ||
|
adad406696 | ||
|
d82eec0fa4 | ||
|
c93f474547 | ||
|
0afd4a6234 |
@@ -81,6 +81,7 @@ ElectronClient/app.js
|
||||
ElectronClient/bridge.js
|
||||
ElectronClient/commands/copyDevCommand.js
|
||||
ElectronClient/commands/focusElement.js
|
||||
ElectronClient/commands/openProfileDirectory.js
|
||||
ElectronClient/commands/startExternalEditing.js
|
||||
ElectronClient/commands/stopExternalEditing.js
|
||||
ElectronClient/commands/toggleExternalEditing.js
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -75,6 +75,7 @@ ElectronClient/app.js
|
||||
ElectronClient/bridge.js
|
||||
ElectronClient/commands/copyDevCommand.js
|
||||
ElectronClient/commands/focusElement.js
|
||||
ElectronClient/commands/openProfileDirectory.js
|
||||
ElectronClient/commands/startExternalEditing.js
|
||||
ElectronClient/commands/stopExternalEditing.js
|
||||
ElectronClient/commands/toggleExternalEditing.js
|
||||
|
1
.ignore
1
.ignore
@@ -24,6 +24,7 @@ ElectronClient/app.js
|
||||
ElectronClient/bridge.js
|
||||
ElectronClient/commands/copyDevCommand.js
|
||||
ElectronClient/commands/focusElement.js
|
||||
ElectronClient/commands/openProfileDirectory.js
|
||||
ElectronClient/commands/startExternalEditing.js
|
||||
ElectronClient/commands/stopExternalEditing.js
|
||||
ElectronClient/commands/toggleExternalEditing.js
|
||||
|
@@ -54,15 +54,25 @@ export default class PluginRunner extends BasePluginRunner {
|
||||
};
|
||||
}
|
||||
|
||||
async run(plugin:Plugin, sandbox:Global) {
|
||||
const vmSandbox = vm.createContext(this.newSandboxProxy(plugin.id, sandbox));
|
||||
async run(plugin:Plugin, sandbox:Global):Promise<void> {
|
||||
return new Promise((resolve:Function, reject:Function) => {
|
||||
const onStarted = () => {
|
||||
plugin.off('started', onStarted);
|
||||
resolve();
|
||||
};
|
||||
|
||||
try {
|
||||
vm.runInContext(plugin.scriptText, vmSandbox);
|
||||
} catch (error) {
|
||||
this.logger().error(`In plugin ${plugin.id}:`, error);
|
||||
return;
|
||||
}
|
||||
plugin.on('started', onStarted);
|
||||
|
||||
const vmSandbox = vm.createContext(this.newSandboxProxy(plugin.id, sandbox));
|
||||
|
||||
try {
|
||||
vm.runInContext(plugin.scriptText, vmSandbox);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
// this.logger().error(`In plugin ${plugin.id}:`, error);
|
||||
// return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -38,42 +38,42 @@ locales['tr_TR'] = require('./tr_TR.json');
|
||||
locales['vi'] = require('./vi.json');
|
||||
locales['zh_CN'] = require('./zh_CN.json');
|
||||
locales['zh_TW'] = require('./zh_TW.json');
|
||||
stats['ar'] = {"percentDone":80};
|
||||
stats['eu'] = {"percentDone":34};
|
||||
stats['bs_BA'] = {"percentDone":83};
|
||||
stats['bg_BG'] = {"percentDone":66};
|
||||
stats['ca'] = {"percentDone":96};
|
||||
stats['ar'] = {"percentDone":79};
|
||||
stats['eu'] = {"percentDone":33};
|
||||
stats['bs_BA'] = {"percentDone":82};
|
||||
stats['bg_BG'] = {"percentDone":65};
|
||||
stats['ca'] = {"percentDone":95};
|
||||
stats['hr_HR'] = {"percentDone":27};
|
||||
stats['cs_CZ'] = {"percentDone":82};
|
||||
stats['da_DK'] = {"percentDone":74};
|
||||
stats['de_DE'] = {"percentDone":98};
|
||||
stats['et_EE'] = {"percentDone":66};
|
||||
stats['cs_CZ'] = {"percentDone":99};
|
||||
stats['da_DK'] = {"percentDone":73};
|
||||
stats['de_DE'] = {"percentDone":97};
|
||||
stats['et_EE'] = {"percentDone":65};
|
||||
stats['en_GB'] = {"percentDone":100};
|
||||
stats['en_US'] = {"percentDone":100};
|
||||
stats['es_ES'] = {"percentDone":95};
|
||||
stats['eo'] = {"percentDone":38};
|
||||
stats['fr_FR'] = {"percentDone":99};
|
||||
stats['gl_ES'] = {"percentDone":43};
|
||||
stats['id_ID'] = {"percentDone":93};
|
||||
stats['it_IT'] = {"percentDone":90};
|
||||
stats['nl_BE'] = {"percentDone":34};
|
||||
stats['nl_NL'] = {"percentDone":95};
|
||||
stats['nb_NO'] = {"percentDone":88};
|
||||
stats['fa'] = {"percentDone":83};
|
||||
stats['pl_PL'] = {"percentDone":98};
|
||||
stats['pt_PT'] = {"percentDone":88};
|
||||
stats['pt_BR'] = {"percentDone":96};
|
||||
stats['es_ES'] = {"percentDone":99};
|
||||
stats['eo'] = {"percentDone":37};
|
||||
stats['fr_FR'] = {"percentDone":98};
|
||||
stats['gl_ES'] = {"percentDone":42};
|
||||
stats['id_ID'] = {"percentDone":92};
|
||||
stats['it_IT'] = {"percentDone":98};
|
||||
stats['nl_BE'] = {"percentDone":33};
|
||||
stats['nl_NL'] = {"percentDone":94};
|
||||
stats['nb_NO'] = {"percentDone":87};
|
||||
stats['fa'] = {"percentDone":82};
|
||||
stats['pl_PL'] = {"percentDone":97};
|
||||
stats['pt_PT'] = {"percentDone":98};
|
||||
stats['pt_BR'] = {"percentDone":95};
|
||||
stats['ro'] = {"percentDone":77};
|
||||
stats['sl_SI'] = {"percentDone":42};
|
||||
stats['sv'] = {"percentDone":70};
|
||||
stats['th_TH'] = {"percentDone":52};
|
||||
stats['vi'] = {"percentDone":85};
|
||||
stats['tr_TR'] = {"percentDone":98};
|
||||
stats['el_GR'] = {"percentDone":96};
|
||||
stats['ru_RU'] = {"percentDone":95};
|
||||
stats['sr_RS'] = {"percentDone":71};
|
||||
stats['zh_CN'] = {"percentDone":96};
|
||||
stats['zh_TW'] = {"percentDone":95};
|
||||
stats['ja_JP'] = {"percentDone":98};
|
||||
stats['ko'] = {"percentDone":98};
|
||||
stats['vi'] = {"percentDone":84};
|
||||
stats['tr_TR'] = {"percentDone":97};
|
||||
stats['el_GR'] = {"percentDone":95};
|
||||
stats['ru_RU'] = {"percentDone":94};
|
||||
stats['sr_RS'] = {"percentDone":70};
|
||||
stats['zh_CN'] = {"percentDone":95};
|
||||
stats['zh_TW'] = {"percentDone":94};
|
||||
stats['ja_JP'] = {"percentDone":97};
|
||||
stats['ko'] = {"percentDone":99};
|
||||
module.exports = { locales: locales, stats: stats };
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2
CliClient/package-lock.json
generated
2
CliClient/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "joplin",
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@@ -28,7 +28,7 @@
|
||||
],
|
||||
"owner": "Laurent Cozic"
|
||||
},
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.1",
|
||||
"bin": {
|
||||
"joplin": "./main.js"
|
||||
},
|
||||
|
@@ -3,6 +3,7 @@ require('app-module-path').addPath(__dirname);
|
||||
const { asyncTest, setupDatabaseAndSynchronizer, switchClient } = require('test-utils.js');
|
||||
const shim = require('lib/shim').default;
|
||||
const { enexXmlToHtml } = require('lib/import-enex-html-gen.js');
|
||||
const cleanHtml = require('clean-html');
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.warn('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
@@ -19,6 +20,20 @@ const audioResource = {
|
||||
title: 'audio test',
|
||||
};
|
||||
|
||||
// All the test HTML files are beautified ones, so we need to run
|
||||
// this before the comparison. Before, beautifying was done by `enexXmlToHtml`
|
||||
// but that was removed due to problems with the clean-html package.
|
||||
const beautifyHtml = (html) => {
|
||||
return new Promise((resolve) => {
|
||||
try {
|
||||
cleanHtml.clean(html, { wrap: 0 }, (...cleanedHtml) => resolve(cleanedHtml.join('')));
|
||||
} catch (error) {
|
||||
console.warn(`Could not clean HTML - the "unclean" version will be used: ${error.message}: ${html.trim().substr(0, 512).replace(/[\n\r]/g, ' ')}...`);
|
||||
resolve([html].join(''));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests the importer for a single note, checking that the result of
|
||||
* processing the given `.enex` input file matches the contents of the given
|
||||
@@ -38,7 +53,7 @@ const compareOutputToExpected = (options) => {
|
||||
it(testTitle, asyncTest(async () => {
|
||||
const enexInput = await shim.fsDriver().readFile(inputFile);
|
||||
const expectedOutput = await shim.fsDriver().readFile(outputFile);
|
||||
const actualOutput = await enexXmlToHtml(enexInput, options.resources);
|
||||
const actualOutput = await beautifyHtml(await enexXmlToHtml(enexInput, options.resources));
|
||||
|
||||
expect(actualOutput).toEqual(expectedOutput);
|
||||
}));
|
||||
|
@@ -1,14 +1,25 @@
|
||||
import FsDriverNode from 'lib/fs-driver-node';
|
||||
import shim from 'lib/shim';
|
||||
const { expectThrow } = require('test-utils.js');
|
||||
|
||||
// On Windows, path.resolve is going to convert a path such as
|
||||
// /tmp/file.txt to c:\tmp\file.txt
|
||||
function platformPath(path:string) {
|
||||
if (shim.isWindows()) {
|
||||
return `C:${path.replace(/\//g, '\\')}`;
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
describe('fsDriver', function() {
|
||||
|
||||
it('should resolveRelativePathWithinDir', () => {
|
||||
const fsDriver = new FsDriverNode();
|
||||
expect(fsDriver.resolveRelativePathWithinDir('/test/temp', './my/file.txt')).toBe('/test/temp/my/file.txt');
|
||||
expect(fsDriver.resolveRelativePathWithinDir('/', './test')).toBe('/test');
|
||||
expect(fsDriver.resolveRelativePathWithinDir('/test', 'myfile.txt')).toBe('/test/myfile.txt');
|
||||
expect(fsDriver.resolveRelativePathWithinDir('/test/temp', './mydir/../test.txt')).toBe('/test/temp/test.txt');
|
||||
expect(fsDriver.resolveRelativePathWithinDir('/test/temp', './my/file.txt')).toBe(platformPath('/test/temp/my/file.txt'));
|
||||
expect(fsDriver.resolveRelativePathWithinDir('/', './test')).toBe(platformPath('/test'));
|
||||
expect(fsDriver.resolveRelativePathWithinDir('/test', 'myfile.txt')).toBe(platformPath('/test/myfile.txt'));
|
||||
expect(fsDriver.resolveRelativePathWithinDir('/test/temp', './mydir/../test.txt')).toBe(platformPath('/test/temp/test.txt'));
|
||||
|
||||
expectThrow(() => fsDriver.resolveRelativePathWithinDir('/test/temp', '../myfile.txt'));
|
||||
expectThrow(() => fsDriver.resolveRelativePathWithinDir('/test/temp', './mydir/../../test.txt'));
|
||||
|
@@ -2,12 +2,10 @@ import PluginRunner from '../app/services/plugins/PluginRunner';
|
||||
import PluginService from 'lib/services/plugins/PluginService';
|
||||
import { ContentScriptType } from 'lib/services/plugins/api/types';
|
||||
import MdToHtml from 'lib/joplin-renderer/MdToHtml';
|
||||
import Setting from 'lib/models/Setting';
|
||||
import shim from 'lib/shim';
|
||||
import uuid from 'lib/uuid';
|
||||
|
||||
require('app-module-path').addPath(__dirname);
|
||||
const { asyncTest, setupDatabaseAndSynchronizer, switchClient, expectThrow } = require('test-utils.js');
|
||||
const { asyncTest, setupDatabaseAndSynchronizer, switchClient, expectThrow, createTempDir } = require('test-utils.js');
|
||||
const Note = require('lib/models/Note');
|
||||
const Folder = require('lib/models/Folder');
|
||||
|
||||
@@ -65,6 +63,9 @@ describe('services_PluginService', function() {
|
||||
|
||||
const allFolders = await Folder.all();
|
||||
expect(allFolders.length).toBe(1);
|
||||
|
||||
// If you have an error here, it might mean you need to run `npm i` from
|
||||
// the "withExternalModules" folder. Not clear exactly why.
|
||||
expect(allFolders[0].title).toBe(' foo');
|
||||
}));
|
||||
|
||||
@@ -154,12 +155,14 @@ describe('services_PluginService', function() {
|
||||
}));
|
||||
|
||||
it('should register a Markdown-it plugin', asyncTest(async () => {
|
||||
const contentScriptPath = `${Setting.value('tempDir')}/markdownItTestPlugin${uuid.createNano()}.js`;
|
||||
const tempDir = await createTempDir();
|
||||
|
||||
const contentScriptPath = `${tempDir}/markdownItTestPlugin.js`;
|
||||
await shim.fsDriver().copy(`${testPluginDir}/content_script/src/markdownItTestPlugin.js`, contentScriptPath);
|
||||
|
||||
const service = newPluginService();
|
||||
|
||||
const plugin = await service.loadPluginFromString('example', Setting.value('tempDir'), `
|
||||
const plugin = await service.loadPluginFromString('example', tempDir, `
|
||||
/* joplin-manifest:
|
||||
{
|
||||
"manifest_version": 1,
|
||||
@@ -173,7 +176,7 @@ describe('services_PluginService', function() {
|
||||
|
||||
joplin.plugins.register({
|
||||
onStart: async function() {
|
||||
await joplin.plugins.registerContentScript('markdownItPlugin', 'justtesting', '${contentScriptPath}');
|
||||
await joplin.plugins.registerContentScript('markdownItPlugin', 'justtesting', './markdownItTestPlugin.js');
|
||||
},
|
||||
});
|
||||
`);
|
||||
@@ -198,7 +201,7 @@ describe('services_PluginService', function() {
|
||||
|
||||
expect(result.html.includes('JUST TESTING: something')).toBe(true);
|
||||
|
||||
await shim.fsDriver().remove(contentScriptPath);
|
||||
await shim.fsDriver().remove(tempDir);
|
||||
}));
|
||||
|
||||
});
|
||||
|
@@ -1,7 +1,12 @@
|
||||
import joplin from 'api';
|
||||
import { ContentScriptType } from 'api/types';
|
||||
|
||||
joplin.plugins.register({
|
||||
onStart: async function() {
|
||||
await joplin.plugins.registerContentScript('markdownItPlugin', 'justtesting', './markdownItTestPlugin.js');
|
||||
await joplin.plugins.registerContentScript(
|
||||
ContentScriptType.MarkdownItPlugin,
|
||||
'justtesting',
|
||||
'./markdownItTestPlugin.js'
|
||||
);
|
||||
},
|
||||
});
|
||||
|
@@ -80,9 +80,9 @@ EncryptionService.fsDriver_ = fsDriver;
|
||||
FileApiDriverLocal.fsDriver_ = fsDriver;
|
||||
|
||||
const logDir = `${__dirname}/../tests/logs`;
|
||||
const tempDir = `${__dirname}/../tests/tmp`;
|
||||
const baseTempDir = `${__dirname}/../tests/tmp`;
|
||||
fs.mkdirpSync(logDir, 0o755);
|
||||
fs.mkdirpSync(tempDir, 0o755);
|
||||
fs.mkdirpSync(baseTempDir, 0o755);
|
||||
fs.mkdirpSync(`${__dirname}/data`);
|
||||
|
||||
SyncTargetRegistry.addClass(SyncTargetMemory);
|
||||
@@ -146,7 +146,7 @@ BaseItem.loadClass('Revision', Revision);
|
||||
|
||||
Setting.setConstant('appId', 'net.cozic.joplintest-cli');
|
||||
Setting.setConstant('appType', 'cli');
|
||||
Setting.setConstant('tempDir', tempDir);
|
||||
Setting.setConstant('tempDir', baseTempDir);
|
||||
Setting.setConstant('env', 'dev');
|
||||
|
||||
BaseService.logger_ = logger;
|
||||
@@ -634,6 +634,12 @@ function tempFilePath(ext) {
|
||||
return `${Setting.value('tempDir')}/${md5(Date.now() + Math.random())}.${ext}`;
|
||||
}
|
||||
|
||||
async function createTempDir() {
|
||||
const tempDirPath = `${baseTempDir}/${uuid.createNano()}`;
|
||||
await fs.mkdirp(tempDirPath);
|
||||
return tempDirPath;
|
||||
}
|
||||
|
||||
function mockDate(year, month, day, tick) {
|
||||
const fixedDate = new Date(2020, 0, 1);
|
||||
jasmine.clock().install();
|
||||
@@ -712,4 +718,4 @@ class TestApp extends BaseApplication {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { synchronizerStart, syncTargetName, setSyncTargetName, syncDir, isNetworkSyncTarget, kvStore, expectThrow, logger, expectNotThrow, resourceService, resourceFetcher, tempFilePath, allSyncTargetItemsEncrypted, msleep, setupDatabase, revisionService, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync, checkThrow, encryptionService, loadEncryptionMasterKey, fileContentEqual, decryptionWorker, asyncTest, currentClientId, id, ids, sortedIds, at, createNTestNotes, createNTestFolders, createNTestTags, mockDate, restoreDate, TestApp };
|
||||
module.exports = { synchronizerStart, syncTargetName, setSyncTargetName, syncDir, createTempDir, isNetworkSyncTarget, kvStore, expectThrow, logger, expectNotThrow, resourceService, resourceFetcher, tempFilePath, allSyncTargetItemsEncrypted, msleep, setupDatabase, revisionService, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync, checkThrow, encryptionService, loadEncryptionMasterKey, fileContentEqual, decryptionWorker, asyncTest, currentClientId, id, ids, sortedIds, at, createNTestNotes, createNTestFolders, createNTestTags, mockDate, restoreDate, TestApp };
|
||||
|
@@ -77,6 +77,7 @@ const globalCommands = [
|
||||
require('./commands/stopExternalEditing'),
|
||||
require('./commands/toggleExternalEditing'),
|
||||
require('./commands/copyDevCommand'),
|
||||
require('./commands/openProfileDirectory'),
|
||||
require('lib/commands/synchronize'),
|
||||
require('lib/commands/historyBackward'),
|
||||
require('lib/commands/historyForward'),
|
||||
|
@@ -149,8 +149,10 @@ function checkForUpdates(inBackground, window, logFilePath, options) {
|
||||
|
||||
const result = await dialog.showMessageBox(parentWindow_, {
|
||||
type: 'info',
|
||||
message: `${_('An update is available, do you want to download it now?')}\n\n${_('Your version: %s', packageInfo.version)}\n${_('New version: %s', newVersionString)}${releaseNotes}`,
|
||||
buttons: [_('Yes'), _('No')].concat(truncateReleaseNotes ? [_('Full Release Notes')] : []),
|
||||
message: `${_('An update is available, do you want to download it now?')}`,
|
||||
detail: `${_('Your version: %s', packageInfo.version)}\n${_('New version: %s', newVersionString)}${releaseNotes}`,
|
||||
buttons: [_('Download'), _('Cancel')].concat(truncateReleaseNotes ? [_('Full Release Notes')] : []),
|
||||
cancelId: 1,
|
||||
});
|
||||
|
||||
const buttonIndex = result.response;
|
||||
|
17
ElectronClient/commands/openProfileDirectory.ts
Normal file
17
ElectronClient/commands/openProfileDirectory.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { CommandRuntime, CommandDeclaration } from '../lib/services/CommandService';
|
||||
import { _ } from 'lib/locale';
|
||||
import bridge from '../services/bridge';
|
||||
import Setting from 'lib/models/Setting';
|
||||
|
||||
export const declaration:CommandDeclaration = {
|
||||
name: 'openProfileDirectory',
|
||||
label: () => _('Open profile directory'),
|
||||
};
|
||||
|
||||
export const runtime = ():CommandRuntime => {
|
||||
return {
|
||||
execute: async () => {
|
||||
bridge().openItem(Setting.value('profileDir'));
|
||||
},
|
||||
};
|
||||
};
|
@@ -8,8 +8,9 @@ export const declaration:CommandDeclaration = {
|
||||
export const runtime = (comp:any):CommandRuntime => {
|
||||
return {
|
||||
execute: async (_context:CommandContext, message:string) => {
|
||||
let brIndex = 1;
|
||||
const lines = message.split('\n').map((line:string) => {
|
||||
if (!line.trim()) return <br/>;
|
||||
if (!line.trim()) return <br key={`${brIndex++}`}/>;
|
||||
return <div key={line} className="text">{line}</div>;
|
||||
});
|
||||
|
||||
|
@@ -116,6 +116,7 @@ const commandNames:string[] = [
|
||||
'setTags',
|
||||
'showNoteContentProperties',
|
||||
'copyDevCommand',
|
||||
'openProfileDirectory',
|
||||
];
|
||||
|
||||
function menuItemSetChecked(id:string, checked:boolean) {
|
||||
@@ -658,6 +659,7 @@ function useMenu(props:Props) {
|
||||
},
|
||||
},
|
||||
|
||||
menuItemDic.openProfileDirectory,
|
||||
menuItemDic.copyDevCommand,
|
||||
|
||||
{
|
||||
|
@@ -43,6 +43,14 @@ async function resourceInfo(options:ContextMenuOptions):Promise<any> {
|
||||
return { resource, resourcePath };
|
||||
}
|
||||
|
||||
function handleCopyToClipboard(options:ContextMenuOptions) {
|
||||
if (options.textToCopy) {
|
||||
clipboard.writeText(options.textToCopy);
|
||||
} else if (options.htmlToCopy) {
|
||||
clipboard.writeHTML(options.htmlToCopy);
|
||||
}
|
||||
}
|
||||
|
||||
export function menuItems():ContextMenuItems {
|
||||
return {
|
||||
open: {
|
||||
@@ -88,7 +96,7 @@ export function menuItems():ContextMenuItems {
|
||||
cut: {
|
||||
label: _('Cut'),
|
||||
onAction: async (options:ContextMenuOptions) => {
|
||||
clipboard.writeText(options.textToCopy);
|
||||
handleCopyToClipboard(options);
|
||||
options.insertContent('');
|
||||
},
|
||||
isActive: (_itemType:ContextMenuItemType, options:ContextMenuOptions) => !options.isReadOnly && (!!options.textToCopy || !!options.htmlToCopy),
|
||||
@@ -96,11 +104,7 @@ export function menuItems():ContextMenuItems {
|
||||
copy: {
|
||||
label: _('Copy'),
|
||||
onAction: async (options:ContextMenuOptions) => {
|
||||
if (options.textToCopy) {
|
||||
clipboard.writeText(options.textToCopy);
|
||||
} else if (options.htmlToCopy) {
|
||||
clipboard.writeHTML(options.htmlToCopy);
|
||||
}
|
||||
handleCopyToClipboard(options);
|
||||
},
|
||||
isActive: (_itemType:ContextMenuItemType, options:ContextMenuOptions) => !!options.textToCopy || !!options.htmlToCopy,
|
||||
},
|
||||
@@ -117,7 +121,7 @@ export function menuItems():ContextMenuItems {
|
||||
onAction: async (options:ContextMenuOptions) => {
|
||||
clipboard.writeText(options.linkToCopy !== null ? options.linkToCopy : options.textToCopy);
|
||||
},
|
||||
isActive: (itemType:ContextMenuItemType) => itemType === ContextMenuItemType.Link,
|
||||
isActive: (itemType:ContextMenuItemType, options:ContextMenuOptions) => itemType === ContextMenuItemType.Link || !!options.linkToCopy,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@@ -41,7 +41,7 @@ export default function useMessageHandler(scrollWhenReady:any, setScrollWhenRead
|
||||
itemType: arg0 && arg0.type,
|
||||
resourceId: arg0.resourceId,
|
||||
textToCopy: arg0.textToCopy,
|
||||
linkToCopy: null,
|
||||
linkToCopy: arg0.linkToCopy || null,
|
||||
htmlToCopy: '',
|
||||
insertContent: () => { console.warn('insertContent() not implemented'); },
|
||||
});
|
||||
|
@@ -368,9 +368,12 @@
|
||||
const selectedText = window.getSelection().toString();
|
||||
|
||||
if (selectedText) {
|
||||
const linkToCopy = event.target && event.target.getAttribute('href') ? event.target.getAttribute('href') : null;
|
||||
|
||||
ipcProxySendToHost('contextMenu', {
|
||||
type: 'text',
|
||||
textToCopy: selectedText,
|
||||
linkToCopy: linkToCopy,
|
||||
});
|
||||
} else if (event.target.getAttribute('href')) {
|
||||
ipcProxySendToHost('contextMenu', {
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user