category: getAddonEventCategory()

in src/amo/installAddon.js [97:259]


          category: getAddonEventCategory(type, INSTALL_DOWNLOAD_FAILED_ACTION),
          label: guid,
        });
      }
    } else if (event.type === 'onInstallCancelled') {
      dispatch({
        type: INSTALL_CANCELLED,
        payload: { guid },
      });

      _tracking.sendEvent({
        action: getAddonTypeForTracking(type),
        category: getAddonEventCategory(type, INSTALL_CANCELLED_ACTION),
        label: guid,
      });
    } else if (event.type === 'onInstallFailed') {
      dispatch(setInstallError({ guid, error: INSTALL_FAILED }));
    }
  };
}

type WithInstallHelpersProps = {|
  addon: AddonType | null,
  version?: AddonVersionType | null,
|};

type WithInstallHelpersPropsFromState = {|
  WrappedComponent: React.ComponentType<any>,
  clientApp: string,
  currentVersion: AddonVersionType | null,
|};

type WithInstallHelpersDefaultProps = {|
  _addonManager: typeof addonManager,
  _getPromotedCategory: typeof getPromotedCategory,
  _log: typeof log,
  _tracking: typeof tracking,
|};

type WithInstallHelpersInternalProps = {|
  ...WithInstallHelpersProps,
  ...WithInstallHelpersPropsFromState,
  ...WithInstallHelpersDefaultProps,
  dispatch: DispatchFunc,
|};

type UninstallParams = {|
  guid: string,
  name: string,
  type: string,
|};

// Props passed to the WrappedComponent.
export type WithInstallHelpersInjectedProps = {|
  enable: () => Promise<any>,
  hasAddonManager: boolean,
  install: () => Promise<any>,
  setCurrentStatus: () => Promise<any>,
  uninstall: (UninstallParams) => Promise<any>,
|};

export class WithInstallHelpers extends React.Component<WithInstallHelpersInternalProps> {
  static defaultProps: WithInstallHelpersDefaultProps = {
    _addonManager: addonManager,
    _getPromotedCategory: getPromotedCategory,
    _log: log,
    _tracking: tracking,
  };

  componentDidMount() {
    this.setCurrentStatus();
  }

  componentDidUpdate(prevProps: WithInstallHelpersInternalProps) {
    const oldGuid = prevProps.addon ? prevProps.addon.guid : null;
    const newGuid = this.props.addon ? this.props.addon.guid : null;

    if (newGuid && newGuid !== oldGuid) {
      this.props._log.info('Updating add-on status');
      this.setCurrentStatus();
    }
  }

  setCurrentStatus(): Promise<void> {
    const { _addonManager, _log, addon, currentVersion, dispatch } = this.props;

    if (!_addonManager.hasAddonManager()) {
      _log.info('No addon manager, cannot set add-on status');
      return Promise.resolve();
    }

    if (!addon) {
      _log.debug('no addon, aborting setCurrentStatus()');
      return Promise.resolve();
    }

    const { guid, type } = addon;
    const payload = { guid, url: currentVersion?.file?.url };

    _log.info('Setting add-on status');
    return _addonManager
      .getAddon(guid)
      .then(
        (clientAddon) => {
          const status = _addonManager.getAddonStatus({
            addon: clientAddon,
            type,
          });

          dispatch(
            setInstallState({
              ...payload,
              status,
              canUninstall: clientAddon.canUninstall,
              version: clientAddon.version,
              name: clientAddon.name,
            }),
          );
        },
        (error) => {
          _log.info(oneLine`Add-on "${guid}" not found so setting status to
            UNINSTALLED; exact error: ${error}`);
          dispatch(setInstallState({ ...payload, status: UNINSTALLED }));
        },
      )
      .catch((error) => {
        _log.error(`Caught error from addonManager: ${error}`);
        // Dispatch a generic error should the success/error functions throw.
        dispatch(
          setInstallState({
            guid,
            status: ERROR,
            error: FATAL_ERROR,
          }),
        );
      });
  }

  enable(): Promise<void> {
    const { _addonManager, _log, _tracking, dispatch, addon } = this.props;

    invariant(addon, 'need an addon to call enable()');

    const { guid, type } = addon;

    return _addonManager
      .enable(guid)
      .then(() => {
        _tracking.sendEvent({
          action: getAddonTypeForTracking(type),
          category: getAddonEventCategory(type, ENABLE_ACTION),
          label: guid,
        });
      })
      .catch((err) => {
        if (err && err.message === SET_ENABLE_NOT_AVAILABLE) {
          _log.info(`addon.setEnabled not available. Unable to enable ${guid}`);
        } else {
          // eslint-disable-next-line amo/only-log-strings
          _log.error(`Error while trying to enable ${guid}: %o`, err);

          dispatch(
            setInstallState({