Remove external link dialog
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
no-shadow
|
||||
class="mx-auto w-full"
|
||||
>
|
||||
<div class="flex flex-col gap-4" data-no-external-confirm>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div v-if="!workspaceInvite" class="flex flex-col items-center gap-y-2 pb-4">
|
||||
<h1 class="text-heading-xl text-center inline-block">
|
||||
{{ title }}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- eslint-disable vuejs-accessibility/no-static-element-interactions -->
|
||||
<!-- eslint-disable vuejs-accessibility/click-events-have-key-events -->
|
||||
<template>
|
||||
<div class="group h-full" data-no-external-confirm>
|
||||
<div class="group h-full">
|
||||
<template v-if="showSidebar">
|
||||
<Portal to="mobile-navigation">
|
||||
<div class="lg:hidden">
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
<template>
|
||||
<LayoutDialog v-model:open="open" max-width="xs" :buttons="buttons">
|
||||
<template #header>Leaving Speckle</template>
|
||||
<p class="mb-2">You're about to open the link below in a new tab:</p>
|
||||
<div class="p-3 bg-highlight-2 rounded-md font-mono break-all">
|
||||
{{ state.url }}
|
||||
</div>
|
||||
<p class="mt-2 mb-4">
|
||||
This is an external website. Speckle is not responsible for its content or
|
||||
security.
|
||||
</p>
|
||||
<p class="font-medium">Do you want to continue?</p>
|
||||
</LayoutDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useExternalLinkDialogState } from '~/lib/common/composables/externalLinkDialog'
|
||||
import type { LayoutDialogButton } from '@speckle/ui-components'
|
||||
|
||||
const { state, close } = useExternalLinkDialogState()
|
||||
const buttons = computed((): LayoutDialogButton[] => [
|
||||
{
|
||||
text: 'Cancel',
|
||||
props: { color: 'subtle' },
|
||||
onClick: () => {
|
||||
close(false)
|
||||
}
|
||||
},
|
||||
{
|
||||
text: 'Continue',
|
||||
onClick: () => {
|
||||
window.open(state.value.url, '_blank', 'noopener,noreferrer')
|
||||
close(true)
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
const open = computed({
|
||||
get: () => state.value.open,
|
||||
set: (v) => {
|
||||
if (!v) close(false)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -5,7 +5,6 @@
|
||||
</ClientOnly>
|
||||
<SingletonFileUploadErrorDialog />
|
||||
<SingletonAppErrorStateManager />
|
||||
<SingletonExternalLinkDialog />
|
||||
</div>
|
||||
<div v-else />
|
||||
</template>
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
:disabled="disabled"
|
||||
:project-id="projectId"
|
||||
:disable-invitation-cta="!canInvite"
|
||||
data-no-external-confirm
|
||||
@submit="onSubmit"
|
||||
@created="$emit('created')"
|
||||
/>
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
type ExternalLinkState = {
|
||||
open: boolean
|
||||
url: string
|
||||
_resolver?: (accepted: boolean) => void
|
||||
}
|
||||
|
||||
const useSharedExternalLinkState = () =>
|
||||
useState<ExternalLinkState>('global_external_link', () => ({
|
||||
open: false,
|
||||
url: ''
|
||||
}))
|
||||
|
||||
export const useExternalLinkDialogController = () => {
|
||||
const state = useSharedExternalLinkState()
|
||||
const confirm = (url: string) =>
|
||||
new Promise<boolean>((resolve) => {
|
||||
state.value = { open: true, url, _resolver: resolve }
|
||||
})
|
||||
return { confirm }
|
||||
}
|
||||
|
||||
export const useExternalLinkDialogState = () => {
|
||||
const state = useSharedExternalLinkState()
|
||||
const close = (accepted: boolean) => {
|
||||
state.value.open = false
|
||||
state.value._resolver?.(accepted)
|
||||
}
|
||||
return { state: readonly(state), close }
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
import { useExternalLinkDialogController } from '~/lib/common/composables/externalLinkDialog'
|
||||
|
||||
export default defineNuxtPlugin(() => {
|
||||
const { confirm } = useExternalLinkDialogController()
|
||||
|
||||
const handler = (e: MouseEvent) => {
|
||||
// Ignore modified / non-left clicks
|
||||
if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return
|
||||
|
||||
const a = (e.target as HTMLElement).closest('a[href]') as HTMLAnchorElement | null
|
||||
if (!a) return
|
||||
|
||||
if (a.hasAttribute('download') || a.closest('[data-no-external-confirm]')) return
|
||||
|
||||
const url = new URL(a.href, window.location.href)
|
||||
|
||||
const isWhitelisted = (url: URL) =>
|
||||
url.hostname === 'speckle.systems' ||
|
||||
url.hostname.endsWith('.speckle.systems') ||
|
||||
url.hostname === 'speckle.community' ||
|
||||
url.hostname.endsWith('.speckle.community') ||
|
||||
url.hostname === 'speckle.xyz' ||
|
||||
url.hostname.endsWith('.speckle.xyz') ||
|
||||
url.hostname === 'speckle.dev' ||
|
||||
url.hostname.endsWith('.speckle.dev')
|
||||
|
||||
if (isWhitelisted(url) || url.origin === window.location.origin) return
|
||||
|
||||
e.preventDefault()
|
||||
void confirm(a.href)
|
||||
}
|
||||
|
||||
document.addEventListener('click', handler, true)
|
||||
})
|
||||
Reference in New Issue
Block a user