mirror of
https://github.com/jellyfin/jellyfin-vue.git
synced 2026-09-03 05:10:26 +03:00
336 lines
8.6 KiB
TypeScript
336 lines
8.6 KiB
TypeScript
import { Plugin } from '@nuxt/types';
|
|
|
|
declare module '@nuxt/types' {
|
|
interface Context {
|
|
$browser: BrowserDetector;
|
|
}
|
|
|
|
interface NuxtAppOptions {
|
|
$browser: BrowserDetector;
|
|
}
|
|
}
|
|
|
|
declare module 'vue/types/vue' {
|
|
interface Vue {
|
|
$browser: BrowserDetector;
|
|
}
|
|
}
|
|
|
|
declare module 'vuex/types/index' {
|
|
// eslint-disable-next-line -- Current TypeScript rules flag S as unused, but Nuxt requires identical types
|
|
interface Store<S> {
|
|
$browser: BrowserDetector;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Utilities to detect the browser and get information on the current environment
|
|
* Based on https://github.com/google/shaka-player/blob/master/lib/util/platform.js
|
|
*
|
|
* @class BrowserDetector
|
|
*/
|
|
class BrowserDetector {
|
|
supportsMediaSource(): boolean {
|
|
// Browsers that lack a media source implementation will have no reference
|
|
// to |window.MediaSource|.
|
|
if (!window.MediaSource) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check if the user agent of the navigator contains a key.
|
|
*
|
|
* @private
|
|
* @static
|
|
* @param {string} key - Key for which to perform a check.
|
|
* @returns {boolean} Determines if user agent of navigator contains a key
|
|
* @memberof BrowserDetector
|
|
*/
|
|
private userAgentContains(key: string): boolean {
|
|
const userAgent = navigator.userAgent || '';
|
|
return userAgent.includes(key);
|
|
}
|
|
|
|
/* Desktop Browsers */
|
|
|
|
/**
|
|
* Check if the current platform is Mozilla Firefox.
|
|
*
|
|
* @returns {boolean} Determines if browser is Mozilla Firefox
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isFirefox(): boolean {
|
|
return this.userAgentContains('Firefox/');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is Microsoft Edge.
|
|
*
|
|
* @static
|
|
* @returns {boolean} Determines if browser is Microsoft Edge
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isEdge(): boolean {
|
|
return this.userAgentContains('Edg/') || this.userAgentContains('Edge/');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is Chromium based.
|
|
*
|
|
* @returns {boolean} Determines if browser is Chromium based
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isChromiumBased(): boolean {
|
|
return this.userAgentContains('Chrome');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is Google Chrome.
|
|
*
|
|
* @returns {boolean} Determines if browser is Google Chrome
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isChrome(): boolean {
|
|
// The Edge user agent will also contain the "Chrome" keyword, so we need
|
|
// to make sure this is not Edge.
|
|
return this.userAgentContains('Chrome') && !this.isEdge();
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is from Apple.
|
|
*
|
|
* Returns true on all iOS browsers and on desktop Safari.
|
|
*
|
|
* Returns false for non-Safari browsers on macOS, which are independent of
|
|
* Apple.
|
|
*
|
|
* @returns {boolean} Determines if current platform is from Apple
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isApple(): boolean {
|
|
return navigator?.vendor.includes('Apple') && !this.isTizen();
|
|
}
|
|
|
|
/**
|
|
* Returns a major version number for Safari, or Safari-based iOS browsers.
|
|
*
|
|
* @returns {number | null} The major version number for Safari
|
|
* @memberof BrowserDetector
|
|
*/
|
|
safariVersion(): number | null {
|
|
// All iOS browsers and desktop Safari will return true for isApple().
|
|
if (!this.isApple()) {
|
|
return null;
|
|
}
|
|
|
|
// This works for iOS Safari and desktop Safari, which contain something
|
|
// like "Version/13.0" indicating the major Safari or iOS version.
|
|
let match = navigator.userAgent.match(/Version\/(\d+)/);
|
|
if (match) {
|
|
return parseInt(match[1], /* base= */ 10);
|
|
}
|
|
|
|
// This works for all other browsers on iOS, which contain something like
|
|
// "OS 13_3" indicating the major & minor iOS version.
|
|
match = navigator.userAgent.match(/OS (\d+)(?:_\d+)?/);
|
|
if (match) {
|
|
return parseInt(match[1], /* base= */ 10);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/* TV Platforms */
|
|
|
|
/**
|
|
* Check if the current platform is Tizen.
|
|
*
|
|
* @returns {boolean} Determines if current platform is Tizen
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isTizen(): boolean {
|
|
return this.userAgentContains('Tizen');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is Tizen 2
|
|
*
|
|
* @returns {boolean} Determines if current platform is Tizen 2
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isTizen2(): boolean {
|
|
return this.userAgentContains('Tizen 2');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is Tizen 3
|
|
*
|
|
* @returns {boolean} Determines if current platform is Tizen 3
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isTizen3(): boolean {
|
|
return this.userAgentContains('Tizen 3');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is Tizen 4.
|
|
*
|
|
* @returns {boolean} Determines if current platform is Tizen 4
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isTizen4(): boolean {
|
|
return this.userAgentContains('Tizen 4');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is Tizen 5.
|
|
*
|
|
* @returns {boolean} Determines if current platform is Tizen 5
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isTizen5(): boolean {
|
|
return this.userAgentContains('Tizen 5');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is Tizen 5.5.
|
|
*
|
|
* @returns {boolean} Determines if current platform is Tizen 5.5
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isTizen55(): boolean {
|
|
return this.userAgentContains('Tizen 5.5');
|
|
}
|
|
|
|
/**
|
|
* Check if the current platform is WebOS.
|
|
*
|
|
* @returns {boolean} Determines if current platform is WebOS
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isWebOS(): boolean {
|
|
return this.userAgentContains('WebOS');
|
|
}
|
|
|
|
/**
|
|
* @returns {boolean} Determines if current platform is WebOS1
|
|
*/
|
|
isWebOS1(): boolean {
|
|
return (
|
|
this.isWebOS &&
|
|
this.userAgentContains('AppleWebKit/537') &&
|
|
!this.userAgentContains('Chrome/')
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @returns {boolean} Determines if current platform is WebOS1
|
|
*/
|
|
isWebOS2(): boolean {
|
|
return (
|
|
this.isWebOS &&
|
|
this.userAgentContains('AppleWebKit/538') &&
|
|
!this.userAgentContains('Chrome/')
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @returns {boolean} Determines if current platform is WebOS3
|
|
*/
|
|
isWebOS3(): boolean {
|
|
return this.isWebOS && this.userAgentContains('Chrome/38');
|
|
}
|
|
|
|
/**
|
|
* @returns {boolean} Determines if current platform is WebOS4
|
|
*/
|
|
isWebOS4(): boolean {
|
|
return this.isWebOS && this.userAgentContains('Chrome/53');
|
|
}
|
|
|
|
/**
|
|
* @returns {boolean} Determines if current platform is WebOS5
|
|
*/
|
|
isWebOS5(): boolean {
|
|
return this.isWebOS && this.userAgentContains('Chrome/68');
|
|
}
|
|
|
|
/* Platform Utilities */
|
|
|
|
/**
|
|
* @returns {boolean} Determines if current platform is Android
|
|
*/
|
|
isAndroid(): boolean {
|
|
return this.userAgentContains('Android');
|
|
}
|
|
|
|
/**
|
|
* Guesses if the platform is a mobile one (iOS or Android).
|
|
*
|
|
* @returns {boolean} Determines if current platform is mobile (Guess)
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isMobile(): boolean {
|
|
if (/(?:iPhone|iPad|iPod|Android)/.test(navigator.userAgent)) {
|
|
// This is Android, iOS, or iPad < 13.
|
|
return true;
|
|
}
|
|
|
|
// Starting with iOS 13 on iPad, the user agent string no longer has the
|
|
// word "iPad" in it. It looks very similar to desktop Safari. This seems
|
|
// to be intentional on Apple's part.
|
|
// See: https://forums.developer.apple.com/thread/119186
|
|
//
|
|
// So if it's an Apple device with multi-touch support, assume it's a mobile
|
|
// device. If some future iOS version starts masking their user agent on
|
|
// both iPhone & iPad, this clause should still work. If a future
|
|
// multi-touch desktop Mac is released, this will need some adjustment.
|
|
//
|
|
// As of January 2020, this is mainly used to adjust the default UI config
|
|
// for mobile devices, so it's low risk if something changes to break this
|
|
// detection.
|
|
return this.isApple() && navigator.maxTouchPoints > 1;
|
|
}
|
|
|
|
/**
|
|
* Guesses if the platform is a Smart TV (Tizen or WebOS).
|
|
*
|
|
* @returns {boolean} Determines if platform is a Smart TV
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isTv(): boolean {
|
|
return this.isTizen() || this.isWebOS();
|
|
}
|
|
|
|
/**
|
|
* Guesses if the platform is a PS4
|
|
*
|
|
* @returns {boolean} Determines if the device is a PS4
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isPs4(): boolean {
|
|
return this.userAgentContains('playstation 4');
|
|
}
|
|
|
|
/**
|
|
* Guesses if the platform is a Xbox
|
|
*
|
|
* @returns {boolean} Determines if the device is a Xbox
|
|
* @memberof BrowserDetector
|
|
*/
|
|
isXbox(): boolean {
|
|
return this.userAgentContains('xbox');
|
|
}
|
|
}
|
|
|
|
export const browserDetector = new BrowserDetector();
|
|
|
|
const browserDetectorPlugin: Plugin = (_context, inject) => {
|
|
inject('browser', browserDetector);
|
|
};
|
|
|
|
export default browserDetectorPlugin;
|