Example #1
0
      onError: async (e, log) => {
        const response = await promisedModal(
          store,
          modals.showError.make({
            wind: "root",
            title: ["prompt.uninstall_error.title"],
            message: ["prompt.uninstall_error.message"],
            buttons: [
              {
                label: ["prompt.action.ok"],
                action: actions.modalResponse({}),
              },
              "cancel",
            ],
            widgetParams: { rawError: e, log },
          })
        );

        if (!response) {
          // modal was closed
          return;
        }

        logger.info(`Should remove entry anyway, performing hard uninstall`);
        try {
          await mcall(messages.UninstallPerform, { caveId, hard: true });
          store.dispatch(actions.uninstallEnded({}));
        } catch (e) {
          logger.error(`Well, even hard uninstall didn't work: ${e.stack}`);
        }
      },
Example #2
0
  watcher.on(actions.requestCaveUninstall, async (store, action) => {
    const { caveId } = action.payload;

    const { cave } = await mcall(messages.FetchCave, { caveId });
    const { game } = cave;

    // FIXME: i18n - plus, that's generally bad
    const title = game ? game.title : "this";

    store.dispatch(
      actions.openModal(
        modals.naked.make({
          wind: "root",
          title: "",
          message: ["prompt.uninstall.message", { title }],
          buttons: [
            {
              label: ["prompt.uninstall.reinstall"],
              id: "modal-reinstall",
              action: actions.queueCaveReinstall({ caveId }),
              icon: "repeat",
            },
            {
              label: ["prompt.uninstall.uninstall"],
              id: "modal-uninstall",
              action: actions.queueCaveUninstall({ caveId }),
              icon: "uninstall",
            },
            "cancel",
          ],
          widgetParams: null,
        })
      )
    );
  });
Example #3
0
        client.on(messages.PrereqsStarted, async ({ tasks }) => {
          prereqsStateParams = {
            gameTitle: game.title,
            tasks: {},
          };

          for (const name of Object.keys(tasks)) {
            const task = tasks[name];
            prereqsStateParams.tasks[name] = {
              fullName: task.fullName,
              order: task.order,
              status: PrereqStatus.Pending,
              progress: 0,
              eta: 0,
              bps: 0,
            };
          }

          prereqsModal = modalWidgets.prereqsState.make({
            window: "root",
            title: ["grid.item.installing"],
            message: "",
            widgetParams: prereqsStateParams,
            buttons: [
              {
                id: "modal-cancel",
                label: ["prompt.action.cancel"],
                action: actions.abortTask({ id: ctx.getTaskId() }),
                className: "secondary",
              },
            ],
            unclosable: true,
          });
          store.dispatch(actions.openModal(prereqsModal));
        });
Example #4
0
  watcher.on(actions.checkForGameUpdates, async (store, action) => {
    reschedule(store);

    if (!store.getState().setup.done) {
      return;
    }

    store.dispatch(
      actions.gameUpdateCheckStatus({
        checking: true,
        progress: 0,
      })
    );

    try {
      store.dispatch(
        actions.gameUpdateCheckStatus({
          checking: true,
          progress: 0,
        })
      );

      const res = await mcall(messages.CheckUpdate, {}, convo => {
        hookLogging(convo, logger);

        convo.on(messages.GameUpdateAvailable, async ({ update }) => {
          store.dispatch(actions.gameUpdateAvailable({ update }));
        });

        convo.on(messages.Progress, async ({ progress }) => {
          store.dispatch(
            actions.gameUpdateCheckStatus({
              checking: true,
              progress,
            })
          );
        });
      });

      if (!isEmpty(res.updates)) {
        for (const update of res.updates) {
          store.dispatch(actions.gameUpdateAvailable({ update }));
        }
      }

      if (!isEmpty(res.warnings)) {
        logger.warn(`Got warnings when checking for updates: `);
        for (const w of res.warnings) {
          logger.warn(w);
        }
      }
    } finally {
      store.dispatch(
        actions.gameUpdateCheckStatus({
          checking: false,
          progress: -1,
        })
      );
    }
  });
Example #5
0
File: login.ts Project: itchio/itch
  watcher.on(actions.useSavedLogin, async (store, action) => {
    const profileId = action.payload.profile.id;
    logger.info(`Attempting saved login for profile ${profileId}`);
    store.dispatch(actions.attemptLogin({}));

    try {
      const { profile } = await withTimeout(
        "Saved login",
        LOGIN_TIMEOUT,
        mcall(
          messages.ProfileUseSavedLogin,
          {
            profileId,
          },
          convo => {
            hookLogging(convo, logger);
          }
        )
      );
      logger.info(`Saved login succeeded!`);
      await loginSucceeded(store, profile);
    } catch (e) {
      // TODO: handle offline login
      const originalProfile = action.payload.profile;
      store.dispatch(
        actions.loginFailed({
          username: originalProfile.user.username,
          error: e,
        })
      );
    }
  });
