diff --git a/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.tsx b/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.tsx
index 7670fde1c2..527547205d 100644
--- a/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.tsx
+++ b/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.tsx
@@ -26,6 +26,7 @@ interface Props {
installState?: InstallState;
updateState?: UpdateState;
themeId: number;
+ isCompatible: boolean;
onToggle?: Function;
onDelete?: Function;
onInstall?: Function;
@@ -34,28 +35,20 @@ interface Props {
function manifestToItem(manifest: PluginManifest): PluginItem {
return {
- id: manifest.id,
- name: manifest.name,
- version: manifest.version,
- description: manifest.description,
+ manifest: manifest,
enabled: true,
deleted: false,
devMode: false,
hasBeenUpdated: false,
- homepage_url: manifest.homepage_url,
};
}
export interface PluginItem {
- id: string;
- name: string;
- version: string;
- description: string;
+ manifest: PluginManifest;
enabled: boolean;
deleted: boolean;
devMode: boolean;
hasBeenUpdated: boolean;
- homepage_url: string;
}
const CellRoot = styled.div`
@@ -71,6 +64,8 @@ const CellRoot = styled.div`
margin-right: 20px;
margin-bottom: 20px;
box-shadow: 1px 1px 3px rgba(0,0,0,0.2);
+
+ opacity: ${props => props.isCompatible ? '1' : '0.6'};
`;
const CellTop = styled.div`
@@ -91,6 +86,12 @@ const CellFooter = styled.div`
flex-direction: row;
`;
+const NeedUpgradeMessage = styled.span`
+ font-family: ${props => props.theme.fontFamily};
+ color: ${props => props.theme.colorWarn};
+ font-size: ${props => props.theme.fontSize}px;
+`;
+
const DevModeLabel = styled.div`
border: 1px solid ${props => props.theme.color};
border-radius: 4px;
@@ -132,8 +133,8 @@ export default function(props: Props) {
const item = props.item ? props.item : manifestToItem(props.manifest);
const onNameClick = useCallback(() => {
- if (!props.item.homepage_url) return;
- bridge().openExternal(props.item.homepage_url);
+ if (!props.item.manifest.homepage_url) return;
+ bridge().openExternal(props.item.manifest.homepage_url);
}, [props.item]);
// For plugins in dev mode things like enabling/disabling or
@@ -194,6 +195,16 @@ export default function(props: Props) {
function renderFooter() {
if (item.devMode) return null;
+ if (!props.isCompatible) {
+ return (
+
+
+ {_('Please upgrade Joplin to use this plugin')}
+
+
+ );
+ }
+
return (
{renderDeleteButton()}
@@ -205,13 +216,13 @@ export default function(props: Props) {
}
return (
-
+
- {item.name} {item.deleted ? _('(%s)', 'Deleted') : ''}v{item.version}
+ {item.manifest.name} {item.deleted ? _('(%s)', 'Deleted') : ''}v{item.manifest.version}
{renderToggleButton()}
- {item.description}
+ {item.manifest.description}
{renderFooter()}
diff --git a/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.tsx b/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.tsx
index ba78cb7aeb..7c80dff61b 100644
--- a/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.tsx
+++ b/packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.tsx
@@ -63,20 +63,16 @@ function usePluginItems(plugins: Plugins, settings: PluginSettings): PluginItem[
};
output.push({
- id: pluginId,
- name: plugin.manifest.name,
- version: plugin.manifest.version,
- description: plugin.manifest.description,
+ manifest: plugin.manifest,
enabled: setting.enabled,
deleted: setting.deleted,
devMode: plugin.devMode,
hasBeenUpdated: setting.hasBeenUpdated,
- homepage_url: plugin.manifest.homepage_url,
});
}
output.sort((a: PluginItem, b: PluginItem) => {
- return a.name < b.name ? -1 : +1;
+ return a.manifest.name < b.manifest.name ? -1 : +1;
});
return output;
@@ -134,12 +130,12 @@ export default function(props: Props) {
const onDelete = useCallback(async (event: any) => {
const item: PluginItem = event.item;
- const confirm = await bridge().showConfirmMessageBox(_('Delete plugin "%s"?', item.name));
+ const confirm = await bridge().showConfirmMessageBox(_('Delete plugin "%s"?', item.manifest.name));
if (!confirm) return;
const newSettings = produce(pluginSettings, (draft: PluginSettings) => {
- if (!draft[item.id]) draft[item.id] = defaultPluginSetting();
- draft[item.id].deleted = true;
+ if (!draft[item.manifest.id]) draft[item.manifest.id] = defaultPluginSetting();
+ draft[item.manifest.id].deleted = true;
});
props.onChange({ value: pluginService.serializePluginSettings(newSettings) });
@@ -149,8 +145,8 @@ export default function(props: Props) {
const item: PluginItem = event.item;
const newSettings = produce(pluginSettings, (draft: PluginSettings) => {
- if (!draft[item.id]) draft[item.id] = defaultPluginSetting();
- draft[item.id].enabled = !draft[item.id].enabled;
+ if (!draft[item.manifest.id]) draft[item.manifest.id] = defaultPluginSetting();
+ draft[item.manifest.id].enabled = !draft[item.manifest.id].enabled;
});
props.onChange({ value: pluginService.serializePluginSettings(newSettings) });
@@ -213,8 +209,8 @@ export default function(props: Props) {
for (const item of items) {
if (item.deleted) continue;
- const isUpdating = updatingPluginsIds[item.id];
- const onUpdateHandler = canBeUpdatedPluginIds[item.id] ? onUpdate : null;
+ const isUpdating = updatingPluginsIds[item.manifest.id];
+ const onUpdateHandler = canBeUpdatedPluginIds[item.manifest.id] ? onUpdate : null;
let updateState = UpdateState.Idle;
if (onUpdateHandler) updateState = UpdateState.CanUpdate;
@@ -222,10 +218,11 @@ export default function(props: Props) {
if (item.hasBeenUpdated) updateState = UpdateState.HasBeenUpdated;
output.push();
diff --git a/packages/lib/services/plugins/PluginService.ts b/packages/lib/services/plugins/PluginService.ts
index 9564630207..3a1a0698c0 100644
--- a/packages/lib/services/plugins/PluginService.ts
+++ b/packages/lib/services/plugins/PluginService.ts
@@ -334,8 +334,12 @@ export default class PluginService extends BaseService {
}
}
+ public isCompatible(pluginVersion: string): boolean {
+ return compareVersions(this.appVersion_, pluginVersion) >= 0;
+ }
+
public async runPlugin(plugin: Plugin) {
- if (compareVersions(this.appVersion_, plugin.manifest.app_min_version) < 0) {
+ if (!this.isCompatible(plugin.manifest.app_min_version)) {
throw new Error(`Plugin "${plugin.id}" was disabled because it requires Joplin version ${plugin.manifest.app_min_version} and current version is ${this.appVersion_}.`);
} else {
this.store_.dispatch({