mirror of https://github.com/laurent22/joplin.git
Desktop: Sort plugin results according to recommended property, and display Recommended tag
parent
9c44133bd0
commit
d97ba57dda
|
@ -873,6 +873,16 @@ class Application extends BaseApplication {
|
|||
// });
|
||||
// }, 2000);
|
||||
|
||||
// setTimeout(() => {
|
||||
// this.dispatch({
|
||||
// type: 'NAV_GO',
|
||||
// routeName: 'Config',
|
||||
// props: {
|
||||
// defaultSection: 'plugins',
|
||||
// },
|
||||
// });
|
||||
// }, 2000);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -133,6 +133,21 @@ const StyledDescription = styled.div`
|
|||
line-height: 1.6em;
|
||||
`;
|
||||
|
||||
const RecommendedBadge = styled.a`
|
||||
font-family: ${props => props.theme.fontFamily};
|
||||
color: ${props => props.theme.colorWarn};
|
||||
font-size: ${props => props.theme.fontSize}px;
|
||||
border: 1px solid ${props => props.theme.colorWarn};
|
||||
padding: 5px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 50px;
|
||||
opacity: 0.8;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
export default function(props: Props) {
|
||||
const item = useMemo(() => {
|
||||
return props.item ? props.item : manifestToItem(props.manifest);
|
||||
|
@ -144,6 +159,10 @@ export default function(props: Props) {
|
|||
bridge().openExternal(manifest.homepage_url);
|
||||
}, [item]);
|
||||
|
||||
const onRecommendedClick = useCallback(() => {
|
||||
bridge().openExternal('https://github.com/joplin/plugins/blob/master/readme/recommended.md#recommended-plugins');
|
||||
}, []);
|
||||
|
||||
// For plugins in dev mode things like enabling/disabling or
|
||||
// uninstalling them doesn't make sense, as that should be done by
|
||||
// adding/removing them from wherever they were loaded from.
|
||||
|
@ -222,11 +241,18 @@ export default function(props: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
function renderRecommendedBadge() {
|
||||
if (props.onToggle) return null;
|
||||
if (!item.manifest._recommended) return null;
|
||||
return <RecommendedBadge href="#" title={_('The Joplin team has vetted this plugin and it meets our standards for security and performance.')} onClick={onRecommendedClick}><i className="fas fa-crown"></i></RecommendedBadge>;
|
||||
}
|
||||
|
||||
return (
|
||||
<CellRoot isCompatible={props.isCompatible}>
|
||||
<CellTop>
|
||||
<StyledNameAndVersion mb={'5px'}><StyledName onClick={onNameClick} href="#" style={{ marginRight: 5 }}>{item.manifest.name} {item.deleted ? _('(%s)', 'Deleted') : ''}</StyledName><StyledVersion>v{item.manifest.version}</StyledVersion></StyledNameAndVersion>
|
||||
{renderToggleButton()}
|
||||
{renderRecommendedBadge()}
|
||||
</CellTop>
|
||||
<CellContent>
|
||||
<StyledDescription>{item.manifest.description}</StyledDescription>
|
||||
|
|
|
@ -30,6 +30,14 @@ interface Props {
|
|||
disabled: boolean;
|
||||
}
|
||||
|
||||
function sortManifestResults(results: PluginManifest[]): PluginManifest[] {
|
||||
return results.sort((m1, m2) => {
|
||||
if (m1._recommended && !m2._recommended) return -1;
|
||||
if (!m1._recommended && m2._recommended) return +1;
|
||||
return m1.name.toLowerCase() < m2.name.toLowerCase() ? -1 : +1;
|
||||
});
|
||||
}
|
||||
|
||||
export default function(props: Props) {
|
||||
const [searchStarted, setSearchStarted] = useState(false);
|
||||
const [manifests, setManifests] = useState<PluginManifest[]>([]);
|
||||
|
@ -47,7 +55,7 @@ export default function(props: Props) {
|
|||
setSearchResultCount(null);
|
||||
} else {
|
||||
const r = await props.repoApi().search(props.searchQuery);
|
||||
setManifests(r);
|
||||
setManifests(sortManifestResults(r));
|
||||
setSearchResultCount(r.length);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -24,6 +24,13 @@ export default function manifestFromObject(o: any): PluginManifest {
|
|||
return o[name];
|
||||
};
|
||||
|
||||
const getBoolean = (name: string, required: boolean = true, defaultValue: boolean = false): boolean => {
|
||||
if (required && !o[name]) throw new Error(`Missing required field: ${name}`);
|
||||
if (!o[name]) return defaultValue;
|
||||
if (typeof o[name] !== 'boolean') throw new Error(`Field must be a boolean: ${name}`);
|
||||
return o[name];
|
||||
};
|
||||
|
||||
const permissions: PluginPermission[] = [];
|
||||
|
||||
const manifest: PluginManifest = {
|
||||
|
@ -39,6 +46,8 @@ export default function manifestFromObject(o: any): PluginManifest {
|
|||
repository_url: getString('repository_url', false),
|
||||
keywords: getStrings('keywords', false),
|
||||
permissions: permissions,
|
||||
|
||||
_recommended: getBoolean('_recommended', false, false),
|
||||
};
|
||||
|
||||
validatePluginId(manifest.id);
|
||||
|
|
|
@ -20,4 +20,6 @@ export interface PluginManifest {
|
|||
_publish_hash?: string;
|
||||
_publish_commit?: string;
|
||||
_npm_package_name?: string;
|
||||
_obsolete?: boolean;
|
||||
_recommended?: boolean;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue