@shopify/app-bridge-host
Version:
App Bridge Host contains components and middleware to be consumed by the app's host, as well as the host itself. The middleware and `Frame` component are responsible for facilitating communication between the client and host, and used to act on actions se
156 lines (153 loc) • 7.09 kB
JavaScript
import { __awaiter, __generator } from 'tslib';
import React, { useState, useRef, useEffect } from 'react';
import { EventListener, Modal } from '@shopify/polaris-internal';
import { useI18n } from '@shopify/react-i18n';
import { fromAction, AppActionType } from '@shopify/app-bridge-core/actions/Error';
import { Context } from '@shopify/app-bridge-core/MessageTransport';
import { Action } from '@shopify/app-bridge-core/actions/Navigation/Redirect';
import { Group } from '@shopify/app-bridge-core/actions/types';
import { getPermissionKey } from '@shopify/app-bridge-core/actions/validator';
import { useRouterContext } from '../../../hooks/useRouterContext.js';
import { useFeature } from '../../../features/utilities/useFeature.js';
import { feature } from '../../../store/reducers/embeddedApp/features/index.js';
import _en from './translations/en.json.js';
function __variableDynamicImportRuntime0__(path) {
switch (path) {
case './translations/cs.json': return import('./translations/cs.json.js');
case './translations/da.json': return import('./translations/da.json.js');
case './translations/de.json': return import('./translations/de.json.js');
case './translations/en.json': return import('./translations/en.json.js');
case './translations/es.json': return import('./translations/es.json.js');
case './translations/fi.json': return import('./translations/fi.json.js');
case './translations/fr.json': return import('./translations/fr.json.js');
case './translations/hi.json': return import('./translations/hi.json.js');
case './translations/it.json': return import('./translations/it.json.js');
case './translations/ja.json': return import('./translations/ja.json.js');
case './translations/ko.json': return import('./translations/ko.json.js');
case './translations/ms.json': return import('./translations/ms.json.js');
case './translations/nb.json': return import('./translations/nb.json.js');
case './translations/nl.json': return import('./translations/nl.json.js');
case './translations/pl.json': return import('./translations/pl.json.js');
case './translations/pt-BR.json': return import('./translations/pt-BR.json.js');
case './translations/pt-PT.json': return import('./translations/pt-PT.json.js');
case './translations/sv.json': return import('./translations/sv.json.js');
case './translations/th.json': return import('./translations/th.json.js');
case './translations/tr.json': return import('./translations/tr.json.js');
case './translations/zh-CN.json': return import('./translations/zh-CN.json.js');
case './translations/zh-TW.json': return import('./translations/zh-TW.json.js');
default: return new Promise(function(resolve, reject) {
(typeof queueMicrotask === 'function' ? queueMicrotask : setTimeout)(
reject.bind(null, new Error("Unknown variable dynamic import: " + path))
);
})
}
}
var APP_REDIRECT_KEY = getPermissionKey(Action.APP);
function LeaveConfirmation(props) {
var router = useRouterContext();
var history = router.history, location = router.location;
var _a = useFeature(feature), permissionsActions = _a[1];
var i18n = useI18n({
id: 'LeaveConfirmation_<hash>',
fallback: _en,
translations: function (locale) {
return __awaiter(this, void 0, void 0, function () {
var dictionary;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, __variableDynamicImportRuntime0__("./translations/".concat(locale, ".json"))];
case 1:
dictionary = _a.sent();
return [2 /*return*/, dictionary];
case 2:
_a.sent();
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
});
},
})[0];
var _b = useState(false), openState = _b[0], setOpen = _b[1];
var open = props.open || openState;
var _c = useState(null), nextLocation = _c[0], setNextLocation = _c[1];
var unblock = useRef();
useEffect(function () {
if (!history.block) {
throw fromAction('Missing the `history.block` method in the Router Context. The router history must contain a method to block route changes', AppActionType.MISSING_HISTORY_BLOCK);
}
disableLeaveHook();
unblock.current = history.block(handleRouteLeave);
return disableLeaveHook;
}, []);
return (React.createElement(React.Fragment, null,
React.createElement(EventListener, { event: "beforeunload", handler: beforeUnload }),
React.createElement(Modal, { title: i18n.translate('title'), open: open, secondaryActions: [
{
content: i18n.translate('cancel'),
onAction: handleClose,
},
{
content: i18n.translate('confirmLabel'),
onAction: handleConfirm,
destructive: true,
},
], onClose: handleClose, sectioned: true }, i18n.translate('content'))));
function disableLeaveHook() {
if (unblock.current) {
unblock.current();
unblock.current = undefined;
}
}
function beforeUnload(evt) {
evt.returnValue = true;
return true;
}
function handleRouteLeave(nextLocation) {
if (!nextLocation || (nextLocation && nextLocation.pathname === location.pathname)) {
return;
}
setOpen(true);
if (nextLocation) {
var url = new URL(window.location.href);
url.pathname = nextLocation.pathname;
setNextLocation(nextLocation);
}
return false;
}
function handleClose() {
var _a;
setOpen(false);
(_a = props.onDiscard) === null || _a === void 0 ? void 0 : _a.call(props);
}
function handleConfirm() {
var _a, _b, _c;
var onConfirm = props.onConfirm;
if (props.open) {
onConfirm === null || onConfirm === void 0 ? void 0 : onConfirm();
return;
}
if (!nextLocation) {
return;
}
if (onConfirm) {
onConfirm();
}
disableLeaveHook();
// Re-enable app redirect subscribe after ContextualSaveBar disables it
permissionsActions.update((_a = {},
_a[Context.Main] = (_b = {},
_b[Group.Navigation] = (_c = {},
_c[APP_REDIRECT_KEY] = {
Dispatch: true,
Subscribe: true,
},
_c),
_b),
_a));
history.push(nextLocation);
}
}
export { LeaveConfirmation as default };