docbrown/app/javascript/mobile/foremMobile.js
Fernando Valverde 75a722bd6e
ForemMobile namespaced functions (#15212)
* window.ForemMobile namespaced functions

* Fix broken Buildkite

* Wait for data-loaded before using Runtime in pack

* Bring back sprockets base

* Better error handling

* Smal fixes to ConsumerApp to support Android platform

* Fix typo

* utilities/waitForDataLoaded.js

* Update app/javascript/utilities/waitForDataLoaded.js

Co-authored-by: Nick Taylor <nick@forem.com>

* Review feedback

* Fix failing spec

* Cleanup promise

* Remove old utility file

* Add Cypress check for namespaced availability

* More specs

* Refactor to rely on ForemMobile for native bridge messaging

* Fix spec/requests/api/v0/instances_spec.rb

* Fix devices spec

* Remove changes to /api/instance

* Refactor to dynamic import

* Fix typo

* Fixed custom event detail payload for tests.

* mock ForemMobile function instead of webkit call directly

* failing jest test debug

* Another attempt

* Fixed broken test that was missing an onMainImageUrlChange prop on the component.

* Fixed mobile bridging E2E tests.

* Move Cypress tests to mobileFlows

* Add JSDocs + cypress spec for injectJSMessage when logged out

* Cleanup + Disable native image upload until AppStore approval

Co-authored-by: Nick Taylor <nick@forem.com>
Co-authored-by: Nick Taylor <nick@dev.to>
2021-11-23 15:25:29 -06:00

88 lines
2.8 KiB
JavaScript

/* global Runtime */
import { request } from '@utilities/http';
export function foremMobileNamespace() {
return {
retryDelayMs: 700,
getUserData() {
return document.body.dataset.user;
},
getInstanceMetadata() {
return JSON.stringify({
name: document.querySelector("meta[property='forem:name']")['content'],
logo: document.querySelector("meta[property='forem:logo']")['content'],
domain: document.querySelector("meta[property='forem:domain']")[
'content'
],
});
},
registerDeviceToken(token, appBundle, platform) {
request(`/users/devices`, {
method: 'POST',
body: { token, platform, app_bundle: appBundle },
credentials: 'same-origin',
})
.then((response) => response.json())
.then((response) => {
if (
!isNaN(parseInt(response.id, 10)) &&
response.error == undefined
) {
// Clear the interval if the registration succeeded
clearInterval(window.ForemMobile.deviceRegistrationInterval);
window.ForemMobile.retryDelayMs = 700;
} else {
// Registration failed - throw and log error message
throw new Error(response.error);
}
})
.catch((error) => {
Honeybadger.notify(error);
// Increase backoff delay time
if (window.ForemMobile.retryDelayMs < 20000) {
window.ForemMobile.retryDelayMs =
window.ForemMobile.retryDelayMs * 2;
}
// Attempt to register again after delay
setTimeout(() => {
window.ForemMobile.registerDeviceToken(token, appBundle, platform);
}, window.ForemMobile.retryDelayMs);
});
},
unregisterDeviceToken(userId, token, appBundle, platform) {
request(`/users/devices/${userId}`, {
method: 'DELETE',
body: { token, platform, app_bundle: appBundle },
credentials: 'same-origin',
});
},
injectJSMessage(message) {
const event = new CustomEvent('ForemMobile', { detail: message });
document.dispatchEvent(event);
},
injectNativeMessage(namespace, message) {
try {
if (Runtime.isNativeIOS(namespace)) {
window.webkit.messageHandlers[namespace].postMessage(message);
} else if (Runtime.isNativeAndroid(namespace)) {
AndroidBridge[`${namespace}Message`](JSON.stringify(message));
}
} catch (error) {
Honeybadger.notify(error);
}
},
userSessionBroadcast() {
const currentUser = document.body.dataset.user;
if (currentUser) {
window.ForemMobile.injectNativeMessage(
'userLogin',
JSON.parse(currentUser),
);
} else {
window.ForemMobile.injectNativeMessage('userLogout', {});
}
},
};
}