Skip to content
This repository was archived by the owner on Jan 6, 2024. It is now read-only.

Commit 09c3fab

Browse files
feat(eyedropper): add error boundary (#110)
1 parent 64e7525 commit 09c3fab

File tree

3 files changed

+47
-16
lines changed

3 files changed

+47
-16
lines changed

src/client/auto-imports.d.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
export {}
66
declare global {
77
const EffectScope: typeof import('vue')['EffectScope']
8-
const FRAME_STATE_STORAGE_KEY: typeof import('./composables/state')['FRAME_STATE_STORAGE_KEY']
98
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
109
const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
10+
const checkIsSecurityContext: typeof import('./utils/index')['checkIsSecurityContext']
1111
const computed: typeof import('vue')['computed']
1212
const computedAsync: typeof import('@vueuse/core')['computedAsync']
1313
const computedEager: typeof import('@vueuse/core')['computedEager']
@@ -78,7 +78,6 @@ declare global {
7878
const onStartTyping: typeof import('@vueuse/core')['onStartTyping']
7979
const onUnmounted: typeof import('vue')['onUnmounted']
8080
const onUpdated: typeof import('vue')['onUpdated']
81-
const openInEditor: typeof import('./utils/index')['openInEditor']
8281
const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
8382
const pick: typeof import('./utils/index')['pick']
8483
const provide: typeof import('vue')['provide']
@@ -197,7 +196,6 @@ declare global {
197196
const useGamepad: typeof import('@vueuse/core')['useGamepad']
198197
const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
199198
const useGraphSettings: typeof import('./composables/graph')['useGraphSettings']
200-
const useGroupedTabStore: typeof import('./composables/tabs')['useGroupedTabStore']
201199
const useGroupedTabs: typeof import('./composables/tabs')['useGroupedTabs']
202200
const useIdle: typeof import('@vueuse/core')['useIdle']
203201
const useImage: typeof import('@vueuse/core')['useImage']

src/client/pages/__eyedropper.vue

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<script setup lang="ts">
1+
<script setup lang="tsx">
22
import { useDevtoolsClient } from '../logic/client'
33
44
const client = useDevtoolsClient()
@@ -16,7 +16,14 @@ function close() {
1616
router.replace(frameState.route.value)
1717
}
1818
19+
const inSecurityContext = checkIsSecurityContext()
20+
// @ts-expect-error missing types
21+
const supportEyeDropper = !!window.EyeDropper
22+
const isSupported = inSecurityContext && supportEyeDropper
23+
1924
async function open() {
25+
if (!isSupported)
26+
return
2027
// @ts-expect-error missing types?
2128
const eyeDropper = new EyeDropper()
2229
return eyeDropper.open()
@@ -34,25 +41,46 @@ onMounted(() => {
3441
color.value = res.sRGBHex
3542
})
3643
})
44+
45+
function ErrorBoundary() {
46+
let content: JSX.Element = <div></div>
47+
if (!inSecurityContext) {
48+
content = <p>
49+
EyeDropper is not available due to <a class="text-primary transition-colors hover:text-primary/80" href="https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts" target='_blank'>secure context</a> restrict.
50+
</p>
51+
}
52+
else if (!supportEyeDropper) {
53+
content = <p>
54+
Your browser doesn't support&nbsp;
55+
<a class="text-primary transition-colors hover:text-primary/80" href="https://developer.mozilla.org/en-US/docs/Web/API/EyeDropper#browser_compatibility" target='_blank'>EyeDropper</a>.
56+
</p>
57+
}
58+
return <div class="flex items-center justify-center text-12px">
59+
{ content }
60+
</div>
61+
}
3762
</script>
3863

3964
<template>
4065
<VPanelGrids h-screen w-screen px5>
4166
<div absolute right-0 top-0 p2>
4267
<button carbon-close ma text-xl op50 hover:op100 @click="close" />
4368
</div>
44-
<div v-if="!color">
45-
Launching EyeDropper
46-
</div>
47-
<div v-else flex items-center>
48-
<span flex items-center>
49-
<em mr-2 inline-block h-5 w-5 border border-base rounded :style="{ backgroundColor: color }" />
50-
:
51-
{{ color }}
52-
</span>
53-
<span ml-2 flex cursor-pointer items-center border border-base rounded-10 p-2 hover="bg-active" @click="restart">
54-
<i class="i-mdi:eyedropper" text-3 />
55-
</span>
69+
<div v-if="isSupported">
70+
<div v-if="!color">
71+
Launching EyeDropper
72+
</div>
73+
<div v-else flex items-center>
74+
<span flex items-center>
75+
<em mr-2 inline-block h-5 w-5 border border-base rounded :style="{ backgroundColor: color }" />
76+
:
77+
{{ color }}
78+
</span>
79+
<span ml-2 flex cursor-pointer items-center border border-base rounded-10 p-2 hover="bg-active" @click="restart">
80+
<i class="i-mdi:eyedropper" text-3 />
81+
</span>
82+
</div>
5683
</div>
84+
<ErrorBoundary v-else />
5785
</VPanelGrids>
5886
</template>

src/client/utils/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,10 @@ export function isMacOS() {
6060
: /Macintosh/.test(navigator.userAgent)
6161
}
6262

63+
// https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts
64+
export function checkIsSecurityContext() {
65+
return !!window.isSecureContext
66+
}
67+
6368
// eslint-disable-next-line no-sequences
6469
export const pick = <T extends object, K extends keyof T>(obj: T, keys: K[]): T => keys.reduce((pre: T, cur: K) => (cur in obj && (pre[cur] = obj[cur]), pre), <T>({}))

0 commit comments

Comments
 (0)