-
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: user friendly permission modal on macos
- Loading branch information
1 parent
7c4fd3f
commit f9d9664
Showing
13 changed files
with
270 additions
and
27 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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
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 |
---|---|---|
@@ -0,0 +1,27 @@ | ||
use accessibility_sys::{kAXTrustedCheckOptionPrompt, AXIsProcessTrustedWithOptions}; | ||
use core_foundation_sys::base::{CFRelease, TCFTypeRef}; | ||
use core_foundation_sys::dictionary::{CFDictionaryAddValue, CFDictionaryCreateMutable}; | ||
use core_foundation_sys::number::{kCFBooleanFalse, kCFBooleanTrue}; | ||
use std::{error::Error, ptr}; | ||
|
||
pub fn check_accessibility(ask_if_not_allowed: bool) -> Result<bool, Box<dyn Error>> { | ||
let is_allowed; | ||
unsafe { | ||
let options = | ||
CFDictionaryCreateMutable(ptr::null_mut(), 0, std::ptr::null(), std::ptr::null()); | ||
let key = kAXTrustedCheckOptionPrompt; | ||
let value = if ask_if_not_allowed { | ||
kCFBooleanTrue | ||
} else { | ||
kCFBooleanFalse | ||
}; | ||
if !options.is_null() { | ||
CFDictionaryAddValue(options, key.as_void_ptr(), value.as_void_ptr()); | ||
is_allowed = AXIsProcessTrustedWithOptions(options); | ||
CFRelease(options as *const _); | ||
} else { | ||
return Err("options is null".into()); | ||
} | ||
} | ||
Ok(is_allowed) | ||
} |
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 |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { cx } from "../lib/utils"; | ||
|
||
interface PermissionModalProps { | ||
allowed: boolean; | ||
checkPermission: (showPrompt: boolean) => void; | ||
} | ||
export default function PermissionModal({ | ||
allowed: granted, | ||
checkPermission, | ||
}: PermissionModalProps) { | ||
return ( | ||
<dialog className={cx("modal", !granted && "modal-open")}> | ||
<div className="modal-box"> | ||
<h3 className="font-bold text-lg">Accessibility</h3> | ||
<p className="py-4"> | ||
Mobslide app lets you use your phone as a remote for presentations. | ||
Just grant accessibility permission. | ||
</p> | ||
<div className="modal-action"> | ||
<button | ||
className="btn btn-primary" | ||
onClick={() => checkPermission(true)} | ||
> | ||
Continue | ||
</button> | ||
</div> | ||
</div> | ||
</dialog> | ||
); | ||
} |
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,3 @@ | ||
export function cx(...cns: (boolean | string | undefined)[]): string { | ||
return cns.filter(Boolean).join(" "); | ||
} |
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,43 @@ | ||
import { invoke } from "@tauri-apps/api/core"; | ||
import * as os from "@tauri-apps/plugin-os"; | ||
import { useEffect, useRef, useState } from "react"; | ||
|
||
export function useAccessibiltyPermission() { | ||
const [isAllowed, setIsAllowed] = useState(true); | ||
const isAllowedOnce = useRef<boolean>(); | ||
const intervalIdRef = useRef<number>(); | ||
|
||
async function checkPermission(showPrompt = true) { | ||
const platform = await os.platform(); | ||
if (platform === "macos") { | ||
const isAllowed = await await invoke("check_accessibility_permission", { | ||
showPrompt, | ||
}); | ||
if (isAllowed) { | ||
isAllowedOnce.current = true; | ||
clearInterval(intervalIdRef.current); | ||
} | ||
setIsAllowed(isAllowed as boolean); | ||
} | ||
} | ||
|
||
async function init() { | ||
const platform = await os.platform(); | ||
|
||
// update permission state every 1 sec without prompt | ||
if (platform === "macos") { | ||
checkPermission(false); | ||
intervalIdRef.current = setInterval( | ||
async () => checkPermission(false), | ||
1000 | ||
); | ||
} | ||
} | ||
|
||
useEffect(() => { | ||
init(); | ||
return () => clearInterval(intervalIdRef.current); | ||
}, []); | ||
|
||
return { isAllowed, checkPermission }; | ||
} |
Oops, something went wrong.