|
|
|
@ -1,11 +1,12 @@
|
|
|
|
|
import React, { memo, useState, useEffect } from 'react';
|
|
|
|
|
import React, { memo, useEffect, useState } from 'react';
|
|
|
|
|
import { unstable_batchedUpdates } from 'react-dom';
|
|
|
|
|
import { toPlural } from '@vizality/util/string';
|
|
|
|
|
import { useForceUpdate } from '@vizality/hooks';
|
|
|
|
|
import { contextMenu } from '@vizality/webpack';
|
|
|
|
|
import { Events } from '@vizality/constants';
|
|
|
|
|
import { Messages } from '@vizality/i18n';
|
|
|
|
|
|
|
|
|
|
import { Divider, FormTitle, Anchor, Icon, LazyImage, Button, Switch } from '..';
|
|
|
|
|
import { Divider, FormTitle, Anchor, Icon, LazyImage, Button, Switch, OverflowTooltip } from '..';
|
|
|
|
|
import { AddonContextMenu } from '.';
|
|
|
|
|
|
|
|
|
|
const { openContextMenu } = contextMenu;
|
|
|
|
@ -78,7 +79,7 @@ const Permissions = memo(({ permissions }) => {
|
|
|
|
|
*/
|
|
|
|
|
const Author = memo(({ author }) => {
|
|
|
|
|
return (
|
|
|
|
|
<div className='vz-addon-card-author-wrapper'>
|
|
|
|
|
<OverflowTooltip className='vz-addon-card-author-wrapper' text={author.name || author}>
|
|
|
|
|
<Anchor
|
|
|
|
|
type='user'
|
|
|
|
|
userId={author.id}
|
|
|
|
@ -86,7 +87,7 @@ const Author = memo(({ author }) => {
|
|
|
|
|
>
|
|
|
|
|
{author.name || author}
|
|
|
|
|
</Anchor>
|
|
|
|
|
</div>
|
|
|
|
|
</OverflowTooltip>
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
@ -106,44 +107,35 @@ const Description = memo(({ description }) => (
|
|
|
|
|
* Addon details.
|
|
|
|
|
* @component
|
|
|
|
|
*/
|
|
|
|
|
const Details = memo(() => {
|
|
|
|
|
const Details = memo(({ stars }) => {
|
|
|
|
|
const downloads = Math.floor(Math.random() * (7777777 - 0)).toLocaleString();
|
|
|
|
|
return (
|
|
|
|
|
<div className='vz-addon-card-details'>
|
|
|
|
|
<div className='vz-addon-card-detail-wrapper'>
|
|
|
|
|
<div className='vz-addon-card-detail-label'>Rating</div>
|
|
|
|
|
<div className='vz-addon-card-detail-value-wrapper'>
|
|
|
|
|
<OverflowTooltip text={`${stars} Stars`} className='vz-addon-card-detail-value-wrapper'>
|
|
|
|
|
<Icon
|
|
|
|
|
className='vz-addon-card-detail-value-icon-wrapper vz-addon-card-rating-icon-wrapper'
|
|
|
|
|
iconClassName='vz-addon-card-rating-icon'
|
|
|
|
|
name='Star'
|
|
|
|
|
size='14'
|
|
|
|
|
/>
|
|
|
|
|
<div className='vz-addon-card-detail-value vz-addon-card-detail-rating-number'>5</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className='vz-addon-card-detail-wrapper'>
|
|
|
|
|
<div className='vz-addon-card-detail-label'>Downloads</div>
|
|
|
|
|
<div className='vz-addon-card-detail-value-wrapper'>
|
|
|
|
|
<Icon
|
|
|
|
|
className='vz-addon-card-detail-value-icon-wrapper vz-addon-card-rating-icon-wrapper'
|
|
|
|
|
iconClassName='vz-addon-card-rating-icon'
|
|
|
|
|
name='Download'
|
|
|
|
|
size='14'
|
|
|
|
|
size='18'
|
|
|
|
|
/>
|
|
|
|
|
<div className='vz-addon-card-detail-value vz-addon-card-detail-downloads-count'>123,663</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className='vz-addon-card-detail-value vz-addon-card-detail-rating-number'>
|
|
|
|
|
{stars}
|
|
|
|
|
</div>
|
|
|
|
|
</OverflowTooltip>
|
|
|
|
|
</div>
|
|
|
|
|
<div className='vz-addon-card-detail-wrapper'>
|
|
|
|
|
<div className='vz-addon-card-detail-label'>Last Updated</div>
|
|
|
|
|
<div className='vz-addon-card-detail-value-wrapper'>
|
|
|
|
|
<OverflowTooltip text={`${downloads} Downloads`} className='vz-addon-card-detail-value-wrapper'>
|
|
|
|
|
<Icon
|
|
|
|
|
className='vz-addon-card-detail-value-icon-wrapper vz-addon-card-rating-icon-wrapper'
|
|
|
|
|
iconClassName='vz-addon-card-rating-icon'
|
|
|
|
|
name='ClockReverse'
|
|
|
|
|
size='14'
|
|
|
|
|
name='CloudDownload'
|
|
|
|
|
size='18'
|
|
|
|
|
/>
|
|
|
|
|
<div className='vz-addon-card-detail-value vz-addon-card-detail-updated-date'>11/26/2020</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div className='vz-addon-card-detail-value vz-addon-card-detail-downloads-count'>
|
|
|
|
|
{downloads}
|
|
|
|
|
</div>
|
|
|
|
|
</OverflowTooltip>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
@ -155,7 +147,7 @@ const Details = memo(() => {
|
|
|
|
|
* @param {object} props
|
|
|
|
|
* @param {string} props.icon Addon icon
|
|
|
|
|
*/
|
|
|
|
|
const AddonIcon = ({ icon }) => {
|
|
|
|
|
const AddonIcon = memo(({ icon }) => {
|
|
|
|
|
return (
|
|
|
|
|
<div className='vz-addon-card-icon'>
|
|
|
|
|
<LazyImage
|
|
|
|
@ -165,7 +157,7 @@ const AddonIcon = ({ icon }) => {
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Addon footer. Used in addon cards.
|
|
|
|
@ -178,12 +170,12 @@ const AddonIcon = ({ icon }) => {
|
|
|
|
|
* @param {boolean} props.isInstalled Is installed
|
|
|
|
|
* @param {function(!props.isEnabled)} props.onToggle Toggle handler
|
|
|
|
|
*/
|
|
|
|
|
const Footer = memo(({ addon, type, hasSettings, isEnabled, isInstalled, onToggle }) => {
|
|
|
|
|
const Footer = memo(({ addon, type, community, hasSettings, isEnabled, isInstalled, onToggle }) => {
|
|
|
|
|
return (
|
|
|
|
|
<div className='vz-addon-card-footer-wrapper'>
|
|
|
|
|
<div className='vz-addon-card-footer'>
|
|
|
|
|
<div className='vz-addon-card-footer-section-left'>
|
|
|
|
|
{isInstalled &&
|
|
|
|
|
{!community && isInstalled &&
|
|
|
|
|
<div className='vz-addon-card-uninstall'>
|
|
|
|
|
<Button
|
|
|
|
|
onClick={evt => {
|
|
|
|
@ -198,43 +190,90 @@ const Footer = memo(({ addon, type, hasSettings, isEnabled, isInstalled, onToggl
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
{/* <div className='vz-addon-card-tags'>
|
|
|
|
|
<div className='vz-addon-card-tag'>
|
|
|
|
|
Pie
|
|
|
|
|
</div>
|
|
|
|
|
<div className='vz-addon-card-tag'>
|
|
|
|
|
Lazer Beams
|
|
|
|
|
</div>
|
|
|
|
|
<div className='vz-addon-card-tag'>
|
|
|
|
|
Stuff
|
|
|
|
|
</div>
|
|
|
|
|
</div> */}
|
|
|
|
|
{community && <Details stars={addon.stars} />}
|
|
|
|
|
</div>
|
|
|
|
|
<div className='vz-addon-card-footer-section-right'>
|
|
|
|
|
{isInstalled && hasSettings &&
|
|
|
|
|
{!community && isInstalled && hasSettings &&
|
|
|
|
|
<div className='vz-addon-card-settings-button'>
|
|
|
|
|
<Icon
|
|
|
|
|
className='vz-addon-card-settings-button-icon-wrapper'
|
|
|
|
|
iconClassName='vz-addon-card-settings-button-icon'
|
|
|
|
|
name='Gear'
|
|
|
|
|
tooltip='Settings'
|
|
|
|
|
onClick={() => vizality.api.routes.navigateTo(`/vizality/${toPlural(type)}/${addon.addonId}`)}
|
|
|
|
|
onClick={evt => {
|
|
|
|
|
evt?.persist?.();
|
|
|
|
|
evt?.preventDefault?.();
|
|
|
|
|
vizality.api.routes.navigateTo(`/vizality/${type}/${addon.addonId}/settings`);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
<div className='vz-addon-card-toggle-wrapper'>
|
|
|
|
|
<Switch
|
|
|
|
|
className='vz-addon-card-toggle'
|
|
|
|
|
value={isEnabled}
|
|
|
|
|
onChange={() => onToggle(!isEnabled)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
{!community && (
|
|
|
|
|
<div className='vz-addon-card-toggle-wrapper'>
|
|
|
|
|
<Switch
|
|
|
|
|
className='vz-addon-card-toggle'
|
|
|
|
|
checked={isEnabled}
|
|
|
|
|
onChange={async v => onToggle(v)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
{community && (
|
|
|
|
|
<div className='vz-addon-card-community-action'>
|
|
|
|
|
{isInstalled
|
|
|
|
|
? (
|
|
|
|
|
<div className='vz-addon-card-uninstall'>
|
|
|
|
|
<Button
|
|
|
|
|
onClick={evt => {
|
|
|
|
|
evt.stopPropagation();
|
|
|
|
|
vizality.manager[toPlural(type)].uninstall(addon.addonId);
|
|
|
|
|
}}
|
|
|
|
|
color={Button.Colors.RED}
|
|
|
|
|
look={Button.Looks.FILLED}
|
|
|
|
|
size={Button.Sizes.ICON}
|
|
|
|
|
>
|
|
|
|
|
<Icon name='Trash' tooltip='Uninstall' />
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
: (
|
|
|
|
|
<Button
|
|
|
|
|
onClick={evt => {
|
|
|
|
|
evt.stopPropagation();
|
|
|
|
|
vizality.manager[toPlural(type)].install(addon.addonId);
|
|
|
|
|
}}
|
|
|
|
|
color={Button.Colors.GREEN}
|
|
|
|
|
look={Button.Looks.FILLED}
|
|
|
|
|
size={Button.Sizes.SMALL}
|
|
|
|
|
>
|
|
|
|
|
Install
|
|
|
|
|
</Button>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const Banner = memo(({ addon }) => {
|
|
|
|
|
const hasBanner = Boolean(addon.manifest.banner);
|
|
|
|
|
return (
|
|
|
|
|
<div className='vz-addon-card-banner-wrapper'>
|
|
|
|
|
<div className='vz-addon-card-banner-inner' >
|
|
|
|
|
{hasBanner && (
|
|
|
|
|
<LazyImage
|
|
|
|
|
className='vz-addon-card-banner-image-wrapper'
|
|
|
|
|
imageClassName='vz-addon-card-banner-image'
|
|
|
|
|
src={addon.manifest.banner}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Addon card in card layout.
|
|
|
|
|
* @component
|
|
|
|
@ -246,19 +285,18 @@ const Footer = memo(({ addon, type, hasSettings, isEnabled, isInstalled, onToggl
|
|
|
|
|
* @param {boolean} props.isInstalled Is installed
|
|
|
|
|
* @param {function()} props.onToggle Toggle handler
|
|
|
|
|
*/
|
|
|
|
|
const AddonCard = memo(({ addon, type, hasSettings, isEnabled, isInstalled, onToggle }) => {
|
|
|
|
|
const AddonCard = memo(({ addon, type, community, hasSettings, isEnabled, isInstalled, onToggle }) => {
|
|
|
|
|
return (
|
|
|
|
|
<div className='vz-addon-card-header-wrapper'>
|
|
|
|
|
{/* {showPreviewImages && <Previews {...props} />} */}
|
|
|
|
|
<div className='vz-addon-card-content-wrapper'>
|
|
|
|
|
<div className='vz-addon-card-content'>
|
|
|
|
|
<div className='vz-addon-card-header'>
|
|
|
|
|
<AddonIcon icon={addon.manifest.icon} />
|
|
|
|
|
<div className='vz-addon-card-metadata'>
|
|
|
|
|
<div className='vz-addon-card-name-version'>
|
|
|
|
|
<div className='vz-addon-card-name'>
|
|
|
|
|
<OverflowTooltip className='vz-addon-card-name' text={addon.manifest.name}>
|
|
|
|
|
{addon.manifest.name}
|
|
|
|
|
</div>
|
|
|
|
|
</OverflowTooltip>
|
|
|
|
|
<span className='vz-addon-card-version'>
|
|
|
|
|
{addon.manifest.version}
|
|
|
|
|
</span>
|
|
|
|
@ -269,6 +307,7 @@ const AddonCard = memo(({ addon, type, hasSettings, isEnabled, isInstalled, onTo
|
|
|
|
|
<Description description={addon.manifest.description} />
|
|
|
|
|
<Permissions permissions={addon.manifest.permissions} />
|
|
|
|
|
<Footer
|
|
|
|
|
community={community}
|
|
|
|
|
addon={addon}
|
|
|
|
|
type={type}
|
|
|
|
|
hasSettings={hasSettings}
|
|
|
|
@ -293,7 +332,10 @@ const AddonCard = memo(({ addon, type, hasSettings, isEnabled, isInstalled, onTo
|
|
|
|
|
* @param {boolean} props.isInstalled Is installed
|
|
|
|
|
* @param {function()} props.onToggle Toggle handler
|
|
|
|
|
*/
|
|
|
|
|
const AddonCardCompact = memo(({ addon, type, hasSettings, isEnabled, isInstalled, onToggle }) => {
|
|
|
|
|
const AddonCardCompact = memo(({ addon, type, community, hasSettings, isEnabled, isInstalled, onToggle }) => {
|
|
|
|
|
const [ installing, setInstalling ] = useState(false);
|
|
|
|
|
const [ installFailed, setInstallFailed ] = useState(false);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className='vz-addon-card-header-wrapper'>
|
|
|
|
|
<div className='vz-addon-card-content-wrapper'>
|
|
|
|
@ -302,49 +344,79 @@ const AddonCardCompact = memo(({ addon, type, hasSettings, isEnabled, isInstalle
|
|
|
|
|
<AddonIcon icon={addon.manifest.icon} />
|
|
|
|
|
<div className='vz-addon-card-metadata'>
|
|
|
|
|
<div className='vz-addon-card-name-version'>
|
|
|
|
|
<div className='vz-addon-card-name'>
|
|
|
|
|
<OverflowTooltip className='vz-addon-card-name' text={addon.manifest.name}>
|
|
|
|
|
{addon.manifest.name}
|
|
|
|
|
</div>
|
|
|
|
|
<span className='vz-addon-card-version'>
|
|
|
|
|
{addon.manifest.version}
|
|
|
|
|
</span>
|
|
|
|
|
</OverflowTooltip>
|
|
|
|
|
</div>
|
|
|
|
|
<Author author={addon.manifest.author} />
|
|
|
|
|
</div>
|
|
|
|
|
{false && <Details />}
|
|
|
|
|
<div className='vz-addon-card-actions'>
|
|
|
|
|
{isInstalled &&
|
|
|
|
|
<div className='vz-addon-card-uninstall'>
|
|
|
|
|
<Icon
|
|
|
|
|
className='vz-addon-card-uninstall-button-wrapper'
|
|
|
|
|
iconClassName='vz-addon-card-uninstall-button'
|
|
|
|
|
name='Trash'
|
|
|
|
|
tooltip='Uninstall'
|
|
|
|
|
onClick={evt => {
|
|
|
|
|
evt.stopPropagation();
|
|
|
|
|
vizality.manager[toPlural(type)].uninstall(addon.addonId);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
{hasSettings && (
|
|
|
|
|
{!community && hasSettings && (
|
|
|
|
|
<div className='vz-addon-card-settings'>
|
|
|
|
|
<Icon
|
|
|
|
|
className='vz-addon-card-settings-button-wrapper'
|
|
|
|
|
iconClassName='vz-addon-card-settings-button'
|
|
|
|
|
name='Gear'
|
|
|
|
|
tooltip='Settings'
|
|
|
|
|
onClick={() => void 0}
|
|
|
|
|
onClick={evt => {
|
|
|
|
|
evt?.persist?.();
|
|
|
|
|
evt?.preventDefault?.();
|
|
|
|
|
vizality.api.routes.navigateTo(`/vizality/${type}/${addon.addonId}/settings`);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
{community && (
|
|
|
|
|
isInstalled
|
|
|
|
|
? (
|
|
|
|
|
<div className='vz-addon-card-uninstall'>
|
|
|
|
|
<Button
|
|
|
|
|
onClick={evt => {
|
|
|
|
|
evt.stopPropagation();
|
|
|
|
|
vizality.manager[toPlural(type)].uninstall(addon.addonId);
|
|
|
|
|
}}
|
|
|
|
|
color={Button.Colors.RED}
|
|
|
|
|
look={Button.Looks.FILLED}
|
|
|
|
|
size={Button.Sizes.ICON}
|
|
|
|
|
>
|
|
|
|
|
<Icon name='Trash' tooltip='Uninstall' />
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
: (
|
|
|
|
|
<div className='vz-addon-card-install'>
|
|
|
|
|
<Button
|
|
|
|
|
onClick={evt => unstable_batchedUpdates(async () => {
|
|
|
|
|
evt.stopPropagation();
|
|
|
|
|
setInstallFailed(false);
|
|
|
|
|
setInstalling(true);
|
|
|
|
|
await vizality.manager[toPlural(type)].install(addon.addonId)
|
|
|
|
|
.then(() => setInstalling(false))
|
|
|
|
|
.catch(() => unstable_batchedUpdates(() => {
|
|
|
|
|
setInstalling(false);
|
|
|
|
|
setInstallFailed(true);
|
|
|
|
|
}));
|
|
|
|
|
})}
|
|
|
|
|
disabled={installing}
|
|
|
|
|
submitting={installing}
|
|
|
|
|
color={installFailed ? Button.Colors.YELLOW : Button.Colors.GREEN}
|
|
|
|
|
look={Button.Looks.FILLED}
|
|
|
|
|
size={Button.Sizes.ICON}
|
|
|
|
|
>
|
|
|
|
|
<Icon name={installFailed ? 'Retry' : 'CloudDownload'} tooltip={installFailed ? 'Retry' : 'Install'} />
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
)}
|
|
|
|
|
{!community && (
|
|
|
|
|
<div className='vz-addon-card-toggle-wrapper'>
|
|
|
|
|
<Switch
|
|
|
|
|
className='vz-addon-card-toggle'
|
|
|
|
|
checked={isEnabled}
|
|
|
|
|
onChange={async v => onToggle(v)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
<div className='vz-addon-card-toggle-wrapper'>
|
|
|
|
|
<Switch
|
|
|
|
|
className='vz-addon-card-toggle'
|
|
|
|
|
value={isEnabled}
|
|
|
|
|
onChange={() => onToggle(!isEnabled)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
@ -364,7 +436,7 @@ const AddonCardCompact = memo(({ addon, type, hasSettings, isEnabled, isInstalle
|
|
|
|
|
* @param {boolean} props.isInstalled Is installed
|
|
|
|
|
* @param {function()} props.onToggle Toggle handler
|
|
|
|
|
*/
|
|
|
|
|
const AddonCardCover = memo(({ addon, type, hasSettings, isEnabled, isInstalled, onToggle }) => {
|
|
|
|
|
const AddonCardCover = memo(({ addon, type, community, hasSettings, isEnabled, isInstalled, onToggle }) => {
|
|
|
|
|
return (
|
|
|
|
|
<div className='vz-addon-card-header-wrapper'>
|
|
|
|
|
<div className='vz-addon-card-content-wrapper'>
|
|
|
|
@ -373,9 +445,9 @@ const AddonCardCover = memo(({ addon, type, hasSettings, isEnabled, isInstalled,
|
|
|
|
|
<div className='vz-addon-card-header'>
|
|
|
|
|
<div className='vz-addon-card-metadata'>
|
|
|
|
|
<div className='vz-addon-card-name-version'>
|
|
|
|
|
<div className='vz-addon-card-name'>
|
|
|
|
|
<OverflowTooltip className='vz-addon-card-name' text={addon.manifest.name}>
|
|
|
|
|
{addon.manifest.name}
|
|
|
|
|
</div>
|
|
|
|
|
</OverflowTooltip>
|
|
|
|
|
<span className='vz-addon-card-version'>
|
|
|
|
|
{addon.manifest.version}
|
|
|
|
|
</span>
|
|
|
|
@ -386,6 +458,7 @@ const AddonCardCover = memo(({ addon, type, hasSettings, isEnabled, isInstalled,
|
|
|
|
|
<Description description={addon.manifest.description} />
|
|
|
|
|
<Permissions permissions={addon.manifest.permissions} />
|
|
|
|
|
<Footer
|
|
|
|
|
community={community}
|
|
|
|
|
addon={addon}
|
|
|
|
|
type={type}
|
|
|
|
|
hasSettings={hasSettings}
|
|
|
|
@ -410,20 +483,18 @@ const AddonCardCover = memo(({ addon, type, hasSettings, isEnabled, isInstalled,
|
|
|
|
|
* @param {boolean} props.isInstalled Is installed
|
|
|
|
|
* @param {function()} props.onToggle Toggle handler
|
|
|
|
|
*/
|
|
|
|
|
const AddonCardList = memo(({ addon, type, hasSettings, isEnabled, isInstalled, onToggle, showPreviewImages }) => {
|
|
|
|
|
const AddonCardList = memo(({ addon, type, community, hasSettings, isEnabled, isInstalled, onToggle }) => {
|
|
|
|
|
return (
|
|
|
|
|
<div className='vz-addon-card-header-wrapper'>
|
|
|
|
|
{/* {showPreviewImages && <Previews {...props} />} */}
|
|
|
|
|
{!showPreviewImages && <AddonIcon icon={addon.manifest.icon} />}
|
|
|
|
|
<AddonIcon icon={addon.manifest.icon} />
|
|
|
|
|
<div className='vz-addon-card-content-wrapper'>
|
|
|
|
|
<div className='vz-addon-card-content'>
|
|
|
|
|
<div className='vz-addon-card-header'>
|
|
|
|
|
{/* {showPreviewImages && <AddonIcon icon={manifest.icon} />} */}
|
|
|
|
|
<div className='vz-addon-card-metadata'>
|
|
|
|
|
<div className='vz-addon-card-name-version'>
|
|
|
|
|
<div className='vz-addon-card-name'>
|
|
|
|
|
<OverflowTooltip className='vz-addon-card-name' text={addon.manifest.name}>
|
|
|
|
|
{addon.manifest.name}
|
|
|
|
|
</div>
|
|
|
|
|
</OverflowTooltip>
|
|
|
|
|
<span className='vz-addon-card-version'>
|
|
|
|
|
{addon.manifest.version}
|
|
|
|
|
</span>
|
|
|
|
@ -434,6 +505,7 @@ const AddonCardList = memo(({ addon, type, hasSettings, isEnabled, isInstalled,
|
|
|
|
|
<Description description={addon.manifest.description} />
|
|
|
|
|
<Permissions permissions={addon.manifest.permissions} />
|
|
|
|
|
<Footer
|
|
|
|
|
community={community}
|
|
|
|
|
addon={addon}
|
|
|
|
|
type={type}
|
|
|
|
|
hasSettings={hasSettings}
|
|
|
|
@ -455,8 +527,49 @@ const AddonCardList = memo(({ addon, type, hasSettings, isEnabled, isInstalled,
|
|
|
|
|
* @param {string} props.type Addon type
|
|
|
|
|
* @param {string} props.display Addon card display type
|
|
|
|
|
*/
|
|
|
|
|
export default memo(({ addonId, type, display, enabled, installed, settings, updates }) => {
|
|
|
|
|
const addon = vizality.manager[toPlural(type)].get(addonId);
|
|
|
|
|
export default memo(({ addonId, type, display, community, isEnabled, isInstalled, hasSettings, hasUpdates }) => {
|
|
|
|
|
isEnabled = typeof isEnabled === 'boolean' ? isEnabled : vizality.manager[toPlural(type)].isEnabled(addonId);
|
|
|
|
|
isInstalled = typeof isInstalled === 'boolean' ? isInstalled : vizality.manager[toPlural(type)].isInstalled(addonId);
|
|
|
|
|
hasSettings = typeof hasSettings === 'boolean' ? hasSettings : vizality.manager[toPlural(type)].hasSettings(addonId);
|
|
|
|
|
const forceUpdate = useForceUpdate();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handles addon enables and disables.
|
|
|
|
|
* @param {object} payload Event payload
|
|
|
|
|
* @param {string} payload.addonId Addon ID
|
|
|
|
|
* @param {string} payload.type Addon type
|
|
|
|
|
*/
|
|
|
|
|
const handleEnableDisable = payload => {
|
|
|
|
|
/**
|
|
|
|
|
* If this is the addon being enabled/disabled, force rerender the card.
|
|
|
|
|
*/
|
|
|
|
|
if (payload.addonId === addonId && payload.type === type) {
|
|
|
|
|
forceUpdate();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add event listeners for addon enable and addon disable.
|
|
|
|
|
*/
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
vizality.manager[toPlural(type)].on(Events.VIZALITY_ADDON_ENABLE, handleEnableDisable);
|
|
|
|
|
vizality.manager[toPlural(type)].on(Events.VIZALITY_ADDON_DISABLE, handleEnableDisable);
|
|
|
|
|
return () => {
|
|
|
|
|
/**
|
|
|
|
|
* Remove the event listeners.
|
|
|
|
|
*/
|
|
|
|
|
vizality.manager[toPlural(type)].removeListener(Events.VIZALITY_ADDON_ENABLE, handleEnableDisable);
|
|
|
|
|
vizality.manager[toPlural(type)].removeListener(Events.VIZALITY_ADDON_DISABLE, handleEnableDisable);
|
|
|
|
|
};
|
|
|
|
|
}, [ type, addonId, display, community, isEnabled, isInstalled, hasSettings ]);
|
|
|
|
|
|
|
|
|
|
let addon;
|
|
|
|
|
if (community) {
|
|
|
|
|
addon = vizality.manager.community[toPlural(type)].get(addonId);
|
|
|
|
|
} else {
|
|
|
|
|
addon = vizality.manager[toPlural(type)].get(addonId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!addon) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -469,58 +582,68 @@ export default memo(({ addonId, type, display, enabled, installed, settings, upd
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handles addon card context menus.
|
|
|
|
|
* @param {document#event:mousedown} evt Mousedown event
|
|
|
|
|
* @returns {void}
|
|
|
|
|
*/
|
|
|
|
|
const handleContextMenu = evt => {
|
|
|
|
|
return openContextMenu(evt, () =>
|
|
|
|
|
<AddonContextMenu
|
|
|
|
|
community={community}
|
|
|
|
|
addonId={addonId}
|
|
|
|
|
type={type}
|
|
|
|
|
hasSettings={vizality.manager[toPlural(type)].hasSettings(addonId)}
|
|
|
|
|
isEnabled={vizality.manager[toPlural(type)].isEnabled(addonId)}
|
|
|
|
|
isInstalled={vizality.manager[toPlural(type)].isInstalled(addonId)}
|
|
|
|
|
hasSettings={hasSettings}
|
|
|
|
|
isEnabled={isEnabled}
|
|
|
|
|
isInstalled={isInstalled}
|
|
|
|
|
onToggle={onToggle}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getAddonDisplayRender = display => {
|
|
|
|
|
const Addon = ({ display }) => {
|
|
|
|
|
switch (display) {
|
|
|
|
|
case 'compact': return (
|
|
|
|
|
<AddonCardCompact
|
|
|
|
|
community={community}
|
|
|
|
|
addon={addon}
|
|
|
|
|
type={type}
|
|
|
|
|
hasSettings={vizality.manager[toPlural(type)].hasSettings(addonId)}
|
|
|
|
|
isEnabled={vizality.manager[toPlural(type)].isEnabled(addonId)}
|
|
|
|
|
isInstalled={vizality.manager[toPlural(type)].isInstalled(addonId)}
|
|
|
|
|
hasSettings={hasSettings}
|
|
|
|
|
isEnabled={isEnabled}
|
|
|
|
|
isInstalled={isInstalled}
|
|
|
|
|
onToggle={onToggle}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
case 'cover': return (
|
|
|
|
|
<AddonCardCover
|
|
|
|
|
community={community}
|
|
|
|
|
addon={addon}
|
|
|
|
|
type={type}
|
|
|
|
|
hasSettings={vizality.manager[toPlural(type)].hasSettings(addonId)}
|
|
|
|
|
isEnabled={vizality.manager[toPlural(type)].isEnabled(addonId)}
|
|
|
|
|
isInstalled={vizality.manager[toPlural(type)].isInstalled(addonId)}
|
|
|
|
|
hasSettings={hasSettings}
|
|
|
|
|
isEnabled={isEnabled}
|
|
|
|
|
isInstalled={isInstalled}
|
|
|
|
|
onToggle={onToggle}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
case 'list': return (
|
|
|
|
|
<AddonCardList
|
|
|
|
|
community={community}
|
|
|
|
|
addon={addon}
|
|
|
|
|
type={type}
|
|
|
|
|
hasSettings={vizality.manager[toPlural(type)].hasSettings(addonId)}
|
|
|
|
|
isEnabled={vizality.manager[toPlural(type)].isEnabled(addonId)}
|
|
|
|
|
isInstalled={vizality.manager[toPlural(type)].isInstalled(addonId)}
|
|
|
|
|
hasSettings={hasSettings}
|
|
|
|
|
isEnabled={isEnabled}
|
|
|
|
|
isInstalled={isInstalled}
|
|
|
|
|
onToggle={onToggle}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
default: return (
|
|
|
|
|
<AddonCard
|
|
|
|
|
community={community}
|
|
|
|
|
addon={addon}
|
|
|
|
|
type={type}
|
|
|
|
|
hasSettings={vizality.manager[toPlural(type)].hasSettings(addonId)}
|
|
|
|
|
isEnabled={vizality.manager[toPlural(type)].isEnabled(addonId)}
|
|
|
|
|
isInstalled={vizality.manager[toPlural(type)].isInstalled(addonId)}
|
|
|
|
|
hasSettings={hasSettings}
|
|
|
|
|
isEnabled={isEnabled}
|
|
|
|
|
isInstalled={isInstalled}
|
|
|
|
|
onToggle={onToggle}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
@ -531,17 +654,16 @@ export default memo(({ addonId, type, display, enabled, installed, settings, upd
|
|
|
|
|
<div
|
|
|
|
|
className='vz-addon-card'
|
|
|
|
|
vz-addon-id={addonId}
|
|
|
|
|
vz-addon-type={type}
|
|
|
|
|
onContextMenu={handleContextMenu}
|
|
|
|
|
onClick={evt => {
|
|
|
|
|
/*
|
|
|
|
|
* if (evt.target.matches('input') || evt.target.matches('button') || evt.target.matches('svg') || evt.target.matches('a')) {
|
|
|
|
|
* return;
|
|
|
|
|
* }
|
|
|
|
|
* vizality.api.routes.navigateTo(`/${toPlural(type)}/${addonId}`);
|
|
|
|
|
*/
|
|
|
|
|
if (evt.target.matches('input') || evt.target.matches('button') || evt.target.matches('svg') || evt.target.matches('a')) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
vizality.api.routes.navigateTo(`/vizality/${type}/${addonId}`);
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{getAddonDisplayRender(display)}
|
|
|
|
|
<Addon display={display} />
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|