Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(all)!: isSupported becomes Ref<boolean> instead of boolean for SSR compatibility #1800

Merged
merged 10 commits into from Jul 10, 2022
5 changes: 3 additions & 2 deletions packages/core/useBattery/index.ts
@@ -1,5 +1,6 @@
/* this implementation is original ported from https://github.com/logaretm/vue-use-web by Abdelrahman Awad */

import { isSup } from '@vueuse/shared'
import { ref } from 'vue-demi'
import { useEventListener } from '../useEventListener'
import type { ConfigurableNavigator } from '../_configurable'
Expand All @@ -25,7 +26,7 @@ type NavigatorWithBattery = Navigator & {
export function useBattery({ navigator = defaultNavigator }: ConfigurableNavigator = {}) {
const events = ['chargingchange', 'chargingtimechange', 'dischargingtimechange', 'levelchange']

const isSupported = navigator && 'getBattery' in navigator
const isSupported = isSup(() => Boolean(navigator && 'getBattery' in navigator))
okxiaoliang4 marked this conversation as resolved.
Show resolved Hide resolved

const charging = ref(false)
const chargingTime = ref(0)
Expand All @@ -41,7 +42,7 @@ export function useBattery({ navigator = defaultNavigator }: ConfigurableNavigat
level.value = this.level
}

if (isSupported) {
if (isSupported.value) {
(navigator as NavigatorWithBattery)
.getBattery()
.then((_battery) => {
Expand Down
6 changes: 3 additions & 3 deletions packages/core/useBluetooth/index.ts
@@ -1,5 +1,5 @@
import { computed, ref, watch } from 'vue-demi'
import { tryOnMounted, tryOnScopeDispose } from '@vueuse/shared'
import { isSup, tryOnMounted, tryOnScopeDispose } from '@vueuse/shared'
import type { ConfigurableNavigator } from '../_configurable'

import { defaultNavigator } from '../_configurable'
Expand Down Expand Up @@ -51,7 +51,7 @@ export function useBluetooth(options?: UseBluetoothOptions) {
navigator = defaultNavigator,
} = options || {}

const isSupported = navigator && 'bluetooth' in navigator
const isSupported = isSup(() => Boolean(navigator && 'bluetooth' in navigator))

const device = ref<undefined | BluetoothDevice>(undefined)

Expand All @@ -63,7 +63,7 @@ export function useBluetooth(options?: UseBluetoothOptions) {

async function requestDevice(): Promise<void> {
// This is the function can only be called if Bluetooth API is supported:
if (!isSupported)
if (!isSupported.value)
return

// Reset any errors we currently have:
Expand Down
6 changes: 3 additions & 3 deletions packages/core/useBroadcastChannel/index.ts
@@ -1,5 +1,5 @@
import { ref } from 'vue-demi'
import { tryOnMounted, tryOnScopeDispose } from '@vueuse/shared'
import { isSup, tryOnMounted, tryOnScopeDispose } from '@vueuse/shared'
import type { ConfigurableWindow } from '../_configurable'
import { defaultWindow } from '../_configurable'

Expand All @@ -24,7 +24,7 @@ export const useBroadcastChannel = (options: UseBroadcastChannelOptions) => {
window = defaultWindow,
} = options

const isSupported = window && 'BroadcastChannel' in window
const isSupported = isSup(() => Boolean(window && 'BroadcastChannel' in window))
const isClosed = ref(false)

const channel = ref<BroadcastChannel | undefined>()
Expand All @@ -42,7 +42,7 @@ export const useBroadcastChannel = (options: UseBroadcastChannelOptions) => {
isClosed.value = true
}

if (isSupported) {
if (isSupported.value) {
tryOnMounted(() => {
error.value = null
channel.value = new BroadcastChannel(name)
Expand Down
12 changes: 6 additions & 6 deletions packages/core/useClipboard/index.ts
@@ -1,8 +1,8 @@
/* this implementation is original ported from https://github.com/logaretm/vue-use-web by Abdelrahman Awad */

import type { MaybeRef } from '@vueuse/shared'
import { useTimeoutFn } from '@vueuse/shared'
import type { ComputedRef } from 'vue-demi'
import { isSup, useTimeoutFn } from '@vueuse/shared'
import type { ComputedRef, Ref } from 'vue-demi'
import { ref, unref } from 'vue-demi'
import type { WindowEventName } from '../useEventListener'
import { useEventListener } from '../useEventListener'
Expand Down Expand Up @@ -31,7 +31,7 @@ export interface ClipboardOptions<Source> extends ConfigurableNavigator {
}

export interface ClipboardReturn<Optional> {
isSupported: boolean
isSupported: Ref<boolean>
text: ComputedRef<string>
copied: ComputedRef<boolean>
copy: Optional extends true ? (text?: string) => Promise<void> : (text: string) => Promise<void>
Expand All @@ -54,7 +54,7 @@ export function useClipboard(options: ClipboardOptions<MaybeRef<string> | undefi
} = options

const events = ['copy', 'cut']
const isSupported = Boolean(navigator && 'clipboard' in navigator)
const isSupported = isSup(() => Boolean(navigator && 'clipboard' in navigator))
const text = ref('')
const copied = ref(false)

Expand All @@ -66,13 +66,13 @@ export function useClipboard(options: ClipboardOptions<MaybeRef<string> | undefi
})
}

if (isSupported && read) {
if (isSupported.value && read) {
for (const event of events)
useEventListener(event as WindowEventName, updateText)
}

async function copy(value = unref(source)) {
if (isSupported && value != null) {
if (isSupported.value && value != null) {
await navigator!.clipboard.writeText(value)
text.value = value
copied.value = true
Expand Down
5 changes: 3 additions & 2 deletions packages/core/useDeviceOrientation/index.ts
@@ -1,5 +1,6 @@
/* this implementation is original ported from https://github.com/logaretm/vue-use-web by Abdelrahman Awad */

import { isSup } from '@vueuse/shared'
import type { Ref } from 'vue-demi'
import { ref } from 'vue-demi'
import { useEventListener } from '../useEventListener'
Expand All @@ -14,14 +15,14 @@ import { defaultWindow } from '../_configurable'
*/
export function useDeviceOrientation(options: ConfigurableWindow = {}) {
const { window = defaultWindow } = options
const isSupported = Boolean(window && 'DeviceOrientationEvent' in window)
const isSupported = isSup(() => Boolean(window && 'DeviceOrientationEvent' in window))

const isAbsolute = ref(false)
const alpha: Ref<number | null> = ref(null)
const beta: Ref<number | null> = ref(null)
const gamma: Ref<number | null> = ref(null)

if (window && isSupported) {
if (window && isSupported.value) {
useEventListener(window, 'deviceorientation', (event) => {
isAbsolute.value = event.absolute
alpha.value = event.alpha
Expand Down
23 changes: 10 additions & 13 deletions packages/core/useDevicesList/index.ts
@@ -1,5 +1,6 @@
/* this implementation is original ported from https://github.com/logaretm/vue-use-web by Abdelrahman Awad */

import { isSup } from '@vueuse/shared'
import type { ComputedRef, Ref } from 'vue-demi'
import { computed, ref } from 'vue-demi'
import { useEventListener } from '../useEventListener'
Expand Down Expand Up @@ -34,7 +35,7 @@ export interface UseDevicesListReturn {
audioOutputs: ComputedRef<MediaDeviceInfo[]>
permissionGranted: Ref<boolean>
ensurePermissions: () => Promise<boolean>
isSupported: boolean
isSupported: Ref<boolean>
}

/**
Expand All @@ -55,19 +56,19 @@ export function useDevicesList(options: UseDevicesListOptions = {}): UseDevicesL
const videoInputs = computed(() => devices.value.filter(i => i.kind === 'videoinput'))
const audioInputs = computed(() => devices.value.filter(i => i.kind === 'audioinput'))
const audioOutputs = computed(() => devices.value.filter(i => i.kind === 'audiooutput'))
let isSupported = false
const isSupported = isSup(() => Boolean(navigator && navigator.mediaDevices && navigator.mediaDevices.enumerateDevices))
const permissionGranted = ref(false)

async function update() {
if (!isSupported)
if (!isSupported.value)
return

devices.value = await navigator!.mediaDevices.enumerateDevices()
onUpdated?.(devices.value)
}

async function ensurePermissions() {
if (!isSupported)
if (!isSupported.value)
return false

if (permissionGranted.value)
Expand All @@ -88,16 +89,12 @@ export function useDevicesList(options: UseDevicesListOptions = {}): UseDevicesL
return permissionGranted.value
}

if (navigator) {
isSupported = Boolean(navigator.mediaDevices && navigator.mediaDevices.enumerateDevices)
if (isSupported.value) {
if (requestPermissions)
ensurePermissions()

if (isSupported) {
if (requestPermissions)
ensurePermissions()

useEventListener(navigator.mediaDevices, 'devicechange', update)
update()
}
useEventListener(navigator!.mediaDevices, 'devicechange', update)
update()
}

return {
Expand Down
5 changes: 3 additions & 2 deletions packages/core/useDisplayMedia/index.ts
@@ -1,4 +1,5 @@
import type { MaybeRef } from '@vueuse/shared'
import { isSup } from '@vueuse/shared'
import type { Ref } from 'vue-demi'
import { ref, shallowRef, watch } from 'vue-demi'
import type { ConfigurableNavigator } from '../_configurable'
Expand Down Expand Up @@ -32,14 +33,14 @@ export function useDisplayMedia(options: UseDisplayMediaOptions = {}) {
const video = options.video
const audio = options.audio
const { navigator = defaultNavigator } = options
const isSupported = Boolean(navigator?.mediaDevices?.getDisplayMedia)
const isSupported = isSup(() => Boolean(navigator?.mediaDevices?.getDisplayMedia))

const constraint: DisplayMediaStreamConstraints = { audio, video }

const stream: Ref<MediaStream | undefined> = shallowRef()

async function _start() {
if (!isSupported || stream.value)
if (!isSupported.value || stream.value)
return
stream.value = await navigator!.mediaDevices.getDisplayMedia(constraint)
return stream.value
Expand Down
5 changes: 3 additions & 2 deletions packages/core/useEyeDropper/index.ts
@@ -1,3 +1,4 @@
import { isSup } from '@vueuse/shared'
import { ref } from 'vue-demi'

export interface EyeDropperOpenOptions {
Expand Down Expand Up @@ -31,11 +32,11 @@ export interface UseEyeDropperOptions {
*/
export function useEyeDropper(options: UseEyeDropperOptions = {}) {
const { initialValue = '' } = options
const isSupported = Boolean(typeof window !== 'undefined' && 'EyeDropper' in window)
const isSupported = isSup(() => Boolean(typeof window !== 'undefined' && 'EyeDropper' in window))
const sRGBHex = ref(initialValue)

async function open(openOptions?: EyeDropperOpenOptions) {
if (!isSupported)
if (!isSupported.value)
return
const eyeDropper: EyeDropper = new (window as any).EyeDropper()
const result = await eyeDropper.open(openOptions)
Expand Down
2 changes: 1 addition & 1 deletion packages/core/useFileDialog/index.md
Expand Up @@ -11,7 +11,7 @@ Open file dialog with ease.
```ts
import { useFileDialog } from '@vueuse/core'

const { files, open, reset } = useDialog()
const { files, open, reset } = useFileDialog()
```

```html
Expand Down
13 changes: 7 additions & 6 deletions packages/core/useFileSystemAccess/index.ts
@@ -1,6 +1,7 @@
import type { Ref } from 'vue-demi'
import { computed, ref, unref, watch } from 'vue-demi'
import type { Awaitable, MaybeRef } from '@vueuse/shared'
import { isSup } from '@vueuse/shared'
import type { ConfigurableWindow } from '../_configurable'
import { defaultWindow } from '../_configurable'

Expand Down Expand Up @@ -102,7 +103,7 @@ export function useFileSystemAccess(options: UseFileSystemAccessOptions = {}): U
dataType = 'Text',
} = unref(options)
const window = _window as FileSystemAccessWindow
const isSupported = Boolean(window && 'showSaveFilePicker' in window && 'showOpenFilePicker' in window)
const isSupported = isSup(() => Boolean(window && 'showSaveFilePicker' in window && 'showOpenFilePicker' in window))

const fileHandle = ref<FileSystemFileHandle>()
const data = ref<string | ArrayBuffer | Blob>()
Expand All @@ -114,7 +115,7 @@ export function useFileSystemAccess(options: UseFileSystemAccessOptions = {}): U
const fileLastModified = computed(() => file.value?.lastModified ?? 0)

async function open(_options: UseFileSystemAccessCommonOptions = {}) {
if (!isSupported)
if (!isSupported.value)
return
const [handle] = await window.showOpenFilePicker({ ...unref(options), ..._options })
fileHandle.value = handle
Expand All @@ -123,7 +124,7 @@ export function useFileSystemAccess(options: UseFileSystemAccessOptions = {}): U
}

async function create(_options: UseFileSystemAccessShowSaveFileOptions = {}) {
if (!isSupported)
if (!isSupported.value)
return
fileHandle.value = await (window as FileSystemAccessWindow).showSaveFilePicker({ ...unref(options), ..._options })
data.value = undefined
Expand All @@ -132,7 +133,7 @@ export function useFileSystemAccess(options: UseFileSystemAccessOptions = {}): U
}

async function save(_options: UseFileSystemAccessShowSaveFileOptions = {}) {
if (!isSupported)
if (!isSupported.value)
return

if (!fileHandle.value)
Expand All @@ -148,7 +149,7 @@ export function useFileSystemAccess(options: UseFileSystemAccessOptions = {}): U
}

async function saveAs(_options: UseFileSystemAccessShowSaveFileOptions = {}) {
if (!isSupported)
if (!isSupported.value)
return

fileHandle.value = await (window as FileSystemAccessWindow).showSaveFilePicker({ ...unref(options), ..._options })
Expand Down Expand Up @@ -194,7 +195,7 @@ export function useFileSystemAccess(options: UseFileSystemAccessOptions = {}): U
}

export interface UseFileSystemAccessReturn<T = string> {
isSupported: boolean
isSupported: Ref<boolean>
data: Ref<T | undefined>
file: Ref<File | undefined>
fileName: Ref<string>
Expand Down
30 changes: 15 additions & 15 deletions packages/core/useFullscreen/index.ts
@@ -1,7 +1,7 @@
/* this implementation is original ported from https://github.com/logaretm/vue-use-web by Abdelrahman Awad */

import { ref } from 'vue-demi'
import { tryOnScopeDispose } from '@vueuse/shared'
import { isSup, tryOnScopeDispose } from '@vueuse/shared'
import type { MaybeElementRef } from '../unrefElement'
import { unrefElement } from '../unrefElement'
import { useEventListener } from '../useEventListener'
Expand Down Expand Up @@ -86,27 +86,27 @@ export function useFullscreen(
const { document = defaultDocument, autoExit = false } = options
const targetRef = target || document?.querySelector('html')
const isFullscreen = ref(false)
let isSupported = false

let map: FunctionMap = functionsMap[0]

if (!document) {
isSupported = false
}
else {
for (const m of functionsMap) {
if (m[1] in document) {
map = m
isSupported = true
break
const isSupported = isSup(() => {
if (!document) {
return false
}
else {
for (const m of functionsMap) {
if (m[1] in document) {
map = m
return true
}
}
}
}
return false
})

const [REQUEST, EXIT, ELEMENT,, EVENT] = map

async function exit() {
if (!isSupported)
if (!isSupported.value)
return
if (document?.[ELEMENT])
await document[EXIT]()
Expand All @@ -115,7 +115,7 @@ export function useFullscreen(
}

async function enter() {
if (!isSupported)
if (!isSupported.value)
return

await exit()
Expand Down
4 changes: 2 additions & 2 deletions packages/core/useGamepad/index.ts
@@ -1,4 +1,4 @@
import { createEventHook, tryOnMounted } from '@vueuse/shared'
import { createEventHook, isSup, tryOnMounted } from '@vueuse/shared'
import type { Ref } from 'vue-demi'
import { computed, ref } from 'vue-demi'
import { useRafFn } from '../useRafFn'
Expand Down Expand Up @@ -62,7 +62,7 @@ export function useGamepad(options: UseGamepadOptions = {}) {
const {
navigator = defaultNavigator,
} = options
const isSupported = navigator && 'getGamepads' in navigator
const isSupported = isSup(() => Boolean(navigator && 'getGamepads' in navigator))
const gamepads = ref<Gamepad[]>([])

const onConnectedHook = createEventHook<number>()
Expand Down