You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nextcloud/core/src/views/UnsupportedBrowser.vue

176 lines
4.3 KiB
Vue

<!--
- SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<div class="content-unsupported-browser guest-box">
<NcEmptyContent>
{{ t('core', 'This browser is not supported') }}
<template #icon>
<Web />
</template>
<template #action>
<div>
<h2>
{{ t('core', 'Your browser is not supported. Please upgrade to a newer version or a supported one.') }}
</h2>
<NcButton class="content-unsupported-browser__continue" type="primary" @click="forceBrowsing">
{{ t('core', 'Continue with this unsupported browser') }}
</NcButton>
</div>
<ul class="content-unsupported-browser__list">
<h3>{{ t('core', 'Supported versions') }}</h3>
<li v-for="browser in formattedBrowsersList" :key="browser">
{{ browser }}
</li>
</ul>
</template>
</NcEmptyContent>
</div>
</template>
<script>
import { generateUrl } from '@nextcloud/router'
import { translate as t, translatePlural as n } from '@nextcloud/l10n'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
import Web from 'vue-material-design-icons/Web.vue'
// eslint-disable-next-line n/no-extraneous-import
import { agents } from 'caniuse-lite/dist/unpacker/agents.js'
import { browserStorageKey } from '../utils/RedirectUnsupportedBrowsers.js'
import { supportedBrowsers } from '../services/BrowsersListService.js'
import browserStorage from '../services/BrowserStorageService.js'
import logger from '../logger.js'
logger.debug('Supported browsers', { supportedBrowsers })
export default {
name: 'UnsupportedBrowser',
components: {
Web,
NcButton,
NcEmptyContent,
},
computed: {
isMobile() {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
},
/**
* Filter out or include mobile/desktop browsers depending
* on the current user platform/device
*/
filteredSupportedBrowsers() {
return supportedBrowsers.filter(browser => {
if (!browser) {
return false
}
if (this.isMobile) {
return this.isMobileBrowser(browser)
}
return !this.isMobileBrowser(browser)
})
},
formattedBrowsersList() {
const list = {}
// supportedBrowsers is generated by webpack at compilation time
this.filteredSupportedBrowsers.forEach(browser => {
const [id, version] = browser.split(' ')
if (!list[id] || list[id] < parseFloat(version, 10)) {
list[id] = parseFloat(version, 10)
}
})
return Object.keys(list).map(id => {
if (!agents[id]?.browser) {
return null
}
const version = list[id]
const name = agents[id]?.browser
return this.t('core', '{name} version {version} and above', {
name, version,
})
}).filter(entry => entry !== null)
},
},
methods: {
t,
n,
// Set the flag allowing this browser and redirect to home
forceBrowsing() {
browserStorage.setItem(browserStorageKey, true)
// Redirect if there is the data
const urlParams = new URLSearchParams(window.location.search)
if (urlParams.has('redirect_url')) {
const redirectPath = Buffer.from(urlParams.get('redirect_url'), 'base64').toString() || '/'
if (redirectPath.startsWith('/')) {
window.location = generateUrl(redirectPath)
return
}
}
window.location = generateUrl('/')
},
/**
* Detect if the browserslist browser is a mobile one
* https://github.com/browserslist/browserslist#query-composition
*
* @param {string} browser a valid browserlist browser. e.g `and_chr 90`
*/
isMobileBrowser(browser) {
browser = browser.toLowerCase()
return browser.includes('and_')
|| browser.includes('android')
|| browser.includes('ios_')
|| browser.includes('mobile')
|| browser.includes('_mob')
|| browser.includes('samsung')
},
},
}
</script>
<style lang="scss" scoped>
$spacing: 30px;
.content-unsupported-browser {
display: flex;
justify-content: center;
width: 400px;
max-width: calc(90vw - 2 * $spacing);
margin: auto;
padding: $spacing;
.empty-content {
margin: 0;
&::v-deep .empty-content__icon {
opacity: 1;
}
}
&__continue {
display: block;
margin: $spacing auto;
}
&__list {
margin-top: 2 * $spacing;
margin-bottom: $spacing;
li {
text-align: left;
}
}
}
</style>