* treat cmd and ctrl key shortcuts differently on macOS * consolidate shortcut key string into Runtime helper
169 lines
5.3 KiB
JavaScript
169 lines
5.3 KiB
JavaScript
/**
|
|
* This class helps managing native feature support. Can easily be referenced
|
|
* from anywhere in JavaScript with:
|
|
*
|
|
* if (Runtime.isNativeiOS('video')) { ... }
|
|
*
|
|
* if (Runtime.isNativeAndroid('podcastMessage')) { ... }
|
|
*/
|
|
class Runtime {
|
|
/**
|
|
* This function returns a string combining the current Medium and OS
|
|
* that represents the current Context where the app is running.
|
|
*
|
|
* @returns {String} "Medium-OS", for example "Browser-Android"
|
|
*/
|
|
static currentContext() {
|
|
return `${Runtime.currentMedium()}-${Runtime.currentOS()}`;
|
|
}
|
|
|
|
/**
|
|
* This function returns a string that represents the current Medium where
|
|
* the app is currently running. The currently supported mediums are Browser,
|
|
* ForemWebView and PWA.
|
|
*
|
|
* @returns {String} One of the supported Mediums or 'Unsupported'
|
|
*/
|
|
static currentMedium() {
|
|
const pwaButtons = document.getElementById('pwa-nav-buttons');
|
|
if (/ForemWebView/i.test(navigator.userAgent)) {
|
|
return 'ForemWebView';
|
|
} else if (pwaButtons.classList.contains('pwa-nav-buttons--showing')) {
|
|
return 'PWA';
|
|
} else {
|
|
return 'Browser';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function returns a string that represents the current OS where the app
|
|
* is currently running. The currently supported Operating Systems are
|
|
* Windows, Linux, macOS, Android and iOS.
|
|
*
|
|
* @returns {String} One of the supported Operating Systems or 'Unsupported'
|
|
*/
|
|
static currentOS() {
|
|
const macosPlatforms = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'];
|
|
const windowsPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE'];
|
|
const iosPlatforms = ['iPhone', 'iPad', 'iPod'];
|
|
|
|
if (macosPlatforms.includes(window.navigator.platform)) {
|
|
return 'macOS';
|
|
} else if (iosPlatforms.includes(window.navigator.platform)) {
|
|
return 'iOS';
|
|
} else if (windowsPlatforms.includes(window.navigator.platform)) {
|
|
return 'Windows';
|
|
} else if (/Android/i.test(window.navigator.userAgent)) {
|
|
return 'Android';
|
|
} else if (/Linux/i.test(window.navigator.platform)) {
|
|
return 'Linux';
|
|
}
|
|
|
|
return 'Unsupported';
|
|
}
|
|
|
|
/**
|
|
* Checks the device for iOS (webkit) native feature support
|
|
*
|
|
* @function isNativeIOS
|
|
* @param {string} namespace Specifies support for a specific feature
|
|
* (i.e. video, podcast, etc)
|
|
* @returns {boolean} true if current environment support native features
|
|
*/
|
|
static isNativeIOS(namespace = null) {
|
|
const nativeCheck =
|
|
/DEV-Native-ios|ForemWebView/i.test(navigator.userAgent) &&
|
|
window &&
|
|
window.webkit &&
|
|
window.webkit.messageHandlers;
|
|
|
|
let namespaceCheck = true;
|
|
if (nativeCheck && namespace) {
|
|
namespaceCheck = window.webkit.messageHandlers[namespace] != undefined;
|
|
}
|
|
|
|
return nativeCheck && namespaceCheck;
|
|
}
|
|
|
|
/**
|
|
* Checks the device for Android native feature support
|
|
*
|
|
* @function isNativeAndroid
|
|
* @param {string} namespace Specifies support for a specific feature
|
|
* (i.e. videoMessage, podcastMessage, etc)
|
|
* @returns {boolean} true if current environment support native features
|
|
*/
|
|
static isNativeAndroid(namespace = null) {
|
|
const nativeCheck =
|
|
/DEV-Native-android|ForemWebView/i.test(navigator.userAgent) &&
|
|
typeof AndroidBridge !== 'undefined';
|
|
|
|
let namespaceCheck = true;
|
|
if (nativeCheck && namespace) {
|
|
namespaceCheck = AndroidBridge[namespace] != undefined;
|
|
}
|
|
|
|
return nativeCheck && namespaceCheck;
|
|
}
|
|
|
|
/**
|
|
* This function copies text to clipboard taking in consideration all
|
|
* supported platforms.
|
|
*
|
|
* @param {string} text to be copied to the clipboard
|
|
*
|
|
* @returns {Promise} Resolves when succesful in copying to clipboard
|
|
*/
|
|
static copyToClipboard(text) {
|
|
return new Promise((resolve, reject) => {
|
|
if (Runtime.isNativeAndroid('copyToClipboard')) {
|
|
AndroidBridge.copyToClipboard(text);
|
|
resolve();
|
|
} else if (navigator.clipboard != null) {
|
|
navigator.clipboard
|
|
.writeText(text)
|
|
.then(() => {
|
|
resolve();
|
|
})
|
|
.catch((e) => {
|
|
reject(e);
|
|
});
|
|
} else {
|
|
reject('Unable to copy the text. Try reloading the page');
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Returns true if the supplied KeyboardEvent includes the OS-specific
|
|
* modifier key. For example, the Cmd key on Apple platforms or the Ctrl key
|
|
* on others.
|
|
*
|
|
* @param {KeyboardEvent} The event to check for the OS-specific modifier key
|
|
*
|
|
* @returns {Boolean} true if the event was fired with the OS-specific
|
|
* modifier key, false otherwise. Also returns false if
|
|
* the event is not a KeyboardEvent.
|
|
*/
|
|
static hasOSSpecificModifier(event) {
|
|
if (!(event instanceof KeyboardEvent)) {
|
|
return false;
|
|
}
|
|
|
|
if (navigator.userAgent.indexOf('Mac OS X') >= 0) {
|
|
return event.metaKey;
|
|
} else {
|
|
return event.ctrlKey;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns a string representation of the expected modifier key for the current OS.
|
|
* This allows us to display correct shortcut key hints to users in the UI, and set up correct shortcut key bindings.
|
|
*
|
|
* @returns {string} either 'cmd' if on macOS, or 'ctrl' otherwise
|
|
*/
|
|
static getOSKeyboardModifierKeyString() {
|
|
return Runtime.currentOS() === 'macOS' ? 'cmd' : 'ctrl';
|
|
}
|
|
}
|