Example #6
0
  const itemForOperation = (operation: IOperation): IMenuItem => {
    const localizedLabel = formatOperation(operation);
    if (operation.name === "launch") {
      return {
        localizedLabel,
        submenu: [
          {
            localizedLabel: ["prompt.action.force_close"],
            action: actions.forceCloseGameRequest({ game }),
          },
        ],
      };
    } else {
      const item: IMenuItem = {
        localizedLabel,
        enabled: false,
      };

      if (operation.type === OperationType.Download && operation.id) {
        item.submenu = [
          {
            localizedLabel: ["grid.item.discard_download"],
            action: actions.discardDownload({ id: operation.id }),
          },
        ];
      }
      return item;
    }
  };
Example #7
0
 watcher.on(actions.silentlyScanInstallLocations, async (store, action) => {
   try {
     logger.info(`Scanning install locations for items...`);
     await mcall(
       messages.InstallLocationsScan,
       {
         legacyMarketPath: legacyMarketPath(),
       },
       convo => {
         hookLogging(convo, logger);
         convo.on(messages.Progress, async ({ progress }) => {
           store.dispatch(actions.locationScanProgress({ progress }));
         });
         convo.on(messages.InstallLocationsScanYield, async ({ game }) => {
           logger.info(`Found ${game.title} - ${game.url}`);
         });
         convo.on(
           messages.InstallLocationsScanConfirmImport,
           async ({ numItems }) => {
             logger.info(`In total, found ${numItems} items.`);
             return { confirm: true };
           }
         );
       }
     );
     logger.info(`Scan complete.`);
     store.dispatch(actions.newItemsImported({}));
   } finally {
     store.dispatch(actions.locationScanDone({}));
   }
 });
Example #8
0
 private onMessage(logger: Logger, msg: ISM) {
   if (msg.type === "no-update-available") {
     this.stage("idle");
   } else if (msg.type === "installing-update") {
     this.stage("download");
   } else if (msg.type === "update-failed") {
     const pp = msg.payload as ISM_UpdateFailed;
     logger.error(`Self-update failed: ${pp.message}`);
   } else if (msg.type === "update-ready") {
     const pp = msg.payload as ISM_UpdateReady;
     logger.info(`Version ${pp.version} is ready to be used.`);
     this.store.dispatch(
       actions.packageNeedRestart({
         name: this.name,
         availableVersion: pp.version,
       })
     );
   } else if (msg.type === "progress") {
     const pp = msg.payload as ISM_Progress;
     this.store.dispatch(
       actions.packageProgress({
         name: this.name,
         progressInfo: pp,
       })
     );
   } else if (msg.type === "log") {
     const pp = msg.payload as ISM_Log;
     logger.info(`> ${pp.message}`);
   }
 }
Example #9
0
  watcher.on(actions.relaunchRequest, async (store, action) => {
    const rs = store.getState();
    const pkg = rs.broth.packages[rs.system.appName];
    if (pkg.stage !== "need-restart") {
      return;
    }
    const version = pkg.availableVersion;
    const restart = t(rs.i18n, ["prompt.self_update_ready.action.restart"]);

    store.dispatch(
      actions.openModal(
        modals.naked.make({
          wind: "root",
          title: ["prompt.self_update.title", { version }],
          message: ["prompt.self_update_ready.message", { restart }],
          buttons: [
            {
              label: ["prompt.self_update_ready.action.restart"],
              action: actions.relaunch({}),
            },
            {
              label: ["prompt.self_update_ready.action.snooze"],
              action: actions.closeModal({ wind: "root" }),
            },
          ],
          widgetParams: null,
        })
      )
    );
  });
Example #10
0
function dispatchUpdateNotification(
  store: Store,
  cave: Cave,
  result: CheckUpdateResult
) {
  if (!result) {
    return;
  }

  if (!isEmpty(result.warnings)) {
    store.dispatch(
      actions.statusMessage({
        message: [
          "status.game_update.check_failed",
          { err: result.warnings[0] },
        ],
      })
    );
    return;
  }

  if (isEmpty(result.updates)) {
    store.dispatch(
      actions.statusMessage({
        message: ["status.game_update.not_found", { title: cave.game.title }],
      })
    );
  } else {
    store.dispatch(
      actions.statusMessage({
        message: ["status.game_update.found", { title: cave.game.title }],
      })
    );
  }
}