-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #216 from solidjs-community/permission-in-firefox
permission: fix in firefox
- Loading branch information
Showing
8 changed files
with
119 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@solid-primitives/permission": minor | ||
--- | ||
|
||
fix in firefox |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<meta name="theme-color" content="#000000" /> | ||
<title>Solid App</title> | ||
<style> | ||
html { | ||
font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif; | ||
} | ||
|
||
body { | ||
padding: 0; | ||
margin: 0; | ||
} | ||
|
||
a, | ||
button { | ||
cursor: pointer; | ||
} | ||
|
||
* { | ||
margin: 0; | ||
} | ||
</style> | ||
</head> | ||
|
||
<body> | ||
<noscript>You need to enable JavaScript to run this app.</noscript> | ||
<div id="root"></div> | ||
|
||
<script src="./index.tsx" type="module"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { Component } from "solid-js"; | ||
import { render } from "solid-js/web"; | ||
import { createPermission } from "../src"; | ||
import "uno.css"; | ||
|
||
const App: Component = () => { | ||
const micPermission = createPermission("microphone"); | ||
const camPermission = createPermission("camera"); | ||
|
||
const requestPermission = (constraints: MediaStreamConstraints) => | ||
navigator.mediaDevices.getUserMedia(constraints) | ||
.then(stream => stream.getTracks().forEach(track => track.stop())) | ||
.catch(console.warn); | ||
|
||
return ( | ||
<div class="p-24 box-border w-full min-h-screen flex flex-col justify-center items-center space-y-4 bg-gray-800 text-white"> | ||
<div class="wrapper-v"> | ||
<h4>Microphone permission:</h4> | ||
<p>{micPermission}</p> | ||
<h4>Camera permission:</h4> | ||
<p>{camPermission}</p> | ||
<h4>Request permissions:</h4> | ||
<button onClick={() => requestPermission({ audio: true })}>Microphone</button> | ||
<button onClick={() => requestPermission({ video: true })}>Camera</button> | ||
<button onClick={() => requestPermission({ audio: true, video: true })}>Both</button> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
render(() => <App />, document.getElementById("root")!); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import { viteConfig } from "../../../vite.config"; | ||
export default viteConfig; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,50 @@ | ||
import { Accessor, createSignal, onCleanup } from "solid-js"; | ||
import { Accessor, createEffect, createSignal, on, onCleanup } from "solid-js"; | ||
|
||
/** | ||
* Querying the permission API | ||
* | ||
* @param name permission name (e.g. "microphone") or a PermissionDescriptor object (`{ name: ... }`) | ||
* @returns "unknown" | "pending" | "granted" | "rejected" | ||
* @returns "unknown" | "denied" | "granted" | "prompt" | ||
*/ | ||
export const createPermission = ( | ||
name: PermissionDescriptor | PermissionName | ||
name: PermissionDescriptor | PermissionName | "microphone" | "camera" | ||
): Accessor<PermissionState | "unknown"> => { | ||
const [permission, setPermission] = createSignal<PermissionState | "unknown">("unknown"); | ||
const [status, setStatus] = createSignal<PermissionStatus>(); | ||
if (navigator) { | ||
navigator.permissions.query(typeof name === "string" ? { name } : name).then(status => { | ||
setPermission(status.state); | ||
const listener = () => setPermission(status.state); | ||
status.addEventListener("change", listener); | ||
onCleanup(() => status.removeEventListener("change", listener)); | ||
}); | ||
navigator.permissions | ||
.query(typeof name === "string" ? { name: name as PermissionName } : name) | ||
.then(setStatus) | ||
.catch(error => { | ||
if (error.name !== "TypeError" || (name !== "microphone" && name !== "camera")) { | ||
return; | ||
} | ||
// firefox will not allow us to read media permissions, | ||
// so we need to wrap getUserMedia in order to get them: | ||
// TODO: only set to prompt if devices are available | ||
setPermission("prompt"); | ||
const constraint = name === "camera" ? "video" : "audio"; | ||
const getUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices); | ||
navigator.mediaDevices.getUserMedia = constraints => | ||
constraints?.[constraint] | ||
? getUserMedia(constraints) | ||
.then(stream => (setPermission("granted"), stream)) | ||
.catch(error => { | ||
if (/not allowed/.test(error.message)) { | ||
setPermission("denied"); | ||
} | ||
return Promise.reject(error); | ||
}) | ||
: getUserMedia(constraints); | ||
}); | ||
createEffect(on(status, (status) => { | ||
if (status) { | ||
setPermission(status.state); | ||
const listener = () => setPermission(status.state); | ||
status.addEventListener("change", listener); | ||
onCleanup(() => status.removeEventListener("change", listener)); | ||
} | ||
})) | ||
} | ||
return permission; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,3 @@ | ||
import { Accessor } from "solid-js"; | ||
import * as API from "."; | ||
|
||
/** | ||
* Querying the permission API | ||
* | ||
* @param name permission name (e.g. "microphone") or a PermissionDescriptor object (`{ name: ... }`) | ||
* @returns "unknown" | "pending" | "granted" | "rejected" | ||
*/ | ||
export const createPermission = ( | ||
_name: PermissionDescriptor | PermissionName | ||
): Accessor<PermissionState | "unknown"> => { | ||
return () => "unknown"; | ||
}; | ||
export const createPermission: typeof API.createPermission = () => () => "unknown"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,5 @@ | ||
{ | ||
"extends": "../../tsconfig.json", | ||
"compilerOptions": { | ||
"outDir": "./dist", | ||
"emitDeclarationOnly": false | ||
}, | ||
"include": ["./src"] | ||
"include": ["./src", "./test", "./dev"], | ||
"exclude": ["node_modules", "./dist"] | ||
} |