1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-08-24 20:19:10 +02:00

Compare commits

...

10 Commits

Author SHA1 Message Date
Laurent Cozic
23d492f79e Desktop release v2.10.17 2023-05-08 17:12:29 +01:00
Laurent Cozic
346a9c6b17 Desktop: Fixes #8072: Enter Key No Longer Saves and Closes The Tag Dialog 2023-05-08 17:11:58 +01:00
Laurent Cozic
3b836fdd61 Desktop: Fixes #8143: Fixes crash when using multiple profiles along with certain plugins 2023-05-08 17:10:32 +01:00
Laurent Cozic
f0afffedc9 Desktop: Fixes #8143: Fixes crash when using multiple profiles along with certain plugins 2023-05-08 17:10:20 +01:00
Laurent Cozic
6d8374885c Desktop release v2.10.16 2023-04-27 09:28:27 +01:00
Laurent Cozic
2e2feaba3d Desktop: Revert to "normal" package compression 2023-04-27 09:28:11 +01:00
Laurent Cozic
b84fc1c8b0 Desktop release v2.10.15 2023-04-26 21:49:44 +01:00
Laurent Cozic
18fef2d9df Desktop: Resolves #8028: Remove custom PDF viewer to reduce application size 2023-04-26 21:49:17 +01:00
Laurent Cozic
dfd0c40982 Desktop release v2.10.14 2023-04-26 12:23:05 +01:00
Arun Kumar
b514ca7e7d Desktop: Resolves #8028: Compress installer to reduce size (#8068) 2023-04-26 12:19:34 +01:00
9 changed files with 104 additions and 42 deletions

View File

@@ -631,7 +631,7 @@ const mapStateToProps = (state: AppState) => {
], whenClauseContext)[0],
contentMaxWidth: state.settings['style.editor.contentMaxWidth'],
isSafeMode: state.settings.isSafeMode,
useCustomPdfViewer: state.settings.useCustomPdfViewer,
useCustomPdfViewer: false, // state.settings.useCustomPdfViewer,
};
};

View File

