You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-11-23 22:36:32 +02:00
Desktop, Mobile: Resolves #13048: Auto-disable plugin settings when conflicting built-in settings are enabled (#13055)
This commit is contained in:
@@ -169,6 +169,30 @@ const userSettingMigration: UserSettingMigration[] = [
|
||||
},
|
||||
];
|
||||
|
||||
// Certain settings for similar (or the same) functionality can conflict. This map
|
||||
// allows automatically adjusting settings when conflicting settings are changed.
|
||||
// See https://github.com/laurent22/joplin/issues/13048
|
||||
const conflictingSettings = [
|
||||
{
|
||||
key1: 'plugin-io.github.personalizedrefrigerator.codemirror6-settings.hideMarkdown',
|
||||
value1: 'some',
|
||||
alternate1: 'none',
|
||||
|
||||
key2: 'editor.inlineRendering',
|
||||
value2: true,
|
||||
alternate2: false,
|
||||
},
|
||||
{
|
||||
key1: 'plugin-plugin.calebjohn.rich-markdown.inlineImages',
|
||||
value1: true,
|
||||
alternate1: false,
|
||||
|
||||
key2: 'editor.imageRendering',
|
||||
value2: true,
|
||||
alternate2: false,
|
||||
},
|
||||
];
|
||||
|
||||
export type SettingMetadataSection = {
|
||||
name: string;
|
||||
isScreen?: boolean;
|
||||
@@ -724,65 +748,77 @@ class Setting extends BaseModel {
|
||||
public static setValue<T extends string>(key: T, value: SettingValueType<T>) {
|
||||
if (!this.cache_) throw new Error('Settings have not been initialized!');
|
||||
|
||||
value = this.formatValue(key, value);
|
||||
value = this.filterValue(key, value);
|
||||
|
||||
const md = this.settingMetadata(key);
|
||||
const enforceLimits = (value: SettingValueType<T>) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Partial refactor of old code before rule was applied
|
||||
if ('minimum' in md && value < md.minimum) value = md.minimum as any;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Partial refactor of old code before rule was applied
|
||||
if ('maximum' in md && value > md.maximum) value = md.maximum as any;
|
||||
const processValue = <Key extends string> (value: SettingValueType<Key>) => {
|
||||
value = this.formatValue(key, value);
|
||||
value = this.filterValue(key, value);
|
||||
|
||||
if ('minimum' in md && value < md.minimum) value = md.minimum as SettingValueType<Key>;
|
||||
if ('maximum' in md && value > md.maximum) value = md.maximum as SettingValueType<Key>;
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
for (let i = 0; i < this.cache_.length; i++) {
|
||||
const c = this.cache_[i];
|
||||
if (c.key === key) {
|
||||
if (md.isEnum === true) {
|
||||
if (!this.isAllowedEnumOption(key, value)) {
|
||||
throw new Error(_('Invalid option value: "%s". Possible values are: %s.', value, this.enumOptionsDoc(key)));
|
||||
const setValueInternal = <Key extends string> (key: Key, value: SettingValueType<Key>) => {
|
||||
value = processValue(value);
|
||||
for (let i = 0; i < this.cache_.length; i++) {
|
||||
const c = this.cache_[i];
|
||||
if (c.key === key) {
|
||||
if (md.isEnum === true) {
|
||||
if (!this.isAllowedEnumOption(key, value)) {
|
||||
throw new Error(_('Invalid option value: "%s". Possible values are: %s.', value, this.enumOptionsDoc(key)));
|
||||
}
|
||||
}
|
||||
|
||||
if (c.value === value) return;
|
||||
|
||||
this.changedKeys_.push(key);
|
||||
|
||||
// Don't log this to prevent sensitive info (passwords, auth tokens...) to end up in logs
|
||||
// logger.info('Setting: ' + key + ' = ' + c.value + ' => ' + value);
|
||||
|
||||
c.value = value;
|
||||
|
||||
this.dispatch({
|
||||
type: 'SETTING_UPDATE_ONE',
|
||||
key: key,
|
||||
value: c.value,
|
||||
});
|
||||
|
||||
this.scheduleSave();
|
||||
this.scheduleChangeEvent();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (c.value === value) return;
|
||||
this.cache_.push({
|
||||
key: key,
|
||||
value: this.formatValue(key, value),
|
||||
});
|
||||
|
||||
this.changedKeys_.push(key);
|
||||
this.dispatch({
|
||||
type: 'SETTING_UPDATE_ONE',
|
||||
key: key,
|
||||
value: this.formatValue(key, value),
|
||||
});
|
||||
|
||||
// Don't log this to prevent sensitive info (passwords, auth tokens...) to end up in logs
|
||||
// logger.info('Setting: ' + key + ' = ' + c.value + ' => ' + value);
|
||||
this.changedKeys_.push(key);
|
||||
|
||||
c.value = enforceLimits(value);
|
||||
this.scheduleSave();
|
||||
this.scheduleChangeEvent();
|
||||
};
|
||||
|
||||
this.dispatch({
|
||||
type: 'SETTING_UPDATE_ONE',
|
||||
key: key,
|
||||
value: c.value,
|
||||
});
|
||||
setValueInternal(key, value);
|
||||
|
||||
this.scheduleSave();
|
||||
this.scheduleChangeEvent();
|
||||
return;
|
||||
// Prevent conflicts. Use setValueInternal to avoid infinite recursion in the case
|
||||
// where conflictingSettings has invalid data.
|
||||
for (const conflict of conflictingSettings) {
|
||||
if (conflict.key1 === key && conflict.value1 === value) {
|
||||
setValueInternal(conflict.key2, conflict.alternate2);
|
||||
} else if (conflict.key2 === key && conflict.value2 === value) {
|
||||
setValueInternal(conflict.key1, conflict.alternate1);
|
||||
}
|
||||
}
|
||||
|
||||
value = enforceLimits(value);
|
||||
|
||||
this.cache_.push({
|
||||
key: key,
|
||||
value: this.formatValue(key, value),
|
||||
});
|
||||
|
||||
this.dispatch({
|
||||
type: 'SETTING_UPDATE_ONE',
|
||||
key: key,
|
||||
value: this.formatValue(key, value),
|
||||
});
|
||||
|
||||
this.changedKeys_.push(key);
|
||||
|
||||
this.scheduleSave();
|
||||
this.scheduleChangeEvent();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
|
||||
Reference in New Issue
Block a user