Last active
November 5, 2018 09:23
-
-
Save SugarDarius/233393e76c8065fa4a9b8bd17fd19006 to your computer and use it in GitHub Desktop.
A React component to detect browsers and update UI
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Detect browser - Browsers | |
* author: Aurélien Dupays Dexemple | |
*/ | |
export type BrowserName = 'Chrome' | | |
'Firefox' | | |
'Safari' | | |
'Internet Explorer' | | |
'Opera' | | |
'BlackBerry' | | |
'Mozilla'; | |
export interface Browser { | |
name: BrowserName; | |
value: string; | |
version: string; | |
} | |
export const browsers: Browser[] = [ | |
{ name: 'Chrome', value: 'Chrome', version: 'Chrome' }, | |
{ name: 'Firefox', value: 'Firefox', version: 'Firefox' }, | |
{ name: 'Safari', value: 'Safari', version: 'Version' }, | |
{ name: 'Internet Explorer', value: 'MSIE', version: 'MSIE' }, | |
{ name: 'Opera', value: 'Opera', version: 'Opera' }, | |
{ name: 'BlackBerry', value: 'CLDC', version: 'CLDC' }, | |
{ name: 'Mozilla', value: 'Mozilla', version: 'Mozilla' } | |
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Detect browser | |
* author: Aurélien Dupays Dexemple | |
*/ | |
import './stylesheet.scss'; | |
import * as React from 'react'; | |
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; | |
import every = require('lodash/every'); | |
import { OperatingSystemName } from './operating-systems'; | |
import { BrowserName } from './browsers'; | |
import { DetectBrowserResult, detectBrowser } from './detect-browser'; | |
export interface DetectBrowserBlackListItem { | |
name: BrowserName; | |
version: number | 'any'; | |
os?: { | |
name: OperatingSystemName; | |
version: number | 'any'; | |
} | |
} | |
export interface DetectBrowserProps { | |
blacklist: DetectBrowserBlackListItem[]; | |
children: JSX.Element[] | JSX.Element; | |
} | |
export class DetectBrowser extends React.PureComponent<DetectBrowserProps> { | |
allowBrowser = (): boolean => { | |
const { blacklist } = this.props; | |
const { platform, userAgent, appVersion, vendor } = navigator; | |
const detectBrowserResult: DetectBrowserResult = detectBrowser([platform, userAgent, appVersion, vendor]); | |
return every(blacklist, (item: DetectBrowserBlackListItem ) => ( | |
!( | |
item.name === detectBrowserResult.browser.name && | |
(item.version !== 'any' ? item.version === detectBrowserResult.browser.version : false) && | |
(item.os ? item.os.name === detectBrowserResult.os.name : false) && | |
(item.os && item.os.version !== 'any' ? item.os.version === detectBrowserResult.os.version : false ) | |
) | |
)); | |
} | |
render(): JSX.Element { | |
const { children } = this.props; | |
const browserIsAllowed: boolean = this.allowBrowser(); | |
return ( | |
<React.Fragment> | |
{ | |
!browserIsAllowed ? ( | |
<div className='detect-browser-box'> | |
<div className='detect-browser-box__content fa-4x'> | |
<div className='fa-2x' style={{ marginBottom: 44 }}> | |
<span className='fa-layers fa-fw'> | |
<FontAwesomeIcon | |
className='detect-browser-box__content__icons' | |
icon='desktop' | |
transform='shrink-8' | |
/> | |
<FontAwesomeIcon | |
className='detect-browser-box__content__icons' | |
icon='ban' | |
style={{ color: 'Tomato' }} | |
transform='grow-2' | |
/> | |
</span> | |
</div> | |
<span className='detect-browser-box__content__message'> | |
We are sorry, our application does not support Internet Explorer.<br /> | |
Please, try opening it with a more recent browser. | |
</span> | |
</div> | |
</div> | |
) : children | |
} | |
</React.Fragment> | |
) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Detect browser - main algorithm | |
* author: Aurélien Dupays Dexemple | |
*/ | |
import { OperatingSystem, operatingSystems } from './operating-systems'; | |
import { Browser, browsers } from './browsers'; | |
export type Agent = string; | |
export type DataItems = OperatingSystem[] | Browser[]; | |
export interface DetectBrowserResultItem { | |
name: string; | |
version: number; | |
} | |
export interface DetectBrowserResult { | |
os: DetectBrowserResultItem; | |
browser: DetectBrowserResultItem; | |
} | |
const getMatches = (agents: Agent[], data: DataItems): DetectBrowserResultItem => { | |
let resultItem: DetectBrowserResultItem = { name: 'unknonw', version: -1 }; | |
const _agents: string = agents.join(' '); | |
let match: boolean = false, matches: RegExpMatchArray | null = null, index: number = 0; | |
const getVersion = (matches: RegExpMatchArray | null = null): number => { | |
const _matches: string | null = matches && matches[1] ? matches[1] : null; | |
return _matches ? Number.parseInt(_matches.split(/[._]+/)[0]) : -1; | |
}; | |
while (!match && index < data.length) { | |
const item = data[index]; | |
match = (new RegExp(item.value, 'i')).test(_agents); | |
if (match) { | |
matches = _agents.match(new RegExp(`${item.version}[- /:;]([\\d._]+)`, 'i')); | |
resultItem.name = item.name; | |
resultItem.version = getVersion(matches); | |
break; | |
} | |
index = index + 1; | |
} | |
return resultItem; | |
} | |
export const detectBrowser = (agents: Agent[]): DetectBrowserResult => ({ | |
os: getMatches(agents, operatingSystems), | |
browser: getMatches(agents, browsers) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Detect browser - Operating systems | |
* author: Aurélien Dupays Dexemple | |
*/ | |
export type OperatingSystemName = 'Windows Phone' | | |
'Windows' | | |
'iPhone' | | |
'iPad' | | |
'Kindle' | | |
'Android' | | |
'PlayBook' | | |
'BlackBerry' | | |
'Macintosh' | | |
'Linux' | | |
'Palm'; | |
export interface OperatingSystem { | |
name: OperatingSystemName; | |
value: string; | |
version: string; | |
}; | |
export const operatingSystems: OperatingSystem[] = [ | |
{ name: 'Windows Phone', value: 'Windows Phone', version: 'OS' }, | |
{ name: 'Windows', value: 'Win', version: 'NT' }, | |
{ name: 'iPhone', value: 'iPhone', version: 'OS' }, | |
{ name: 'iPad', value: 'iPad', version: 'OS' }, | |
{ name: 'Kindle', value: 'Silk', version: 'Silk' }, | |
{ name: 'Android', value: 'Android', version: 'Android' }, | |
{ name: 'PlayBook', value: 'PlayBook', version: 'OS' }, | |
{ name: 'BlackBerry', value: 'BlackBerry', version: '/' }, | |
{ name: 'Macintosh', value: 'Mac', version: 'OS X' }, | |
{ name: 'Linux', value: 'Linux', version: 'rv' }, | |
{ name: 'Palm', value: 'Palm', version: 'PalmOS' } | |
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Detect browser - stylesheet | |
* author: Aurélien Dupays Dexemple | |
*/ | |
@import '../../shared/stylesheets/colors.scss'; | |
@import '../../shared/stylesheets/mixins.scss'; | |
.detect-browser-box { | |
position: fixed; | |
top: 0; | |
left: 0; | |
display: flex !important; | |
flex-direction: column !important; | |
justify-content: center; | |
align-items: center; | |
width: 100%; | |
height: 100%; | |
background-color: $gray-9; | |
z-index: 99999; | |
overflow: hidden !important; | |
&__content { | |
position: relative; | |
display: flex !important; | |
flex-direction: column !important; | |
justify-content: center; | |
align-items: center; | |
width: 80%; | |
max-width: 800px; | |
min-height: 200px; | |
padding: 54px 16px; | |
border-radius: 3px; | |
border: solid 1px $gray-7; | |
background-color: $white-0; | |
&__icons { color: $gray-1; } | |
&__message { | |
text-align: center; | |
@include font($EtelkaTextPro, 300, 22px); | |
color: $gray-1; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment