176 lines
4.3 KiB
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>
|