@@ -26,11 +26,15 @@ export default class PromptDialog extends React.Component<Props, any> {
private focusInput_: boolean;
private styles_: any;
private styleKey_: string;
private menuIsOpened_: boolean = false;
constructor(props: Props) {
super(props);
this.answerInput_ = React.createRef();
this.select_menuOpen = this.select_menuOpen.bind(this);
this.select_menuClose = this.select_menuClose.bind(this);
}
UNSAFE_componentWillMount() {
@@ -39,6 +43,7 @@ export default class PromptDialog extends React.Component<Props, any> {
answer: this.props.defaultValue ? this.props.defaultValue : '',
});
this.focusInput_ = true;
this.menuIsOpened_ = false;
}
UNSAFE_componentWillReceiveProps(newProps: Props) {
@@ -52,7 +57,15 @@ export default class PromptDialog extends React.Component<Props, any> {
}
}
componentDidUpdate() {
private select_menuOpen() {
this.menuIsOpened_ = true;
}
private select_menuClose() {
this.menuIsOpened_ = false;
}
public componentDidUpdate() {
if (this.focusInput_ && this.answerInput_.current) this.answerInput_.current.focus();
this.focusInput_ = false;
}
@@ -224,16 +237,14 @@ export default class PromptDialog extends React.Component<Props, any> {
const onKeyDown = (event: any) => {
if (event.key === 'Enter') {
if (this.props.inputType === 'tags' || this.props.inputType === 'dropdown') {
// If the dropdown is open, we don't close the dialog - instead
// the currently item will be selcted. If it is closed however
// we confirm the dialog.
if ((this.props.inputType === 'tags' || this.props.inputType === 'dropdown') && this.menuIsOpened_) {
// Do nothing
} else {
onClose(true);
}
// } else if (this.answerInput_.current && !this.answerInput_.current.state.menuIsOpen) {
// // The menu will be open if the user is selecting a new item
// onClose(true);
// }
} else if (event.key === 'Escape') {
onClose(false);
}
@@ -246,9 +257,9 @@ export default class PromptDialog extends React.Component<Props, any> {
if (this.props.inputType === 'datetime') {
inputComp = <Datetime className="datetime-picker" value={this.state.answer} inputProps={{ style: styles.input }} dateFormat={time.dateFormat()} timeFormat={time.timeFormat()} onChange={(momentObject: any) => onDateTimeChange(momentObject)} />;
} else if (this.props.inputType === 'tags') {
inputComp = <CreatableSelect className="tag-selector" styles={styles.select} theme={styles.selectTheme} ref={this.answerInput_} value={this.state.answer} placeholder="" components={makeAnimated()} isMulti={true} isClearable={false} backspaceRemovesValue={true} options={this.props.autocomplete} onChange={onSelectChange} onKeyDown={(event: any) => onKeyDown(event)} />;
inputComp = <CreatableSelect className="tag-selector" onMenuOpen={this.select_menuOpen} onMenuClose={this.select_menuClose} styles={styles.select} theme={styles.selectTheme} ref={this.answerInput_} value={this.state.answer} placeholder="" components={makeAnimated()} isMulti={true} isClearable={false} backspaceRemovesValue={true} options={this.props.autocomplete} onChange={onSelectChange} onKeyDown={(event: any) => onKeyDown(event)} />;
} else if (this.props.inputType === 'dropdown') {
inputComp = <Select className="item-selector" styles={styles.select} theme={styles.selectTheme} ref={this.answerInput_} components={makeAnimated()} value={this.props.answer} defaultValue={this.props.defaultValue} isClearable={false} options={this.props.autocomplete} onChange={onSelectChange} onKeyDown={(event: any) => onKeyDown(event)} />;
inputComp = <Select className="item-selector" onMenuOpen={this.select_menuOpen} onMenuClose={this.select_menuClose} styles={styles.select} theme={styles.selectTheme} ref={this.answerInput_} components={makeAnimated()} value={this.props.answer} defaultValue={this.props.defaultValue} isClearable={false} options={this.props.autocomplete} onChange={onSelectChange} onKeyDown={(event: any) => onKeyDown(event)} />;
} else {
inputComp = <input style={styles.input} ref={this.answerInput_} value={this.state.answer} type="text" onChange={event => onChange(event)} onKeyDown={event => onKeyDown(event)} />;
}

View File

@@ -1,6 +1,6 @@
{
"name": "@joplin/app-desktop",
"version": "2.10.13",
"version": "2.10.17",
"description": "Joplin for Desktop",
"main": "main.js",
"private": true,
@@ -27,6 +27,7 @@
},
"build": {
"appId": "net.cozic.joplin-desktop",
"compression": "normal",
"productName": "Joplin",
"npmRebuild": false,
"afterSign": "./tools/notarizeMacApp.js",
@@ -137,7 +138,6 @@
"@fortawesome/fontawesome-free": "5.15.4",
"@joeattardi/emoji-button": "4.6.4",
"@joplin/lib": "~2.10",
"@joplin/pdf-viewer": "~2.10",
"@joplin/renderer": "~2.10",
"async-mutex": "0.4.0",
"codemirror": "5.65.9",

View File

@@ -72,10 +72,10 @@ async function main() {
src: langSourceDir,
dest: `${buildLibDir}/tinymce/langs`,
},
{
src: resolve(__dirname, '../../pdf-viewer/dist'),
dest: `${buildLibDir}/@joplin/pdf-viewer`,
},
// {
// src: resolve(__dirname, '../../pdf-viewer/dist'),
// dest: `${buildLibDir}/@joplin/pdf-viewer`,
// },
];
const files = [
@@ -93,10 +93,10 @@ async function main() {
src: resolve(__dirname, '../../lib/services/plugins/sandboxProxy.js'),
dest: `${buildLibDir}/@joplin/lib/services/plugins/sandboxProxy.js`,
},
{
src: resolve(__dirname, '../../pdf-viewer/index.html'),
dest: `${buildLibDir}/@joplin/pdf-viewer/index.html`,
},
// {
// src: resolve(__dirname, '../../pdf-viewer/index.html'),
// dest: `${buildLibDir}/@joplin/pdf-viewer/index.html`,
// },
];
// First we delete all the destination directories, then we copy the files.

View File

@@ -1,4 +1,4 @@
import Setting, { SettingSectionSource, SettingStorage } from '../models/Setting';
import Setting, { SettingItemType, SettingSectionSource, SettingStorage } from '../models/Setting';
import { setupDatabaseAndSynchronizer, switchClient, expectThrow, expectNotThrow, msleep } from '../testing/test-utils';
import { readFile, stat, mkdirp, writeFile, pathExists, readdir } from 'fs-extra';
import Logger from '../Logger';
@@ -297,12 +297,21 @@ describe('models/Setting', () => {
expect(Setting.isSet('spellChecker.languages')).toBe(false);
}));
it('should load sub-profile settings - 1', async () => {
it('should load sub-profile settings', async () => {
await Setting.reset();
await Setting.registerSetting('non_builtin', {
public: true,
storage: SettingStorage.File,
isGlobal: true,
type: SettingItemType.Bool,
value: false,
});
Setting.setValue('locale', 'fr_FR'); // Global setting
Setting.setValue('theme', Setting.THEME_DARK); // Global setting
Setting.setValue('sync.target', 9); // Local setting
Setting.setValue('non_builtin', true); // Local setting
await Setting.saveAll();
await switchToSubProfileSettings();
@@ -311,6 +320,9 @@ describe('models/Setting', () => {
expect(Setting.value('theme')).toBe(Setting.THEME_DARK); // Should come from the root profile
expect(Setting.value('sync.target')).toBe(0); // Should come from the local profile
// Non-built-in variables are not copied
expect(() => Setting.value('non_builtin')).toThrow();
// Also check that the special loadOne() function works as expected
expect((await Setting.loadOne('locale')).value).toBe('fr_FR');
@@ -318,7 +330,7 @@ describe('models/Setting', () => {
expect((await Setting.loadOne('sync.target')).value).toBe(undefined);
});
it('should save sub-profile settings - 2', async () => {
it('should save sub-profile settings', async () => {
await Setting.reset();
Setting.setValue('locale', 'fr_FR'); // Global setting
Setting.setValue('theme', Setting.THEME_DARK); // Global setting

View File

@@ -9,6 +9,7 @@ import FileHandler, { SettingValues } from './settings/FileHandler';
import Logger from '../Logger';
import mergeGlobalAndLocalSettings from '../services/profileConfig/mergeGlobalAndLocalSettings';
import splitGlobalAndLocalSettings from '../services/profileConfig/splitGlobalAndLocalSettings';
import JoplinError from '../JoplinError';
const { sprintf } = require('sprintf-js');
const ObjectUtils = require('../ObjectUtils');
const { toTitleCase } = require('../string-utils.js');
@@ -312,6 +313,7 @@ class Setting extends BaseModel {
private static fileHandler_: FileHandler = null;
private static rootFileHandler_: FileHandler = null;
private static settingFilename_: string = 'settings.json';
private static buildInMetadata_: SettingItems = null;
static tableName() {
return 'settings';
@@ -406,7 +408,7 @@ class Setting extends BaseModel {
return output;
};
this.metadata_ = {
this.buildInMetadata_ = {
'clientId': {
value: '',
type: SettingItemType.String,
@@ -1384,7 +1386,7 @@ class Setting extends BaseModel {
useCustomPdfViewer: {
value: false,
type: SettingItemType.Bool,
public: true,
public: false,
advanced: true,
appTypes: [AppType.Desktop],
label: () => 'Use custom PDF viewer (Beta)',
@@ -1685,6 +1687,8 @@ class Setting extends BaseModel {
};
this.metadata_ = { ...this.buildInMetadata_ };
this.metadata_ = Object.assign(this.metadata_, this.customMetadata_);
if (this.constants_.env === Env.Dev) this.validateMetadata(this.metadata_);
@@ -1698,6 +1702,10 @@ class Setting extends BaseModel {
}
}
public static isBuiltinKey(key: string): boolean {
return key in this.buildInMetadata_;
}
public static customCssFilePath(filename: string): string {
return `${this.value('rootProfileDir')}/${filename}`;
}
@@ -1799,7 +1807,7 @@ class Setting extends BaseModel {
static settingMetadata(key: string): SettingItem {
const metadata = this.metadata();
if (!(key in metadata)) throw new Error(`Unknown key: ${key}`);
if (!(key in metadata)) throw new JoplinError(`Unknown key: ${key}`, 'unknown_key');
const output = Object.assign({}, metadata[key]);
output.key = key;
return output;
@@ -2244,7 +2252,7 @@ class Setting extends BaseModel {
static enumOptions(key: string) {
const metadata = this.metadata();
if (!metadata[key]) throw new Error(`Unknown key: ${key}`);
if (!metadata[key]) throw new JoplinError(`Unknown key: ${key}`, 'unknown_key');
if (!metadata[key].options) throw new Error(`No options for: ${key}`);
return metadata[key].options();
}

View File

@@ -1,20 +1,52 @@
import Logger from '../../Logger';
import Setting from '../../models/Setting';
const logger = Logger.create('mergeGlobalAndLocalSettings');
export default (rootSettings: Record<string, any>, subProfileSettings: Record<string, any>) => {
const output: Record<string, any> = { ...subProfileSettings };
for (const k of Object.keys(output)) {
const md = Setting.settingMetadata(k);
if (md.isGlobal) {
delete output[k];
if (k in rootSettings) output[k] = rootSettings[k];
try {
const md = Setting.settingMetadata(k);
if (md.isGlobal) {
delete output[k];
if (k in rootSettings) output[k] = rootSettings[k];
}
} catch (error) {
if (error.code === 'unknown_key') {
// The root settings may contain plugin parameters, but the
// sub-profile won't necessarily have these plugins. In that
// case, the app will throw an error, but we can ignore it since
// we don't need this particular setting.
// https://github.com/laurent22/joplin/issues/8143
logger.info(`Ignoring unknown key in root settings: ${k}`);
}
}
}
for (const k of Object.keys(rootSettings)) {
const md = Setting.settingMetadata(k);
if (md.isGlobal) {
output[k] = rootSettings[k];
// We only copy built-in key and not, for example, plugin keys, because
// those are plugin-specific
if (!Setting.isBuiltinKey(k)) {
logger.info(`Skipping non-built-in key: ${k}`);
continue;
}
try {
const md = Setting.settingMetadata(k);
if (md.isGlobal) {
output[k] = rootSettings[k];
}
} catch (error) {
if (error.code === 'unknown_key') {
// The root settings may contain plugin parameters, but the
// sub-profile won't necessarily have these plugins. In that
// case, the app will throw an error, but we can ignore it since
// we don't need this particular setting.
// https://github.com/laurent22/joplin/issues/8143
logger.info(`Ignoring unknown key in root settings: ${k}`);
}
}
}

View File

@@ -9,12 +9,12 @@
"access": "restricted"
},
"scripts": {
"tsc": "tsc --project tsconfig.json",
"watch": "webpack --watch --config webpack.config.js --mode=development",
"build": "webpack --config webpack.config.js --mode=production",
"test": "jest",
"test-ci": "yarn test",
"postinstall": "yarn build"
"tsc_DISABLED": "tsc --project tsconfig.json",
"watch_DISABLED": "webpack --watch --config webpack.config.js --mode=development",
"build_DISABLED": "webpack --config webpack.config.js --mode=production",
"test_DISABLED": "jest",
"test-ci_DISABLED": "yarn test",
"postinstall_DISABLED": "yarn build"
},
"author": "Joplin",
"license": "AGPL-3.0-or-later",

View File

@@ -4644,7 +4644,6 @@ __metadata:
"@fortawesome/fontawesome-free": 5.15.4
"@joeattardi/emoji-button": 4.6.4
"@joplin/lib": ~2.10
"@joplin/pdf-viewer": ~2.10
"@joplin/renderer": ~2.10
"@joplin/tools": ~2.10
"@testing-library/react-hooks": 8.0.1
@@ -4948,7 +4947,7 @@ __metadata:
languageName: unknown
linkType: soft
"@joplin/pdf-viewer@workspace:packages/pdf-viewer, @joplin/pdf-viewer@~2.10":
"@joplin/pdf-viewer@workspace:packages/pdf-viewer":
version: 0.0.0-use.local
resolution: "@joplin/pdf-viewer@workspace:packages/pdf-viewer"
dependencies: