@buoy-gg/permissions 7.0.44 → 7.0.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.configureAppSettings=configureAppSettings;exports.installRnpSettingsIntercept=installRnpSettingsIntercept;exports.installSettingsIntercept=installSettingsIntercept;exports.notifyAppOfChange=notifyAppOfChange;exports.openSettingsStandIn=openSettingsStandIn;exports.settingsTarget=settingsTarget;exports.simulateLeaveApp=simulateLeaveApp;exports.simulateReturnToApp=simulateReturnToApp;var _sharedUi=require("@buoy-gg/shared-ui");var _model=require("./model");var _store=require("./store");var _wrap=require("./adapters/wrap");let emitter=null;let alert=null;function configureAppSettings(e){emitter=e.emitter;alert=e.alert}function emitAppState(e){try{emitter?.emit("appStateDidChange",{app_state:e,[_sharedUi.BUOY_SYNTHETIC_MARK]:true})}catch{}}function simulateLeaveApp(){if((0,_store.getPlatform)()==="ios")emitAppState("inactive");emitAppState("background")}function simulateReturnToApp(){emitAppState("active")}let notifyTimer=null;let standInOpen=false;function notifyAppOfChange(){if(!emitter||standInOpen)return;if(notifyTimer)clearTimeout(notifyTimer);notifyTimer=setTimeout(()=>{notifyTimer=null;simulateLeaveApp();setTimeout(simulateReturnToApp,60)},120)}function settingsTarget(){const{log:e,permissions:r}=(0,_store.getPermissionsSnapshot)();const n=t=>t==="denied"||t==="blocked"||t==="restricted";const i=e.filter(t=>t.permission&&t.overridden&&(0,_store.getOverride)(t.permission)!==null);const s=i.find(t=>n((0,_store.getOverride)(t.permission)));if(s)return s.permission;const a=r.find(t=>t.override!==null&&n(t.override));if(a)return a.id;if(i[0])return i[0].permission;const u=r.find(t=>t.override!==null);return u?.id??null}function settingsChoices(e){const r=(0,_store.getPlatform)();return(0,_model.supportedStates)(e,r).filter(n=>(n!=="undetermined"||r==="ios"&&e==="location")&&n!=="restricted"&&!(r==="android"&&n==="blocked"))}function openSettingsStandIn(e,r){const n=(0,_store.getPlatform)();const i=(0,_model.permissionInfo)(e);const s=(0,_store.getOverride)(e);(0,_store.recordCall)({source:r,method:"openSettings",permission:e,kind:"settings",real:null,returned:s,overridden:true});simulateLeaveApp();standInOpen=true;return new Promise(a=>{let u=false;const t=()=>{if(u)return;u=true;standInOpen=false;simulateReturnToApp();a()};if(!alert){t();return}const p=settingsChoices(e);const l=n==="android"?p.filter(o=>o!==s).slice(0,2):p;const c=l.map(o=>({text:`${o===s?"\u2713 ":""}${(0,_model.settingsLabel)(e,n,o)}`,onPress:()=>{try{(0,_store.setOverride)(e,o)}catch{}t()}}));c.push({text:"Back to App",onPress:t,style:"cancel"});alert.alert(i.label,"Buoy's stand-in for Settings. Pick what the app gets when it comes back.",c,{cancelable:true,onDismiss:t})})}function shouldIntercept(){return(0,_store.getSettings)().interceptSettings&&(0,_store.anyOverride)()&&settingsTarget()!==null}function isAppSettingsUrl(e){return typeof e==="string"&&/^app-settings:/i.test(e)}function installSettingsIntercept(e){if(!e)return;(0,_wrap.wrapMethod)(e,"openSettings",r=>(...n)=>{if(!shouldIntercept())return r(...n);return openSettingsStandIn(settingsTarget(),"Linking")});(0,_wrap.wrapMethod)(e,"openURL",r=>(...n)=>{if(!isAppSettingsUrl(n[0])||!shouldIntercept())return r(...n);return openSettingsStandIn(settingsTarget(),"Linking")})}function installRnpSettingsIntercept(e){if(!e)return;(0,_wrap.wrapMethod)(e,"openSettings",r=>(...n)=>{const i=n[0];if(i!==void 0&&i!=="application"&&i!=="notifications"||!shouldIntercept()){return r(...n)}const s=i==="notifications"&&(0,_store.getOverride)("notifications")!==null?"notifications":settingsTarget();return openSettingsStandIn(s,"react-native-permissions")})}
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.closeSettingsStandIn=closeSettingsStandIn;exports.configureAppSettings=configureAppSettings;exports.installRnpSettingsIntercept=installRnpSettingsIntercept;exports.installSettingsIntercept=installSettingsIntercept;exports.isSettingsStandInOpen=isSettingsStandInOpen;exports.notifyAppOfChange=notifyAppOfChange;exports.openSettingsStandIn=openSettingsStandIn;exports.settingsTarget=settingsTarget;exports.simulateLeaveApp=simulateLeaveApp;exports.simulateReturnToApp=simulateReturnToApp;var _sharedUi=require("@buoy-gg/shared-ui");var _model=require("./model");var _store=require("./store");var _wrap=require("./adapters/wrap");let emitter=null;let alert=null;function configureAppSettings(e){emitter=e.emitter;alert=e.alert}function emitAppState(e){try{emitter?.emit("appStateDidChange",{app_state:e,[_sharedUi.BUOY_SYNTHETIC_MARK]:true})}catch{}}function simulateLeaveApp(){if((0,_store.getPlatform)()==="ios")emitAppState("inactive");emitAppState("background")}function simulateReturnToApp(){emitAppState("active")}let notifyTimer=null;let standInOpen=false;let closeStandIn=null;function isSettingsStandInOpen(){return standInOpen}function closeSettingsStandIn(){if(!closeStandIn)return false;closeStandIn();return true}function notifyAppOfChange(){if(!emitter||standInOpen)return;if(notifyTimer)clearTimeout(notifyTimer);notifyTimer=setTimeout(()=>{notifyTimer=null;simulateLeaveApp();setTimeout(simulateReturnToApp,60)},120)}function settingsTarget(){const{log:e,permissions:r}=(0,_store.getPermissionsSnapshot)();const n=t=>t==="denied"||t==="blocked"||t==="restricted";const i=e.filter(t=>t.permission&&t.overridden&&(0,_store.getOverride)(t.permission)!==null);const s=i.find(t=>n((0,_store.getOverride)(t.permission)));if(s)return s.permission;const u=r.find(t=>t.override!==null&&n(t.override));if(u)return u.id;if(i[0])return i[0].permission;const a=r.find(t=>t.override!==null);return a?.id??null}function settingsChoices(e){const r=(0,_store.getPlatform)();return(0,_model.supportedStates)(e,r).filter(n=>(n!=="undetermined"||r==="ios"&&e==="location")&&n!=="restricted"&&!(r==="android"&&n==="blocked"))}function openSettingsStandIn(e,r){const n=(0,_store.getPlatform)();const i=(0,_model.permissionInfo)(e);const s=(0,_store.getOverride)(e);(0,_store.recordCall)({source:r,method:"openSettings",permission:e,kind:"settings",real:null,returned:s,overridden:true});simulateLeaveApp();standInOpen=true;return new Promise(u=>{let a=false;const t=()=>{if(a)return;a=true;standInOpen=false;closeStandIn=null;simulateReturnToApp();u()};closeStandIn=t;if(!alert){t();return}const p=settingsChoices(e);const c=n==="android"?p.filter(o=>o!==s).slice(0,2):p;const l=c.map(o=>({text:`${o===s?"\u2713 ":""}${(0,_model.settingsLabel)(e,n,o)}`,onPress:()=>{try{(0,_store.setOverride)(e,o)}catch{}t()}}));l.push({text:"Back to App",onPress:t,style:"cancel"});alert.alert(i.label,"Buoy's stand-in for Settings. Pick what the app gets when it comes back.",l,{cancelable:true,onDismiss:t})})}function shouldIntercept(){return(0,_store.getSettings)().interceptSettings&&(0,_store.anyOverride)()&&settingsTarget()!==null}function isAppSettingsUrl(e){return typeof e==="string"&&/^app-settings:/i.test(e)}function installSettingsIntercept(e){if(!e)return;(0,_wrap.wrapMethod)(e,"openSettings",r=>(...n)=>{if(!shouldIntercept())return r(...n);return openSettingsStandIn(settingsTarget(),"Linking")});(0,_wrap.wrapMethod)(e,"openURL",r=>(...n)=>{if(!isAppSettingsUrl(n[0])||!shouldIntercept())return r(...n);return openSettingsStandIn(settingsTarget(),"Linking")})}function installRnpSettingsIntercept(e){if(!e)return;(0,_wrap.wrapMethod)(e,"openSettings",r=>(...n)=>{const i=n[0];if(i!==void 0&&i!=="application"&&i!=="notifications"||!shouldIntercept()){return r(...n)}const s=i==="notifications"&&(0,_store.getOverride)("notifications")!==null?"notifications":settingsTarget();return openSettingsStandIn(s,"react-native-permissions")})}
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.permissionsSyncAdapter=void 0;var _sharedUi=require("@buoy-gg/shared-ui");var _expo=require("../engine/adapters/expo");var _appSettings=require("../engine/appSettings");var _store=require("../engine/store");function obj(e){return e&&typeof e==="object"?e:{}}function permissionParam(e){return e.permission??e.id??e.permissionId??e.name}function boolParam(e,r){const t=e[r];if(typeof t==="boolean")return t;if(t==="true")return true;if(t==="false")return false;return void 0}const permissionsSyncAdapter=exports.permissionsSyncAdapter=(0,_sharedUi.createSyncAdapter)({version:1,getSnapshot(){return(0,_store.getPermissionsSnapshot)()},subscribe(e){return(0,_store.subscribePermissions)(e)},actions:{async getState(){await(0,_expo.refreshExpoRealStates)();return(0,_store.getPermissionsSnapshot)()},setOverride(e){const r=obj(e);const t=permissionParam(r);const s=r.state??r.status??r.value;if(t===void 0||s===void 0){throw new Error('setOverride needs `permission` (e.g. "location", "camera", "notifications") and `state` ("undetermined", "granted", "limited", "denied", "blocked" or "restricted").')}return(0,_store.setOverride)(t,s)},clearOverride(e){const r=permissionParam(obj(e));if(r===void 0)throw new Error("clearOverride needs `permission`.");return(0,_store.clearOverride)(r)},requestReal(e){const r=permissionParam(obj(e));if(r===void 0)throw new Error("requestReal needs `permission`.");return(0,_store.requestRealPermission)(r)},resetAll(){return(0,_store.resetPermissions)()},updateSettings(e){const r=obj(e);return(0,_store.updatePermissionSettings)({requestAnswer:r.requestAnswer??r.answer,persist:boolParam(r,"persist"),showChip:boolParam(r,"showChip"),notifyApp:boolParam(r,"notifyApp"),enforce:boolParam(r,"enforce"),interceptSettings:boolParam(r,"interceptSettings")})},clearLog(){return(0,_store.clearPermissionLog)()},simulateReturnFromSettings(){(0,_appSettings.notifyAppOfChange)();return(0,_store.getPermissionsSnapshot)()}}});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.permissionsSyncAdapter=void 0;var _sharedUi=require("@buoy-gg/shared-ui");var _expo=require("../engine/adapters/expo");var _appSettings=require("../engine/appSettings");var _store=require("../engine/store");function obj(e){return e&&typeof e==="object"?e:{}}function permissionParam(e){return e.permission??e.id??e.permissionId??e.name}function boolParam(e,r){const t=e[r];if(typeof t==="boolean")return t;if(t==="true")return true;if(t==="false")return false;return void 0}const permissionsSyncAdapter=exports.permissionsSyncAdapter=(0,_sharedUi.createSyncAdapter)({version:1,getSnapshot(){return(0,_store.getPermissionsSnapshot)()},subscribe(e){return(0,_store.subscribePermissions)(e)},actions:{async getState(){await(0,_expo.refreshExpoRealStates)();return(0,_appSettings.isSettingsStandInOpen)()?{...(0,_store.getPermissionsSnapshot)(),settingsStandInOpen:true}:(0,_store.getPermissionsSnapshot)()},setOverride(e){const r=obj(e);const t=permissionParam(r);const n=r.state??r.status??r.value;if(t===void 0||n===void 0){throw new Error('setOverride needs `permission` (e.g. "location", "camera", "notifications") and `state` ("undetermined", "granted", "limited", "denied", "blocked" or "restricted").')}(0,_appSettings.closeSettingsStandIn)();return(0,_store.setOverride)(t,n)},clearOverride(e){const r=permissionParam(obj(e));if(r===void 0)throw new Error("clearOverride needs `permission`.");(0,_appSettings.closeSettingsStandIn)();return(0,_store.clearOverride)(r)},requestReal(e){const r=permissionParam(obj(e));if(r===void 0)throw new Error("requestReal needs `permission`.");return(0,_store.requestRealPermission)(r)},resetAll(){(0,_appSettings.closeSettingsStandIn)();return(0,_store.resetPermissions)()},updateSettings(e){const r=obj(e);return(0,_store.updatePermissionSettings)({requestAnswer:r.requestAnswer??r.answer,persist:boolParam(r,"persist"),showChip:boolParam(r,"showChip"),notifyApp:boolParam(r,"notifyApp"),enforce:boolParam(r,"enforce"),interceptSettings:boolParam(r,"interceptSettings")})},clearLog(){return(0,_store.clearPermissionLog)()},simulateReturnFromSettings(){if(!(0,_appSettings.closeSettingsStandIn)())(0,_appSettings.notifyAppOfChange)();return(0,_store.getPermissionsSnapshot)()}}});
@@ -1 +1 @@
1
- "use strict";import{BUOY_SYNTHETIC_MARK as b}from"@buoy-gg/shared-ui";import{permissionInfo as k,settingsLabel as A,supportedStates as T}from"./model";import{anyOverride as I,getOverride as p,getPermissionsSnapshot as w,getPlatform as a,getSettings as O,recordCall as P,setOverride as R}from"./store";import{wrapMethod as f}from"./adapters/wrap";let d=null;let m=null;export function configureAppSettings(t){d=t.emitter;m=t.alert}function g(t){try{d?.emit("appStateDidChange",{app_state:t,[b]:true})}catch{}}export function simulateLeaveApp(){if(a()==="ios")g("inactive");g("background")}export function simulateReturnToApp(){g("active")}let l=null;let S=false;export function notifyAppOfChange(){if(!d||S)return;if(l)clearTimeout(l);l=setTimeout(()=>{l=null;simulateLeaveApp();setTimeout(simulateReturnToApp,60)},120)}export function settingsTarget(){const{log:t,permissions:r}=w();const n=e=>e==="denied"||e==="blocked"||e==="restricted";const i=t.filter(e=>e.permission&&e.overridden&&p(e.permission)!==null);const o=i.find(e=>n(p(e.permission)));if(o)return o.permission;const c=r.find(e=>e.override!==null&&n(e.override));if(c)return c.id;if(i[0])return i[0].permission;const u=r.find(e=>e.override!==null);return u?.id??null}function C(t){const r=a();return T(t,r).filter(n=>(n!=="undetermined"||r==="ios"&&t==="location")&&n!=="restricted"&&!(r==="android"&&n==="blocked"))}export function openSettingsStandIn(t,r){const n=a();const i=k(t);const o=p(t);P({source:r,method:"openSettings",permission:t,kind:"settings",real:null,returned:o,overridden:true});simulateLeaveApp();S=true;return new Promise(c=>{let u=false;const e=()=>{if(u)return;u=true;S=false;simulateReturnToApp();c()};if(!m){e();return}const v=C(t);const y=n==="android"?v.filter(s=>s!==o).slice(0,2):v;const x=y.map(s=>({text:`${s===o?"\u2713 ":""}${A(t,n,s)}`,onPress:()=>{try{R(t,s)}catch{}e()}}));x.push({text:"Back to App",onPress:e,style:"cancel"});m.alert(i.label,"Buoy's stand-in for Settings. Pick what the app gets when it comes back.",x,{cancelable:true,onDismiss:e})})}function h(){return O().interceptSettings&&I()&&settingsTarget()!==null}function L(t){return typeof t==="string"&&/^app-settings:/i.test(t)}export function installSettingsIntercept(t){if(!t)return;f(t,"openSettings",r=>(...n)=>{if(!h())return r(...n);return openSettingsStandIn(settingsTarget(),"Linking")});f(t,"openURL",r=>(...n)=>{if(!L(n[0])||!h())return r(...n);return openSettingsStandIn(settingsTarget(),"Linking")})}export function installRnpSettingsIntercept(t){if(!t)return;f(t,"openSettings",r=>(...n)=>{const i=n[0];if(i!==void 0&&i!=="application"&&i!=="notifications"||!h()){return r(...n)}const o=i==="notifications"&&p("notifications")!==null?"notifications":settingsTarget();return openSettingsStandIn(o,"react-native-permissions")})}
1
+ "use strict";import{BUOY_SYNTHETIC_MARK as b}from"@buoy-gg/shared-ui";import{permissionInfo as k,settingsLabel as A,supportedStates as T}from"./model";import{anyOverride as O,getOverride as l,getPermissionsSnapshot as w,getPlatform as d,getSettings as P,recordCall as R,setOverride as C}from"./store";import{wrapMethod as m}from"./adapters/wrap";let g=null;let S=null;export function configureAppSettings(t){g=t.emitter;S=t.alert}function h(t){try{g?.emit("appStateDidChange",{app_state:t,[b]:true})}catch{}}export function simulateLeaveApp(){if(d()==="ios")h("inactive");h("background")}export function simulateReturnToApp(){h("active")}let p=null;let a=false;let f=null;export function isSettingsStandInOpen(){return a}export function closeSettingsStandIn(){if(!f)return false;f();return true}export function notifyAppOfChange(){if(!g||a)return;if(p)clearTimeout(p);p=setTimeout(()=>{p=null;simulateLeaveApp();setTimeout(simulateReturnToApp,60)},120)}export function settingsTarget(){const{log:t,permissions:r}=w();const n=e=>e==="denied"||e==="blocked"||e==="restricted";const i=t.filter(e=>e.permission&&e.overridden&&l(e.permission)!==null);const o=i.find(e=>n(l(e.permission)));if(o)return o.permission;const u=r.find(e=>e.override!==null&&n(e.override));if(u)return u.id;if(i[0])return i[0].permission;const c=r.find(e=>e.override!==null);return c?.id??null}function L(t){const r=d();return T(t,r).filter(n=>(n!=="undetermined"||r==="ios"&&t==="location")&&n!=="restricted"&&!(r==="android"&&n==="blocked"))}export function openSettingsStandIn(t,r){const n=d();const i=k(t);const o=l(t);R({source:r,method:"openSettings",permission:t,kind:"settings",real:null,returned:o,overridden:true});simulateLeaveApp();a=true;return new Promise(u=>{let c=false;const e=()=>{if(c)return;c=true;a=false;f=null;simulateReturnToApp();u()};f=e;if(!S){e();return}const v=L(t);const I=n==="android"?v.filter(s=>s!==o).slice(0,2):v;const y=I.map(s=>({text:`${s===o?"\u2713 ":""}${A(t,n,s)}`,onPress:()=>{try{C(t,s)}catch{}e()}}));y.push({text:"Back to App",onPress:e,style:"cancel"});S.alert(i.label,"Buoy's stand-in for Settings. Pick what the app gets when it comes back.",y,{cancelable:true,onDismiss:e})})}function x(){return P().interceptSettings&&O()&&settingsTarget()!==null}function B(t){return typeof t==="string"&&/^app-settings:/i.test(t)}export function installSettingsIntercept(t){if(!t)return;m(t,"openSettings",r=>(...n)=>{if(!x())return r(...n);return openSettingsStandIn(settingsTarget(),"Linking")});m(t,"openURL",r=>(...n)=>{if(!B(n[0])||!x())return r(...n);return openSettingsStandIn(settingsTarget(),"Linking")})}export function installRnpSettingsIntercept(t){if(!t)return;m(t,"openSettings",r=>(...n)=>{const i=n[0];if(i!==void 0&&i!=="application"&&i!=="notifications"||!x()){return r(...n)}const o=i==="notifications"&&l("notifications")!==null?"notifications":settingsTarget();return openSettingsStandIn(o,"react-native-permissions")})}
@@ -1 +1 @@
1
- "use strict";import{createSyncAdapter as a}from"@buoy-gg/shared-ui";import{refreshExpoRealStates as c}from"../engine/adapters/expo";import{notifyAppOfChange as d}from"../engine/appSettings";import{clearOverride as p,clearPermissionLog as f,getPermissionsSnapshot as i,requestRealPermission as m,resetPermissions as l,setOverride as g,subscribePermissions as w,updatePermissionSettings as h}from"../engine/store";function s(e){return e&&typeof e==="object"?e:{}}function o(e){return e.permission??e.id??e.permissionId??e.name}function n(e,r){const t=e[r];if(typeof t==="boolean")return t;if(t==="true")return true;if(t==="false")return false;return void 0}export const permissionsSyncAdapter=a({version:1,getSnapshot(){return i()},subscribe(e){return w(e)},actions:{async getState(){await c();return i()},setOverride(e){const r=s(e);const t=o(r);const u=r.state??r.status??r.value;if(t===void 0||u===void 0){throw new Error('setOverride needs `permission` (e.g. "location", "camera", "notifications") and `state` ("undetermined", "granted", "limited", "denied", "blocked" or "restricted").')}return g(t,u)},clearOverride(e){const r=o(s(e));if(r===void 0)throw new Error("clearOverride needs `permission`.");return p(r)},requestReal(e){const r=o(s(e));if(r===void 0)throw new Error("requestReal needs `permission`.");return m(r)},resetAll(){return l()},updateSettings(e){const r=s(e);return h({requestAnswer:r.requestAnswer??r.answer,persist:n(r,"persist"),showChip:n(r,"showChip"),notifyApp:n(r,"notifyApp"),enforce:n(r,"enforce"),interceptSettings:n(r,"interceptSettings")})},clearLog(){return f()},simulateReturnFromSettings(){d();return i()}}});
1
+ "use strict";import{createSyncAdapter as d}from"@buoy-gg/shared-ui";import{refreshExpoRealStates as c}from"../engine/adapters/expo";import{closeSettingsStandIn as s,isSettingsStandInOpen as p,notifyAppOfChange as f}from"../engine/appSettings";import{clearOverride as m,clearPermissionLog as l,getPermissionsSnapshot as i,requestRealPermission as g,resetPermissions as S,setOverride as w,subscribePermissions as h,updatePermissionSettings as b}from"../engine/store";function o(e){return e&&typeof e==="object"?e:{}}function a(e){return e.permission??e.id??e.permissionId??e.name}function n(e,r){const t=e[r];if(typeof t==="boolean")return t;if(t==="true")return true;if(t==="false")return false;return void 0}export const permissionsSyncAdapter=d({version:1,getSnapshot(){return i()},subscribe(e){return h(e)},actions:{async getState(){await c();return p()?{...i(),settingsStandInOpen:true}:i()},setOverride(e){const r=o(e);const t=a(r);const u=r.state??r.status??r.value;if(t===void 0||u===void 0){throw new Error('setOverride needs `permission` (e.g. "location", "camera", "notifications") and `state` ("undetermined", "granted", "limited", "denied", "blocked" or "restricted").')}s();return w(t,u)},clearOverride(e){const r=a(o(e));if(r===void 0)throw new Error("clearOverride needs `permission`.");s();return m(r)},requestReal(e){const r=a(o(e));if(r===void 0)throw new Error("requestReal needs `permission`.");return g(r)},resetAll(){s();return S()},updateSettings(e){const r=o(e);return b({requestAnswer:r.requestAnswer??r.answer,persist:n(r,"persist"),showChip:n(r,"showChip"),notifyApp:n(r,"notifyApp"),enforce:n(r,"enforce"),interceptSettings:n(r,"interceptSettings")})},clearLog(){return l()},simulateReturnFromSettings(){if(!s())f();return i()}}});
@@ -11,6 +11,16 @@ export declare function configureAppSettings(options: {
11
11
  export declare function simulateLeaveApp(): void;
12
12
  /** Come back from Settings. iOS reports background (will-enter-foreground) then active. */
13
13
  export declare function simulateReturnToApp(): void;
14
+ /** Whether Buoy's Settings stand-in is waiting on a tap. */
15
+ export declare function isSettingsStandInOpen(): boolean;
16
+ /**
17
+ * Close the stand-in the way "Back to App" does. An agent that taps "Open
18
+ * Settings" opens a native alert it can never tap; until someone does, every
19
+ * later change was silent (notifyAppOfChange returns while it is open) and the
20
+ * app never re-read its permissions (BK location suite). The native alert may
21
+ * stay drawn — React Native can't dismiss one — but its buttons do nothing now.
22
+ */
23
+ export declare function closeSettingsStandIn(): boolean;
14
24
  /**
15
25
  * After a change from the tool: background → active, so screens that
16
26
  * re-check permissions when the app comes back see the new state. Batched,
@@ -1,7 +1,9 @@
1
1
  import { type PermissionsSnapshot } from "../engine/store";
2
2
  export declare const permissionsSyncAdapter: import("@buoy-gg/shared-ui").SyncAdapter<PermissionsSnapshot, {
3
3
  /** Current overrides, what the OS says, and the recent calls. Re-reads the OS first. */
4
- getState(): Promise<PermissionsSnapshot>;
4
+ getState(): Promise<PermissionsSnapshot & {
5
+ settingsStandInOpen?: true;
6
+ }>;
5
7
  setOverride(params: unknown): PermissionsSnapshot;
6
8
  clearOverride(params: unknown): PermissionsSnapshot;
7
9
  /**
package/lib/web/index.mjs CHANGED
@@ -1 +1 @@
1
- "use client";var ge=Object.defineProperty;var Xe=Object.getOwnPropertyDescriptor;var Qe=Object.getOwnPropertyNames;var et=Object.prototype.hasOwnProperty;var tt=(e,t)=>{for(var n in t)ge(e,n,{get:t[n],enumerable:true})},ye=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Qe(t))!et.call(e,i)&&i!==n&&ge(e,i,{get:()=>t[i],enumerable:!(o=Xe(t,i))||o.enumerable});return e},nt=(e,t,n)=>(ye(e,t,"default"),n&&ye(n,t,"default"));var be=process.env.NODE_ENV!=="production";typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);function Q(){return false}import{useEffect as ot,useSyncExternalStore as we}from"react";var ve={};tt(ve,{AccessibilityInfo:()=>at,ActivityIndicator:()=>nn,Alert:()=>sn,Animated:()=>lt,AppRegistry:()=>dt,AppState:()=>ut,Appearance:()=>ct,BackHandler:()=>pt,Button:()=>on,CheckBox:()=>Tt,Clipboard:()=>mt,DeviceEventEmitter:()=>Ut,Dimensions:()=>ht,Easing:()=>ft,FlatList:()=>Ot,I18nManager:()=>gt,Image:()=>Ct,ImageBackground:()=>Et,InteractionManager:()=>bt,Keyboard:()=>yt,KeyboardAvoidingView:()=>Nt,LayoutAnimation:()=>wt,Linking:()=>vt,LogBox:()=>Vt,Modal:()=>en,NativeEventEmitter:()=>At,NativeModules:()=>st,PanResponder:()=>St,Picker:()=>Dt,PixelRatio:()=>Pt,Platform:()=>xt,Pressable:()=>Qt,ProgressBar:()=>Lt,RefreshControl:()=>qt,SafeAreaView:()=>_t,ScrollView:()=>Ae,SectionList:()=>Mt,Share:()=>Rt,StatusBar:()=>Bt,StyleSheet:()=>j,Switch:()=>tn,Text:()=>h,TextInput:()=>Jt,Touchable:()=>$t,TouchableHighlight:()=>Zt,TouchableNativeFeedback:()=>zt,TouchableOpacity:()=>P,TouchableWithoutFeedback:()=>Xt,UIManager:()=>kt,Vibration:()=>It,View:()=>g,VirtualizedList:()=>jt,YellowBox:()=>Ht,findNodeHandle:()=>rn,unstable_createElement:()=>rt,useColorScheme:()=>Ft,useLocaleContext:()=>Wt,useWindowDimensions:()=>Kt});nt(ve,it);import*as it from"react-native-web";import{unstable_createElement as rt,NativeModules as st,AccessibilityInfo as at,Animated as lt,Appearance as ct,AppRegistry as dt,AppState as ut,BackHandler as pt,Clipboard as mt,Dimensions as ht,Easing as ft,I18nManager as gt,Keyboard as yt,InteractionManager as bt,LayoutAnimation as wt,Linking as vt,NativeEventEmitter as At,PanResponder as St,PixelRatio as Pt,Platform as xt,Share as Rt,StyleSheet as j,UIManager as kt,Vibration as It,CheckBox as Tt,FlatList as Ot,Image as Ct,ImageBackground as Et,KeyboardAvoidingView as Nt,Picker as Dt,ProgressBar as Lt,RefreshControl as qt,SafeAreaView as _t,SectionList as Mt,StatusBar as Bt,Touchable as $t,TouchableNativeFeedback as zt,VirtualizedList as jt,YellowBox as Ht,LogBox as Vt,DeviceEventEmitter as Ut,useColorScheme as Ft,useLocaleContext as Wt,useWindowDimensions as Kt}from"react-native-web";import*as w from"react-native-web";import{createElement as Gt,forwardRef as Yt}from"react";function A(e){let t=Yt((o,i)=>{let{accessibilityState:l,accessibilityValue:c,...m}=o;for(let d of["busy","checked","disabled","expanded","selected"])l?.[d]!==void 0&&m[`aria-${d}`]===void 0&&(m[`aria-${d}`]=l[d]);for(let[d,u]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))c?.[d]!==void 0&&m[`aria-${u}`]===void 0&&(m[`aria-${u}`]=c[d]);return Gt(e,{...m,ref:i})}),n=e.State;return n&&Object.assign(t,{State:n}),t.displayName=e.displayName??e.name??"NativeWebView",t}var g=A(w.View),h=A(w.Text),Jt=A(w.TextInput),P=A(w.TouchableOpacity),Zt=A(w.TouchableHighlight),Xt=A(w.TouchableWithoutFeedback),Qt=A(w.Pressable),Ae=A(w.ScrollView),en=A(w.Modal),tn=A(w.Switch),nn=A(w.ActivityIndicator),on=A(w.Button),rn=w.findNodeHandle,sn={alert(e,t,n,o){if(typeof document>"u")return;let i=document.createElement("dialog");i.dataset.buoyRoot="",i.setAttribute("aria-label",e),i.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let l=document.createElement("h2");if(l.textContent=e,l.style.cssText="font-size:18px;margin:0 0 12px",i.appendChild(l),t){let u=document.createElement("p");u.textContent=t,u.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",i.appendChild(u)}let c=document.createElement("div");c.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let m=n?.length?n:[{text:"OK"}],d=()=>{i.close?.(),i.remove()};for(let u of m){let S=document.createElement("button");S.type="button",S.textContent=u.text??"OK",S.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${u.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,S.onclick=()=>{d(),u.onPress?.()},c.appendChild(S)}i.addEventListener("cancel",u=>{u.preventDefault(),o?.cancelable!==false&&(d(),o?.onDismiss?.())}),i.appendChild(c),document.body.appendChild(i),i.showModal?i.showModal():i.setAttribute("open","")}};import{FloatingTool as Se,PermissionsIcon as Pe,X as an,dismissFloatingTool as ln,getFloatingTools as cn,night as L,openBuoyTool as dn,openFloatingTool as xe}from"@buoy-gg/shared-ui/web";var ee=["undetermined","granted","limited","denied","blocked","restricted"],un=["ask","allow","limited","deny"],te={location:{id:"location",label:"Location",limited:{ios:"Approximate",android:"Approximate"},purpose:"use your location"},locationBackground:{id:"locationBackground",label:"Background Location",purpose:"use your location in the background"},camera:{id:"camera",label:"Camera",purpose:"access your camera"},microphone:{id:"microphone",label:"Microphone",purpose:"access your microphone"},notifications:{id:"notifications",label:"Notifications",limited:{ios:"Provisional"},purpose:"send you notifications"},photos:{id:"photos",label:"Photos",limited:{ios:"Selected Photos",android:"Selected Photos"},purpose:"access your photos"},contacts:{id:"contacts",label:"Contacts",limited:{ios:"Selected Contacts"},purpose:"access your contacts"},calendar:{id:"calendar",label:"Calendar",purpose:"access your calendar"},reminders:{id:"reminders",label:"Reminders",only:"ios",purpose:"access your reminders"},tracking:{id:"tracking",label:"Tracking",only:"ios",purpose:"track your activity across other companies' apps and websites"},motion:{id:"motion",label:"Motion & Fitness",purpose:"access your motion and fitness activity"},bluetooth:{id:"bluetooth",label:"Bluetooth",purpose:"use Bluetooth"}},ne=Object.keys(te);function Re(e){return typeof e=="string"&&(e in te||e.startsWith("android:")&&e.length>8)}function R(e){let t=te[e];if(t)return t;let n=e.slice(8).replace(/^android\.permission\./,"");return{id:e,label:n.toLowerCase().split("_").map(o=>o.charAt(0).toUpperCase()+o.slice(1)).join(" "),only:"android",purpose:`use ${n.toLowerCase().replace(/_/g," ")}`}}function H(e,t){let n=R(e),o=["undetermined","granted"];return n.limited?.[t]&&o.push("limited"),o.push("denied"),t==="android"&&o.push("blocked"),t==="ios"&&e!=="notifications"&&o.push("restricted"),o}function pn(e,t,n){return H(e,t).includes(n)}function mn(e,t,n){return pn(e,t,n)?n:n==="blocked"?"denied":n==="restricted"?t==="android"?"blocked":"denied":n==="limited"?"granted":n}function hn(e,t,n){switch(n){case"undetermined":return"Never asked. The next request shows a prompt.";case"granted":return"Full access.";case"limited":return e==="location"?"Allowed, with an approximate position.":e==="photos"?"Allowed for the photos the person picked.":e==="contacts"?"Allowed for the contacts the person picked.":e==="notifications"?"Delivered quietly to Notification Center, without asking.":"Partial access.";case"denied":return t==="ios"?"The person said no. The app can't ask again, only send them to Settings.":"The person said no once. The app can ask one more time.";case"blocked":return"The person said no for good. Only Settings can change it.";case"restricted":return"Turned off by Screen Time or device management. The person can't change it."}}function fn(e,t){if(!e||typeof e!="object")return null;let n=e,o=typeof n.ios?.status=="number"?n.ios.status:void 0;return o===3||o===4?"limited":n.status==="granted"?n.accessPrivileges==="limited"||n.ios?.accuracy==="reduced"||n.android?.accuracy==="coarse"?"limited":"granted":n.status==="denied"?t==="android"&&n.canAskAgain===false?"blocked":"denied":n.status==="undetermined"?"undetermined":null}function k(e,t,n){switch(n){case"undetermined":return"Not Asked";case"granted":return"Allowed";case"limited":return R(e).limited?.[t]??"Limited";case"denied":return"Denied";case"blocked":return"Blocked";case"restricted":return"Restricted"}}import{devToolsStorageKeys as gn,persistentStorage as yn}from"@buoy-gg/shared-ui/web";var I={requestAnswer:"ask",persist:true,showChip:true,notifyApp:true,enforce:true,interceptSettings:true},bn=gn.permissions.state();function q(e,t){return typeof e=="boolean"?e:t}function wn(e){let t=e&&typeof e=="object"?e:{};return{requestAnswer:un.includes(t.requestAnswer)?t.requestAnswer:I.requestAnswer,persist:q(t.persist,I.persist),showChip:q(t.showChip,I.showChip),notifyApp:q(t.notifyApp,I.notifyApp),enforce:q(t.enforce,I.enforce),interceptSettings:q(t.interceptSettings,I.interceptSettings)}}var oe=Promise.resolve();function ke(e){let t=JSON.stringify(e);return oe=oe.then(()=>yn.setItem(bn,t)).catch(()=>{}),oe.then(()=>{})}var vn=50,Ie="__buoyPermissionsStore",Te=globalThis,r=Te[Ie]??(Te[Ie]={platform:"ios",booted:false,overrides:new Map,settings:{...I},seen:new Map,libraries:new Set,log:[],nextLogId:1,listeners:new Set,snapshot:null,prompter:null,changeHooks:new Set,realRequesters:new Map,host:{isSimulator:null,deviceName:null,bundleId:null},once:new Set});r.once??(r.once=new Set);var V=()=>{let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()};function T(){r.snapshot=null;for(let e of Array.from(r.listeners))try{e()}catch{}}function _(){if(!r.settings.persist){ke({v:1,overrides:{},settings:r.settings});return}ke(An())}function An(){return{v:1,overrides:Object.fromEntries(Array.from(r.overrides,([e,t])=>[e,r.once.has(e)?"undetermined":t])),settings:r.settings}}function C(e){let t=r.seen.get(e);return t||(t={sources:new Set,real:null,calls:0,lastCallAt:null,lastReadAt:null,changedAt:null},r.seen.set(e,t)),t}async function Sn(e){let t=ie(e),n=r.realRequesters.get(t);if(!n)throw new Error(`No installed library can ask the system for ${R(t).label}.`);let o=await n();return o!==null&&Ce(t,o),b()}function U(e,t){for(let n of Array.from(r.changeHooks))try{n({id:e,from:t})}catch{}}function Oe(){return r.platform}function Pn(){return r.settings}function xn(e){return r.overrides.get(e)??null}function Rn(e){return r.overrides.has(e)}function kn(){return r.overrides.size>0}function Ce(e,t,n){if(t===null)return;let o=C(e);n&&o.sources.add(n),o.real!==t&&(o.real=t,T())}function ie(e){if(!Re(e))throw new Error(`Unknown permission "${String(e)}". Use one of: ${ne.join(", ")}, or android:<android.permission.NAME>.`);return e}function Ee(e,t){let n=ie(e);if(!ee.includes(t))throw new Error(`Unknown state "${String(t)}". Use one of: ${ee.join(", ")}.`);let o=t,i=H(n,r.platform),l=r.platform==="ios"&&o==="blocked"?"denied":o;if(!i.includes(l))throw new Error(`${R(n).label} can't be "${o}" on ${r.platform}. It can be: ${i.join(", ")}.`);return(r.overrides.get(n)!==l||r.once.has(n))&&(r.overrides.set(n,l),r.once.delete(n),C(n).changedAt=V(),_(),T(),U(n,"tool")),b()}function Ne(e){let t=ie(e);return r.overrides.delete(t)&&(r.once.delete(t),C(t).changedAt=V(),_(),T(),U(t,"tool")),b()}function re(){if(r.overrides.size>0){let e=V();for(let t of r.overrides.keys())C(t).changedAt=e;r.overrides.clear(),r.once.clear(),_(),T(),U(null,"tool")}return b()}function In(){return Object.fromEntries(r.overrides)}function Tn(e){let t=V();for(let n of r.overrides.keys())C(n).changedAt=t;r.overrides.clear(),r.once.clear();for(let[n,o]of Object.entries(e)){let i=n;!o||!Re(i)||(r.overrides.set(i,mn(i,r.platform,o)),C(i).changedAt=t)}return _(),T(),U(null,"tool"),b()}function De(e){let t={};for(let[o,i]of Object.entries(e))i!==void 0&&(t[o]=i);if(t.requestAnswer!==void 0&&!["ask","allow","limited","deny"].includes(t.requestAnswer))throw new Error('requestAnswer must be "ask", "allow", "limited" or "deny".');let n=wn({...r.settings,...t});return r.settings=n,_(),T(),b()}function On(){r.log=[];for(let e of r.seen.values())e.calls=0,e.lastCallAt=null;return T(),b()}function Cn(e,t){if(!e||!t)return null;let n=o=>o==="granted"||o==="limited";return n(e)&&!n(t)?"The phone hasn't allowed this, so calls that need it, like getting a position or a photo, still fail.":null}function b(){if(r.snapshot)return r.snapshot;let e=new Set([...r.seen.keys(),...r.overrides.keys()]),t=o=>{let i=ne.indexOf(o);return i===-1?1e3:i},n=Array.from(e).filter(o=>{let i=R(o).only;return!i||i===r.platform}).sort((o,i)=>t(o)-t(i)||o.localeCompare(i)).map(o=>{let i=r.seen.get(o),l=r.overrides.get(o)??null,c=i?.real??null;return{id:o,label:R(o).label,states:H(o,r.platform),override:l,real:c,effective:l??c,sources:i?Array.from(i.sources).sort():[],calls:i?.calls??0,lastCallAt:i?.lastCallAt??null,lastReadAt:i?.lastReadAt??null,changedAt:i?.changedAt??null,stale:i?.changedAt!=null&&i.lastReadAt!=null&&i.lastReadAt<i.changedAt,once:r.once.has(o),warning:Cn(l,c),canRequestReal:r.realRequesters.has(o)}});return r.snapshot={platform:r.platform,host:r.host,libraries:Array.from(r.libraries).sort(),permissions:n,overriddenCount:r.overrides.size,settings:r.settings,log:r.log.slice(0,vn)},r.snapshot}function M(e){return r.listeners.add(e),()=>r.listeners.delete(e)}import{jsx as v,jsxs as se}from"react/jsx-runtime";var F="permissions-chip",En=8e3,Le={id:F,render:e=>v(Me,{...e})},Nn=()=>cn().some(e=>e.id===F);function Dn(){xe(Le)}var E=null,ae=new Set,W=()=>{};function K(e){E&&clearTimeout(E.timer),E=e;for(let t of Array.from(ae))t();W()}function Ln(e){return ae.add(e),()=>{ae.delete(e)}}var qe=()=>E;function qn(){K({overrides:In(),timer:setTimeout(()=>K(null),En)}),re()}function _n(){let e=E;e&&(K(null),Tn(e.overrides))}var _e=false;function Mn(){if(_e)return;_e=true;let e=false;W=()=>{let t=(kn()||E!==null)&&Pn().showChip;t&&!e?xe(Le):!t&&Nn()&&ln(F),e=t},M(W),W()}function Me({id:e,revealToken:t}){let n=we(M,b,b),o=we(Ln,qe,qe);ot(()=>{o&&n.overriddenCount>0&&K(null)},[o,n.overriddenCount]);let i=n.permissions.filter(m=>m.override!==null),l=i.length===1?i[0]:null,c=l?`${l.label}: ${l.once&&l.override==="granted"?"Allowed Once":k(l.id,n.platform,l.override)}`:`${i.length} permissions simulated`;return o&&i.length===0?v(Se,{id:e,revealToken:t,variant:"strip",dragFromSurface:true,defaultPlacement:"top",accessibilityLabel:"Move or hide the permissions strip",handleAdornment:v(Pe,{size:12}),children:se(g,{style:x.row,children:[v(h,{style:x.title,numberOfLines:1,testID:"permissions-chip-summary",children:"Real permissions"}),v(P,{testID:"permissions-chip-undo",accessibilityRole:"button",accessibilityLabel:"Undo, put the simulated permissions back",onPress:_n,style:x.undo,hitSlop:{top:8,bottom:8,left:8,right:8},children:v(h,{style:x.undoText,children:"Undo"})})]})}):v(Se,{id:e,revealToken:t,variant:"strip",dragFromSurface:true,defaultPlacement:"top",accessibilityLabel:`Move or hide the permissions strip. ${c}`,handleAdornment:v(Pe,{size:12}),children:se(g,{style:x.row,children:[se(P,{testID:"permissions-chip-open",accessibilityRole:"button",accessibilityLabel:`${c}. Open Permissions`,onPress:()=>{dn("permissions")},style:x.open,children:[v(g,{style:x.dot}),v(h,{style:x.title,numberOfLines:1,testID:"permissions-chip-summary",children:c})]}),v(g,{style:x.separator}),v(P,{testID:"permissions-chip-reset",accessibilityRole:"button",accessibilityLabel:"Use real permissions",onPress:qn,style:x.button,hitSlop:{top:8,bottom:8,left:4,right:8},children:v(an,{size:16,color:L.color.textSecondary})})]})})}var x=j.create({row:{flexDirection:"row",alignItems:"center",gap:10,paddingLeft:12,paddingRight:4,minHeight:40,minWidth:200},open:{flexDirection:"row",alignItems:"center",gap:8,flexShrink:1},dot:{width:7,height:7,borderRadius:4,backgroundColor:L.color.accent},title:{color:L.color.text,fontSize:14,fontWeight:"600",flexShrink:1},button:{width:32,height:32,alignItems:"center",justifyContent:"center",borderRadius:16},undo:{paddingHorizontal:12,paddingVertical:6},undoText:{color:L.color.accent,fontSize:14,fontWeight:"600"},separator:{width:j.hairlineWidth,height:20,backgroundColor:L.color.separator}});import{PermissionsIcon as Bn,PERMISSIONS_ICON_COLOR as $n,createToolFactory as zn,defineToolPreset as jn}from"@buoy-gg/shared-ui/web";import{useEffect as Hn,useSyncExternalStore as Vn}from"react";import{reloadApp as Un}from"@buoy-gg/shared-ui/web";var le={ios:{code:"ERR_DENIED_FOREGROUND_LOCATION_PERMISSION",reason:"Location permission is required to do this operation"},android:{code:"ERR_LOCATION_UNAUTHORIZED",reason:"Not authorized to use location services"}},Be={ios:{code:"ERR_DENIED_BACKGROUND_LOCATION_PERMISSION",reason:"Background location permission is required to do this operation"},android:{code:"ERR_LOCATION_BACKGROUND_UNAUTHORIZED",reason:"Not authorized to use background location services"}},Fn=[{module:"ExpoLocation",library:"expo-location",permissions:[{get:"getForegroundPermissionsAsync",request:"requestForegroundPermissionsAsync",permission:"location",flavor:"location"},{get:"getBackgroundPermissionsAsync",request:"requestBackgroundPermissionsAsync",permission:"locationBackground",flavor:"locationBackground"},{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"location",flavor:"location"}],gated:[{method:"getCurrentPositionAsync",permission:"location",...le},{method:"getLastKnownPositionAsync",permission:"location",...le},{method:"watchPositionImplAsync",permission:"location",...le},{method:"startGeofencingAsync",permission:"locationBackground",...Be},{method:"startLocationUpdatesAsync",permission:"locationBackground",...Be}]},{module:"ExpoMaps",library:"expo-maps",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"location",flavor:"plain"}]},{module:"ExpoCamera",library:"expo-camera",permissions:[{get:"getCameraPermissionsAsync",request:"requestCameraPermissionsAsync",permission:"camera",flavor:"plain"},{get:"getMicrophonePermissionsAsync",request:"requestMicrophonePermissionsAsync",permission:"microphone",flavor:"plain"}]},{module:"ExpoNotificationPermissionsModule",library:"expo-notifications",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"notifications",flavor:"notifications",defaultArgs:e=>e==="ios"?[{allowAlert:true,allowBadge:true,allowSound:true}]:[void 0]}]},{module:"ExpoMediaLibrary",library:"expo-media-library",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"photos",flavor:"privileges",defaultArgs:()=>[false]}],gated:["getAssetsAsync","getAlbumsAsync","getAssetInfoAsync","createAssetAsync","saveToLibraryAsync"].map(e=>({method:e,permission:"photos",ios:{code:"ERR_MEDIA_LIBRARY_PERMISSIONS",reason:"Media Library permission is required to do this operation"}}))},{module:"ExponentImagePicker",library:"expo-image-picker",permissions:[{get:"getCameraPermissionsAsync",request:"requestCameraPermissionsAsync",permission:"camera",flavor:"plain"},{get:"getMediaLibraryPermissionsAsync",request:"requestMediaLibraryPermissionsAsync",permission:"photos",flavor:"privileges",defaultArgs:()=>[false]}],gated:[{method:"launchCameraAsync",permission:"camera",ios:{code:"ERR_MISSING_CAMERA_PERMISSION",reason:"Missing camera or camera roll permission"},android:{code:"ERR_USER_REJECTED_PERMISSIONS",reason:"User rejected permissions"}}]},{module:"ExpoContacts",library:"expo-contacts",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"contacts",flavor:"privileges"}]},{module:"ExpoCalendar",library:"expo-calendar",permissions:[{get:"getCalendarPermissionsAsync",request:"requestCalendarPermissionsAsync",permission:"calendar",flavor:"plain"},{get:"getRemindersPermissionsAsync",request:"requestRemindersPermissionsAsync",permission:"reminders",flavor:"plain"}]},{module:"CalendarNext",library:"expo-calendar",permissions:[{get:"getCalendarPermissions",request:"requestCalendarPermissions",permission:"calendar",flavor:"plain"},{get:"getRemindersPermissions",request:"requestRemindersPermissions",permission:"reminders",flavor:"plain"}]},{module:"ExpoTrackingTransparency",library:"expo-tracking-transparency",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"tracking",flavor:"plain"}]},{module:"ExpoAudio",library:"expo-audio",permissions:[{get:"getRecordingPermissionsAsync",request:"requestRecordingPermissionsAsync",permission:"microphone",flavor:"plain"}]},{module:"ExponentPedometer",library:"expo-sensors",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"motion",flavor:"plain"}]}];function Wn(){let e=globalThis.expo?.modules;return e&&typeof e=="object"?e:null}function Kn(e){try{return new Set(Object.keys(e))}catch{return new Set}}function Gn(e,t=[]){return e.flavor!=="privileges"?[]:t.length>0?t.slice(0,1):[false]}async function $e(){let e=Wn();if(!e)return;let t=Kn(e),n=Oe(),o=[];for(let i of Fn){if(!t.has(i.module))continue;let l=e[i.module];if(!l)continue;let c=new Set;for(let m of i.permissions){if(c.has(m.permission))continue;let d=l[m.get],u=d?.__buoyPermissionsOriginal??d;typeof u=="function"&&(c.add(m.permission),o.push(Promise.resolve().then(()=>u.apply(l,Gn(m))).then(S=>Ce(m.permission,fn(S,n),i.library)).catch(()=>{})))}}await Promise.all(o)}import{createSyncAdapter as Yn}from"@buoy-gg/shared-ui/web";import{BUOY_SYNTHETIC_MARK as Jn}from"@buoy-gg/shared-ui/web";var ze=null;function ce(e){try{ze?.emit("appStateDidChange",{app_state:e,[Jn]:true})}catch{}}function Zn(){Oe()==="ios"&&ce("inactive"),ce("background")}function Xn(){ce("active")}var G=null,Qn=false;function eo(){!ze||Qn||(G&&clearTimeout(G),G=setTimeout(()=>{G=null,Zn(),setTimeout(Xn,60)},120))}function Y(e){return e&&typeof e=="object"?e:{}}function de(e){return e.permission??e.id??e.permissionId??e.name}function B(e,t){let n=e[t];if(typeof n=="boolean")return n;if(n==="true")return true;if(n==="false")return false}var je=Yn({version:1,getSnapshot(){return b()},subscribe(e){return M(e)},actions:{async getState(){return await $e(),b()},setOverride(e){let t=Y(e),n=de(t),o=t.state??t.status??t.value;if(n===void 0||o===void 0)throw new Error('setOverride needs `permission` (e.g. "location", "camera", "notifications") and `state` ("undetermined", "granted", "limited", "denied", "blocked" or "restricted").');return Ee(n,o)},clearOverride(e){let t=de(Y(e));if(t===void 0)throw new Error("clearOverride needs `permission`.");return Ne(t)},requestReal(e){let t=de(Y(e));if(t===void 0)throw new Error("requestReal needs `permission`.");return Sn(t)},resetAll(){return re()},updateSettings(e){let t=Y(e);return De({requestAnswer:t.requestAnswer??t.answer,persist:B(t,"persist"),showChip:B(t,"showChip"),notifyApp:B(t,"notifyApp"),enforce:B(t,"enforce"),interceptSettings:B(t,"interceptSettings")})},clearLog(){return On()},simulateReturnFromSettings(){return eo(),b()}}});import{useEffect as to,useReducer as no,useState as He}from"react";import{Check as oo,ChevronLeft as io,ChevronRight as Ve,NightCard as O,NightFootnote as N,NightRows as ue,NightSectionLabel as Ue,night as a,useSafeAreaInsets as ro,useToolScreenHeader as so}from"@buoy-gg/shared-ui/web";import{Fragment as Fe,jsx as s,jsxs as f}from"react/jsx-runtime";var pe=1500,ao=()=>{let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()};function lo(e,t){return e.effective?e.once&&e.effective==="granted"?"Allowed Once":k(e.id,t,e.effective):"Not Checked"}function We({snapshot:e,onAction:t,onReload:n}){let o=ro({minBottom:16}),[i,l]=He(null),[c,m]=He({name:"list"}),d=(y,Z)=>{l(null),t(y,Z).catch(X=>{l(X instanceof Error?X.message:String(X))})},u=c.name==="detail"?e?.permissions.find(y=>y.id===c.id):void 0,S=()=>m(c.name==="detail"&&c.from==="other"?{name:"other"}:{name:"list"}),D=c.name==="other"?"Other Permissions":u?u.label:null,Ze=so(D?{title:D,onBack:S,searchable:false}:null,[D,c.name,c.name==="detail"?c.from:null]);if(!e)return s(g,{style:p.waiting,testID:"permissions-waiting",children:s(N,{centered:true,children:"Waiting for the app\u2026"})});let{platform:J,permissions:me}=e,he=me.filter(y=>y.calls>0||y.override!==null),$=me.filter(y=>!(y.calls>0||y.override!==null)),fe=(y,Z)=>m({name:"detail",id:y,from:Z}),z;return c.name==="detail"&&u?z=s(po,{row:u,platform:J,log:e.log,run:d,onPicked:S}):c.name==="other"?z=f(g,{children:[s(Ke,{rows:$,platform:J,onOpen:y=>fe(y,"other")}),s(N,{children:"Your app can ask for these but hasn't yet."})]}):z=f(Fe,{children:[he.length>0?s(Ke,{rows:he,platform:J,onOpen:y=>fe(y,"list"),onReload:n}):s(O,{padded:true,children:s(h,{style:p.empty,testID:"permissions-empty",children:"Your app hasn't checked any permissions yet. Open a screen that uses location, the camera or notifications and it will show up here."})}),$.length>0?s(O,{children:f(P,{testID:"permissions-other",accessibilityRole:"button",accessibilityLabel:`Other Permissions, ${$.length}`,activeOpacity:.6,onPress:()=>m({name:"other"}),style:p.row,children:[s(h,{style:p.rowTitle,children:"Other Permissions"}),f(g,{style:p.rowRight,children:[s(h,{style:p.rowValue,children:$.length}),s(Ve,{size:16,color:a.color.textTertiary})]})]})}):null,e.overriddenCount>0?s(O,{children:s(P,{testID:"permissions-reset",accessibilityRole:"button",accessibilityLabel:"Use Real Permissions",activeOpacity:.6,onPress:()=>d("resetAll"),style:p.row,children:s(h,{style:p.destructive,children:"Use Real Permissions"})})}):null]}),f(Ae,{style:p.fill,contentContainerStyle:[p.content,{paddingBottom:o.bottom}],testID:"permissions-scroll",children:[!Ze&&c.name!=="list"?f(P,{testID:"permissions-back",accessibilityRole:"button",accessibilityLabel:"Back",onPress:S,style:p.inlineBack,children:[s(io,{size:18,color:a.color.accent}),s(h,{style:p.inlineBackText,children:c.name==="detail"&&c.from==="other"?"Other Permissions":"Permissions"}),D?s(h,{style:p.inlineTitle,children:D}):null]}):null,i?s(N,{tone:"danger",centered:true,children:s(h,{testID:"permissions-error",children:i})}):null,z]})}function Ke({rows:e,platform:t,onOpen:n,onReload:o}){let[,i]=no(d=>d+1,0),l=ao(),c=e.filter(d=>d.stale&&d.changedAt!==null&&l-d.changedAt<pe).map(d=>pe-(l-d.changedAt)),m=c.length>0?Math.min(...c):null;return to(()=>{if(m===null)return;let d=setTimeout(i,m+50);return()=>clearTimeout(d)},[m]),s(O,{children:s(ue,{children:e.map(d=>{let u=d.stale&&d.changedAt!==null&&l-d.changedAt>=pe;return f(g,{children:[s(co,{row:d,platform:t,onPress:()=>n(d.id)}),u?f(g,{style:p.stale,testID:`permissions-stale-${d.id}`,children:[s(h,{style:p.staleText,children:"The app hasn't checked again since this changed."}),o?s(P,{testID:`permissions-reload-${d.id}`,accessibilityRole:"button",accessibilityLabel:"Reload App",onPress:o,hitSlop:{top:8,bottom:8,left:8,right:8},children:s(h,{style:p.staleAction,children:"Reload App"})}):null]}):null]},d.id)})})})}function co({row:e,platform:t,onPress:n}){let o=e.override!==null,i=lo(e,t),l=e.real?k(e.id,t,e.real):"Not Checked";return f(P,{testID:`permissions-row-${e.id}`,accessibilityRole:"button",accessibilityLabel:`${e.label}: ${i}${o?`, simulated. Phone: ${l}`:""}`,activeOpacity:.6,onPress:n,style:p.row,children:[f(g,{style:p.rowLeft,children:[s(h,{style:p.rowTitle,children:e.label}),o?f(h,{style:p.rowSub,testID:`permissions-phone-${e.id}`,children:["Phone: ",l]}):null]}),f(g,{style:p.rowRight,children:[o?s(g,{style:p.dot}):null,s(h,{style:[p.rowValue,o?p.rowValueSimulated:null],testID:`permissions-value-${e.id}`,numberOfLines:1,children:i}),s(Ve,{size:16,color:a.color.textTertiary})]})]})}function Ge({title:e,detail:t,selected:n,testID:o,onPress:i}){return f(P,{testID:o,accessibilityRole:"button",accessibilityLabel:`${e}. ${t}`,accessibilityState:{selected:n},activeOpacity:.6,onPress:i,style:p.option,children:[f(g,{style:p.optionText,children:[s(h,{style:p.rowTitle,children:e}),s(h,{style:p.optionDetail,children:t})]}),s(g,{style:p.check,children:n?s(oo,{size:18,color:a.color.accent}):null})]})}var uo={check:"Checked",request:"Asked",settings:"Opened Settings",gated:"Needed it"};function po({row:e,platform:t,log:n,run:o,onPicked:i}){let l=e.real?k(e.id,t,e.real):null,c=u=>{u===null?o("clearOverride",{permission:e.id}):o("setOverride",{permission:e.id,state:u}),i()},m=n.filter(u=>u.permission===e.id).slice(0,8),d=e.canRequestReal&&e.real==="undetermined";return f(Fe,{children:[f(g,{children:[s(Ue,{children:"What the app sees"}),s(O,{children:f(ue,{children:[s(Ge,{title:"Phone's Setting",detail:l?`Use what the phone says: ${l}.`:"Use what the phone says.",selected:e.override===null,testID:`permissions-state-${e.id}-real`,onPress:()=>c(null)},"real"),e.states.map(u=>s(Ge,{title:k(e.id,t,u),detail:hn(e.id,t,u),selected:e.override===u,testID:`permissions-state-${e.id}-${u}`,onPress:()=>c(u)},u))]})})]}),d?f(g,{children:[s(O,{children:s(P,{testID:`permissions-request-real-${e.id}`,accessibilityRole:"button",accessibilityLabel:`Show the real system prompt for ${e.label}`,activeOpacity:.6,onPress:()=>o("requestReal",{permission:e.id}),style:p.row,children:s(h,{style:p.action,children:"Show Real Prompt"})})}),s(N,{children:e.warning??"Asks the phone for real, so calls that need this permission work."})]}):e.warning?s(N,{tone:"warning",children:s(h,{testID:`permissions-warning-${e.id}`,children:e.warning})}):null,m.length>0?f(g,{children:[s(Ue,{children:"Recent"}),s(O,{children:s(ue,{children:m.map(u=>s(ho,{entry:u,platform:t},u.id))})}),e.sources.length>0?f(N,{children:["Read through ",e.sources.join(", ")]}):null]}):null]})}function mo(e){let t=new Date(e),n=o=>String(o).padStart(2,"0");return`${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`}function ho({entry:e,platform:t}){let n=e.error?"Failed":e.returned&&e.permission?e.answer==="once"&&e.returned==="granted"?"Allowed Once":k(e.permission,t,e.returned):"";return f(g,{style:p.recentRow,testID:`permissions-log-${e.id}`,children:[s(h,{style:p.recentTime,children:mo(e.at)}),s(h,{style:p.recentVerb,numberOfLines:1,children:uo[e.kind]}),s(h,{style:[p.recentResult,e.error?p.recentFailed:null],numberOfLines:1,children:n})]})}var p=j.create({fill:{flex:1},content:{paddingHorizontal:a.gutter,paddingTop:12,gap:a.groupGap},waiting:{flex:1,alignItems:"center",justifyContent:"center",padding:24},empty:{color:a.color.textSecondary,fontSize:a.font.body,lineHeight:20},row:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:50,paddingHorizontal:a.rowPadH,paddingVertical:10},rowLeft:{flexShrink:1,gap:2},rowTitle:{color:a.color.text,fontSize:a.font.row},rowSub:{color:a.color.textTertiary,fontSize:a.font.caption},rowRight:{flexDirection:"row",alignItems:"center",gap:6,flexShrink:1},rowValue:{color:a.color.textSecondary,fontSize:a.font.row},rowValueSimulated:{color:a.color.accent},dot:{width:7,height:7,borderRadius:4,backgroundColor:a.color.accent},stale:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",columnGap:10,rowGap:4,paddingHorizontal:a.rowPadH,paddingBottom:12,marginTop:-4},staleText:{color:a.color.textSecondary,fontSize:a.font.caption,flexShrink:1},staleAction:{color:a.color.accent,fontSize:a.font.caption,fontWeight:"600"},destructive:{color:a.color.danger,fontSize:a.font.row},action:{color:a.color.accent,fontSize:a.font.row},option:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:a.rowPadH,paddingVertical:11,minHeight:50},optionText:{flex:1,gap:2},optionDetail:{color:a.color.textTertiary,fontSize:a.font.caption,lineHeight:17},check:{width:20,alignItems:"center"},inlineBack:{flexDirection:"row",alignItems:"center",gap:4,marginBottom:-8},inlineBackText:{color:a.color.accent,fontSize:a.font.row},inlineTitle:{color:a.color.text,fontSize:a.font.row,fontWeight:"600",marginLeft:"auto"},recentRow:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:a.rowPadH,paddingVertical:10},recentTime:{color:a.color.textTertiary,fontSize:a.font.caption,fontVariant:["tabular-nums"]},recentVerb:{color:a.color.text,fontSize:a.font.body,flex:1},recentResult:{color:a.color.textSecondary,fontSize:a.font.body},recentFailed:{color:a.color.danger}});import{jsx as fo}from"react/jsx-runtime";var go=je.actions;async function yo(e,t){let n=go[e];if(!n)throw new Error(`Unknown permissions action: ${e}`);return n(t)}function bo(){Un("auto","buoy permissions").catch(()=>{})}function Ye(){Hn(()=>{Q(),$e()},[]);let e=Vn(M,b,b);return fo(We,{snapshot:e,onAction:yo,onReload:bo})}import{jsx as wo}from"react/jsx-runtime";var Je=jn({id:"permissions",name:"PERMISSIONS",description:"Test denied, blocked, limited and not-asked permission states",slot:"both",color:$n,icon:({size:e,color:t})=>wo(Bn,{size:e,color:t}),component:Ye,modal:{subtitle:"choose what the app is allowed to do"}}),vo=zn(Je);import{PermissionsIcon as Ao,PERMISSIONS_ICON_COLOR as So}from"@buoy-gg/shared-ui/web";var Po=typeof navigator<"u"&&navigator.product==="ReactNative";Po&&typeof be<"u"&&be&&(Q(),Mn());export{ne as KNOWN_PERMISSION_IDS,F as PERMISSIONS_CHIP_ID,So as PERMISSIONS_ICON_COLOR,ee as PERMISSION_STATES,Ye as PermissionsBody,Me as PermissionsChip,Ao as PermissionsIcon,We as PermissionsToolView,Ne as clearPermissionOverride,vo as createPermissionsTool,xn as getPermissionOverride,b as getPermissionsSnapshot,Q as installPermissions,Rn as isPermissionOverridden,Dn as openPermissionsChip,R as permissionInfo,je as permissionsSyncAdapter,Je as permissionsToolPreset,re as resetPermissions,Ee as setPermissionOverride,k as stateLabel,M as subscribePermissions,H as supportedStates,De as updatePermissionSettings};
1
+ "use client";var ye=Object.defineProperty;var tt=Object.getOwnPropertyDescriptor;var nt=Object.getOwnPropertyNames;var ot=Object.prototype.hasOwnProperty;var it=(e,t)=>{for(var n in t)ye(e,n,{get:t[n],enumerable:true})},be=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of nt(t))!ot.call(e,i)&&i!==n&&ye(e,i,{get:()=>t[i],enumerable:!(o=tt(t,i))||o.enumerable});return e},rt=(e,t,n)=>(be(e,t,"default"),n&&be(n,t,"default"));var we=process.env.NODE_ENV!=="production";typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);function ee(){return false}import{useEffect as st,useSyncExternalStore as ve}from"react";var Ae={};it(Ae,{AccessibilityInfo:()=>dt,ActivityIndicator:()=>sn,Alert:()=>cn,Animated:()=>ut,AppRegistry:()=>mt,AppState:()=>ht,Appearance:()=>pt,BackHandler:()=>ft,Button:()=>an,CheckBox:()=>Et,Clipboard:()=>gt,DeviceEventEmitter:()=>Kt,Dimensions:()=>yt,Easing:()=>bt,FlatList:()=>Nt,I18nManager:()=>wt,Image:()=>Dt,ImageBackground:()=>Lt,InteractionManager:()=>At,Keyboard:()=>vt,KeyboardAvoidingView:()=>qt,LayoutAnimation:()=>St,Linking:()=>Pt,LogBox:()=>Wt,Modal:()=>on,NativeEventEmitter:()=>xt,NativeModules:()=>ct,PanResponder:()=>Rt,Picker:()=>_t,PixelRatio:()=>kt,Platform:()=>It,Pressable:()=>nn,ProgressBar:()=>Mt,RefreshControl:()=>Bt,SafeAreaView:()=>$t,ScrollView:()=>Se,SectionList:()=>zt,Share:()=>Tt,StatusBar:()=>jt,StyleSheet:()=>j,Switch:()=>rn,Text:()=>h,TextInput:()=>Xt,Touchable:()=>Ht,TouchableHighlight:()=>en,TouchableNativeFeedback:()=>Vt,TouchableOpacity:()=>P,TouchableWithoutFeedback:()=>tn,UIManager:()=>Ot,Vibration:()=>Ct,View:()=>g,VirtualizedList:()=>Ut,YellowBox:()=>Ft,findNodeHandle:()=>ln,unstable_createElement:()=>lt,useColorScheme:()=>Gt,useLocaleContext:()=>Yt,useWindowDimensions:()=>Jt});rt(Ae,at);import*as at from"react-native-web";import{unstable_createElement as lt,NativeModules as ct,AccessibilityInfo as dt,Animated as ut,Appearance as pt,AppRegistry as mt,AppState as ht,BackHandler as ft,Clipboard as gt,Dimensions as yt,Easing as bt,I18nManager as wt,Keyboard as vt,InteractionManager as At,LayoutAnimation as St,Linking as Pt,NativeEventEmitter as xt,PanResponder as Rt,PixelRatio as kt,Platform as It,Share as Tt,StyleSheet as j,UIManager as Ot,Vibration as Ct,CheckBox as Et,FlatList as Nt,Image as Dt,ImageBackground as Lt,KeyboardAvoidingView as qt,Picker as _t,ProgressBar as Mt,RefreshControl as Bt,SafeAreaView as $t,SectionList as zt,StatusBar as jt,Touchable as Ht,TouchableNativeFeedback as Vt,VirtualizedList as Ut,YellowBox as Ft,LogBox as Wt,DeviceEventEmitter as Kt,useColorScheme as Gt,useLocaleContext as Yt,useWindowDimensions as Jt}from"react-native-web";import*as w from"react-native-web";import{createElement as Zt,forwardRef as Qt}from"react";function A(e){let t=Qt((o,i)=>{let{accessibilityState:l,accessibilityValue:c,...m}=o;for(let d of["busy","checked","disabled","expanded","selected"])l?.[d]!==void 0&&m[`aria-${d}`]===void 0&&(m[`aria-${d}`]=l[d]);for(let[d,u]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))c?.[d]!==void 0&&m[`aria-${u}`]===void 0&&(m[`aria-${u}`]=c[d]);return Zt(e,{...m,ref:i})}),n=e.State;return n&&Object.assign(t,{State:n}),t.displayName=e.displayName??e.name??"NativeWebView",t}var g=A(w.View),h=A(w.Text),Xt=A(w.TextInput),P=A(w.TouchableOpacity),en=A(w.TouchableHighlight),tn=A(w.TouchableWithoutFeedback),nn=A(w.Pressable),Se=A(w.ScrollView),on=A(w.Modal),rn=A(w.Switch),sn=A(w.ActivityIndicator),an=A(w.Button),ln=w.findNodeHandle,cn={alert(e,t,n,o){if(typeof document>"u")return;let i=document.createElement("dialog");i.dataset.buoyRoot="",i.setAttribute("aria-label",e),i.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let l=document.createElement("h2");if(l.textContent=e,l.style.cssText="font-size:18px;margin:0 0 12px",i.appendChild(l),t){let u=document.createElement("p");u.textContent=t,u.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",i.appendChild(u)}let c=document.createElement("div");c.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let m=n?.length?n:[{text:"OK"}],d=()=>{i.close?.(),i.remove()};for(let u of m){let S=document.createElement("button");S.type="button",S.textContent=u.text??"OK",S.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${u.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,S.onclick=()=>{d(),u.onPress?.()},c.appendChild(S)}i.addEventListener("cancel",u=>{u.preventDefault(),o?.cancelable!==false&&(d(),o?.onDismiss?.())}),i.appendChild(c),document.body.appendChild(i),i.showModal?i.showModal():i.setAttribute("open","")}};import{FloatingTool as Pe,PermissionsIcon as xe,X as dn,dismissFloatingTool as un,getFloatingTools as pn,night as L,openBuoyTool as mn,openFloatingTool as Re}from"@buoy-gg/shared-ui/web";var te=["undetermined","granted","limited","denied","blocked","restricted"],hn=["ask","allow","limited","deny"],ne={location:{id:"location",label:"Location",limited:{ios:"Approximate",android:"Approximate"},purpose:"use your location"},locationBackground:{id:"locationBackground",label:"Background Location",purpose:"use your location in the background"},camera:{id:"camera",label:"Camera",purpose:"access your camera"},microphone:{id:"microphone",label:"Microphone",purpose:"access your microphone"},notifications:{id:"notifications",label:"Notifications",limited:{ios:"Provisional"},purpose:"send you notifications"},photos:{id:"photos",label:"Photos",limited:{ios:"Selected Photos",android:"Selected Photos"},purpose:"access your photos"},contacts:{id:"contacts",label:"Contacts",limited:{ios:"Selected Contacts"},purpose:"access your contacts"},calendar:{id:"calendar",label:"Calendar",purpose:"access your calendar"},reminders:{id:"reminders",label:"Reminders",only:"ios",purpose:"access your reminders"},tracking:{id:"tracking",label:"Tracking",only:"ios",purpose:"track your activity across other companies' apps and websites"},motion:{id:"motion",label:"Motion & Fitness",purpose:"access your motion and fitness activity"},bluetooth:{id:"bluetooth",label:"Bluetooth",purpose:"use Bluetooth"}},oe=Object.keys(ne);function ke(e){return typeof e=="string"&&(e in ne||e.startsWith("android:")&&e.length>8)}function R(e){let t=ne[e];if(t)return t;let n=e.slice(8).replace(/^android\.permission\./,"");return{id:e,label:n.toLowerCase().split("_").map(o=>o.charAt(0).toUpperCase()+o.slice(1)).join(" "),only:"android",purpose:`use ${n.toLowerCase().replace(/_/g," ")}`}}function H(e,t){let n=R(e),o=["undetermined","granted"];return n.limited?.[t]&&o.push("limited"),o.push("denied"),t==="android"&&o.push("blocked"),t==="ios"&&e!=="notifications"&&o.push("restricted"),o}function fn(e,t,n){return H(e,t).includes(n)}function gn(e,t,n){return fn(e,t,n)?n:n==="blocked"?"denied":n==="restricted"?t==="android"?"blocked":"denied":n==="limited"?"granted":n}function yn(e,t,n){switch(n){case"undetermined":return"Never asked. The next request shows a prompt.";case"granted":return"Full access.";case"limited":return e==="location"?"Allowed, with an approximate position.":e==="photos"?"Allowed for the photos the person picked.":e==="contacts"?"Allowed for the contacts the person picked.":e==="notifications"?"Delivered quietly to Notification Center, without asking.":"Partial access.";case"denied":return t==="ios"?"The person said no. The app can't ask again, only send them to Settings.":"The person said no once. The app can ask one more time.";case"blocked":return"The person said no for good. Only Settings can change it.";case"restricted":return"Turned off by Screen Time or device management. The person can't change it."}}function bn(e,t){if(!e||typeof e!="object")return null;let n=e,o=typeof n.ios?.status=="number"?n.ios.status:void 0;return o===3||o===4?"limited":n.status==="granted"?n.accessPrivileges==="limited"||n.ios?.accuracy==="reduced"||n.android?.accuracy==="coarse"?"limited":"granted":n.status==="denied"?t==="android"&&n.canAskAgain===false?"blocked":"denied":n.status==="undetermined"?"undetermined":null}function k(e,t,n){switch(n){case"undetermined":return"Not Asked";case"granted":return"Allowed";case"limited":return R(e).limited?.[t]??"Limited";case"denied":return"Denied";case"blocked":return"Blocked";case"restricted":return"Restricted"}}import{devToolsStorageKeys as wn,persistentStorage as vn}from"@buoy-gg/shared-ui/web";var I={requestAnswer:"ask",persist:true,showChip:true,notifyApp:true,enforce:true,interceptSettings:true},An=wn.permissions.state();function q(e,t){return typeof e=="boolean"?e:t}function Sn(e){let t=e&&typeof e=="object"?e:{};return{requestAnswer:hn.includes(t.requestAnswer)?t.requestAnswer:I.requestAnswer,persist:q(t.persist,I.persist),showChip:q(t.showChip,I.showChip),notifyApp:q(t.notifyApp,I.notifyApp),enforce:q(t.enforce,I.enforce),interceptSettings:q(t.interceptSettings,I.interceptSettings)}}var ie=Promise.resolve();function Ie(e){let t=JSON.stringify(e);return ie=ie.then(()=>vn.setItem(An,t)).catch(()=>{}),ie.then(()=>{})}var Pn=50,Te="__buoyPermissionsStore",Oe=globalThis,r=Oe[Te]??(Oe[Te]={platform:"ios",booted:false,overrides:new Map,settings:{...I},seen:new Map,libraries:new Set,log:[],nextLogId:1,listeners:new Set,snapshot:null,prompter:null,changeHooks:new Set,realRequesters:new Map,host:{isSimulator:null,deviceName:null,bundleId:null},once:new Set});r.once??(r.once=new Set);var V=()=>{let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()};function T(){r.snapshot=null;for(let e of Array.from(r.listeners))try{e()}catch{}}function _(){if(!r.settings.persist){Ie({v:1,overrides:{},settings:r.settings});return}Ie(xn())}function xn(){return{v:1,overrides:Object.fromEntries(Array.from(r.overrides,([e,t])=>[e,r.once.has(e)?"undetermined":t])),settings:r.settings}}function C(e){let t=r.seen.get(e);return t||(t={sources:new Set,real:null,calls:0,lastCallAt:null,lastReadAt:null,changedAt:null},r.seen.set(e,t)),t}async function Rn(e){let t=re(e),n=r.realRequesters.get(t);if(!n)throw new Error(`No installed library can ask the system for ${R(t).label}.`);let o=await n();return o!==null&&Ee(t,o),y()}function U(e,t){for(let n of Array.from(r.changeHooks))try{n({id:e,from:t})}catch{}}function Ce(){return r.platform}function kn(){return r.settings}function In(e){return r.overrides.get(e)??null}function Tn(e){return r.overrides.has(e)}function On(){return r.overrides.size>0}function Ee(e,t,n){if(t===null)return;let o=C(e);n&&o.sources.add(n),o.real!==t&&(o.real=t,T())}function re(e){if(!ke(e))throw new Error(`Unknown permission "${String(e)}". Use one of: ${oe.join(", ")}, or android:<android.permission.NAME>.`);return e}function Ne(e,t){let n=re(e);if(!te.includes(t))throw new Error(`Unknown state "${String(t)}". Use one of: ${te.join(", ")}.`);let o=t,i=H(n,r.platform),l=r.platform==="ios"&&o==="blocked"?"denied":o;if(!i.includes(l))throw new Error(`${R(n).label} can't be "${o}" on ${r.platform}. It can be: ${i.join(", ")}.`);return(r.overrides.get(n)!==l||r.once.has(n))&&(r.overrides.set(n,l),r.once.delete(n),C(n).changedAt=V(),_(),T(),U(n,"tool")),y()}function De(e){let t=re(e);return r.overrides.delete(t)&&(r.once.delete(t),C(t).changedAt=V(),_(),T(),U(t,"tool")),y()}function se(){if(r.overrides.size>0){let e=V();for(let t of r.overrides.keys())C(t).changedAt=e;r.overrides.clear(),r.once.clear(),_(),T(),U(null,"tool")}return y()}function Cn(){return Object.fromEntries(r.overrides)}function En(e){let t=V();for(let n of r.overrides.keys())C(n).changedAt=t;r.overrides.clear(),r.once.clear();for(let[n,o]of Object.entries(e)){let i=n;!o||!ke(i)||(r.overrides.set(i,gn(i,r.platform,o)),C(i).changedAt=t)}return _(),T(),U(null,"tool"),y()}function Le(e){let t={};for(let[o,i]of Object.entries(e))i!==void 0&&(t[o]=i);if(t.requestAnswer!==void 0&&!["ask","allow","limited","deny"].includes(t.requestAnswer))throw new Error('requestAnswer must be "ask", "allow", "limited" or "deny".');let n=Sn({...r.settings,...t});return r.settings=n,_(),T(),y()}function Nn(){r.log=[];for(let e of r.seen.values())e.calls=0,e.lastCallAt=null;return T(),y()}function Dn(e,t){if(!e||!t)return null;let n=o=>o==="granted"||o==="limited";return n(e)&&!n(t)?"The phone hasn't allowed this, so calls that need it, like getting a position or a photo, still fail.":null}function y(){if(r.snapshot)return r.snapshot;let e=new Set([...r.seen.keys(),...r.overrides.keys()]),t=o=>{let i=oe.indexOf(o);return i===-1?1e3:i},n=Array.from(e).filter(o=>{let i=R(o).only;return!i||i===r.platform}).sort((o,i)=>t(o)-t(i)||o.localeCompare(i)).map(o=>{let i=r.seen.get(o),l=r.overrides.get(o)??null,c=i?.real??null;return{id:o,label:R(o).label,states:H(o,r.platform),override:l,real:c,effective:l??c,sources:i?Array.from(i.sources).sort():[],calls:i?.calls??0,lastCallAt:i?.lastCallAt??null,lastReadAt:i?.lastReadAt??null,changedAt:i?.changedAt??null,stale:i?.changedAt!=null&&i.lastReadAt!=null&&i.lastReadAt<i.changedAt,once:r.once.has(o),warning:Dn(l,c),canRequestReal:r.realRequesters.has(o)}});return r.snapshot={platform:r.platform,host:r.host,libraries:Array.from(r.libraries).sort(),permissions:n,overriddenCount:r.overrides.size,settings:r.settings,log:r.log.slice(0,Pn)},r.snapshot}function M(e){return r.listeners.add(e),()=>r.listeners.delete(e)}import{jsx as v,jsxs as ae}from"react/jsx-runtime";var F="permissions-chip",Ln=8e3,qe={id:F,render:e=>v(Be,{...e})},qn=()=>pn().some(e=>e.id===F);function _n(){Re(qe)}var E=null,le=new Set,W=()=>{};function K(e){E&&clearTimeout(E.timer),E=e;for(let t of Array.from(le))t();W()}function Mn(e){return le.add(e),()=>{le.delete(e)}}var _e=()=>E;function Bn(){K({overrides:Cn(),timer:setTimeout(()=>K(null),Ln)}),se()}function $n(){let e=E;e&&(K(null),En(e.overrides))}var Me=false;function zn(){if(Me)return;Me=true;let e=false;W=()=>{let t=(On()||E!==null)&&kn().showChip;t&&!e?Re(qe):!t&&qn()&&un(F),e=t},M(W),W()}function Be({id:e,revealToken:t}){let n=ve(M,y,y),o=ve(Mn,_e,_e);st(()=>{o&&n.overriddenCount>0&&K(null)},[o,n.overriddenCount]);let i=n.permissions.filter(m=>m.override!==null),l=i.length===1?i[0]:null,c=l?`${l.label}: ${l.once&&l.override==="granted"?"Allowed Once":k(l.id,n.platform,l.override)}`:`${i.length} permissions simulated`;return o&&i.length===0?v(Pe,{id:e,revealToken:t,variant:"strip",dragFromSurface:true,defaultPlacement:"top",accessibilityLabel:"Move or hide the permissions strip",handleAdornment:v(xe,{size:12}),children:ae(g,{style:x.row,children:[v(h,{style:x.title,numberOfLines:1,testID:"permissions-chip-summary",children:"Real permissions"}),v(P,{testID:"permissions-chip-undo",accessibilityRole:"button",accessibilityLabel:"Undo, put the simulated permissions back",onPress:$n,style:x.undo,hitSlop:{top:8,bottom:8,left:8,right:8},children:v(h,{style:x.undoText,children:"Undo"})})]})}):v(Pe,{id:e,revealToken:t,variant:"strip",dragFromSurface:true,defaultPlacement:"top",accessibilityLabel:`Move or hide the permissions strip. ${c}`,handleAdornment:v(xe,{size:12}),children:ae(g,{style:x.row,children:[ae(P,{testID:"permissions-chip-open",accessibilityRole:"button",accessibilityLabel:`${c}. Open Permissions`,onPress:()=>{mn("permissions")},style:x.open,children:[v(g,{style:x.dot}),v(h,{style:x.title,numberOfLines:1,testID:"permissions-chip-summary",children:c})]}),v(g,{style:x.separator}),v(P,{testID:"permissions-chip-reset",accessibilityRole:"button",accessibilityLabel:"Use real permissions",onPress:Bn,style:x.button,hitSlop:{top:8,bottom:8,left:4,right:8},children:v(dn,{size:16,color:L.color.textSecondary})})]})})}var x=j.create({row:{flexDirection:"row",alignItems:"center",gap:10,paddingLeft:12,paddingRight:4,minHeight:40,minWidth:200},open:{flexDirection:"row",alignItems:"center",gap:8,flexShrink:1},dot:{width:7,height:7,borderRadius:4,backgroundColor:L.color.accent},title:{color:L.color.text,fontSize:14,fontWeight:"600",flexShrink:1},button:{width:32,height:32,alignItems:"center",justifyContent:"center",borderRadius:16},undo:{paddingHorizontal:12,paddingVertical:6},undoText:{color:L.color.accent,fontSize:14,fontWeight:"600"},separator:{width:j.hairlineWidth,height:20,backgroundColor:L.color.separator}});import{PermissionsIcon as jn,PERMISSIONS_ICON_COLOR as Hn,createToolFactory as Vn,defineToolPreset as Un}from"@buoy-gg/shared-ui/web";import{useEffect as Fn,useSyncExternalStore as Wn}from"react";import{reloadApp as Kn}from"@buoy-gg/shared-ui/web";var ce={ios:{code:"ERR_DENIED_FOREGROUND_LOCATION_PERMISSION",reason:"Location permission is required to do this operation"},android:{code:"ERR_LOCATION_UNAUTHORIZED",reason:"Not authorized to use location services"}},$e={ios:{code:"ERR_DENIED_BACKGROUND_LOCATION_PERMISSION",reason:"Background location permission is required to do this operation"},android:{code:"ERR_LOCATION_BACKGROUND_UNAUTHORIZED",reason:"Not authorized to use background location services"}},Gn=[{module:"ExpoLocation",library:"expo-location",permissions:[{get:"getForegroundPermissionsAsync",request:"requestForegroundPermissionsAsync",permission:"location",flavor:"location"},{get:"getBackgroundPermissionsAsync",request:"requestBackgroundPermissionsAsync",permission:"locationBackground",flavor:"locationBackground"},{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"location",flavor:"location"}],gated:[{method:"getCurrentPositionAsync",permission:"location",...ce},{method:"getLastKnownPositionAsync",permission:"location",...ce},{method:"watchPositionImplAsync",permission:"location",...ce},{method:"startGeofencingAsync",permission:"locationBackground",...$e},{method:"startLocationUpdatesAsync",permission:"locationBackground",...$e}]},{module:"ExpoMaps",library:"expo-maps",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"location",flavor:"plain"}]},{module:"ExpoCamera",library:"expo-camera",permissions:[{get:"getCameraPermissionsAsync",request:"requestCameraPermissionsAsync",permission:"camera",flavor:"plain"},{get:"getMicrophonePermissionsAsync",request:"requestMicrophonePermissionsAsync",permission:"microphone",flavor:"plain"}]},{module:"ExpoNotificationPermissionsModule",library:"expo-notifications",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"notifications",flavor:"notifications",defaultArgs:e=>e==="ios"?[{allowAlert:true,allowBadge:true,allowSound:true}]:[void 0]}]},{module:"ExpoMediaLibrary",library:"expo-media-library",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"photos",flavor:"privileges",defaultArgs:()=>[false]}],gated:["getAssetsAsync","getAlbumsAsync","getAssetInfoAsync","createAssetAsync","saveToLibraryAsync"].map(e=>({method:e,permission:"photos",ios:{code:"ERR_MEDIA_LIBRARY_PERMISSIONS",reason:"Media Library permission is required to do this operation"}}))},{module:"ExponentImagePicker",library:"expo-image-picker",permissions:[{get:"getCameraPermissionsAsync",request:"requestCameraPermissionsAsync",permission:"camera",flavor:"plain"},{get:"getMediaLibraryPermissionsAsync",request:"requestMediaLibraryPermissionsAsync",permission:"photos",flavor:"privileges",defaultArgs:()=>[false]}],gated:[{method:"launchCameraAsync",permission:"camera",ios:{code:"ERR_MISSING_CAMERA_PERMISSION",reason:"Missing camera or camera roll permission"},android:{code:"ERR_USER_REJECTED_PERMISSIONS",reason:"User rejected permissions"}}]},{module:"ExpoContacts",library:"expo-contacts",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"contacts",flavor:"privileges"}]},{module:"ExpoCalendar",library:"expo-calendar",permissions:[{get:"getCalendarPermissionsAsync",request:"requestCalendarPermissionsAsync",permission:"calendar",flavor:"plain"},{get:"getRemindersPermissionsAsync",request:"requestRemindersPermissionsAsync",permission:"reminders",flavor:"plain"}]},{module:"CalendarNext",library:"expo-calendar",permissions:[{get:"getCalendarPermissions",request:"requestCalendarPermissions",permission:"calendar",flavor:"plain"},{get:"getRemindersPermissions",request:"requestRemindersPermissions",permission:"reminders",flavor:"plain"}]},{module:"ExpoTrackingTransparency",library:"expo-tracking-transparency",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"tracking",flavor:"plain"}]},{module:"ExpoAudio",library:"expo-audio",permissions:[{get:"getRecordingPermissionsAsync",request:"requestRecordingPermissionsAsync",permission:"microphone",flavor:"plain"}]},{module:"ExponentPedometer",library:"expo-sensors",permissions:[{get:"getPermissionsAsync",request:"requestPermissionsAsync",permission:"motion",flavor:"plain"}]}];function Yn(){let e=globalThis.expo?.modules;return e&&typeof e=="object"?e:null}function Jn(e){try{return new Set(Object.keys(e))}catch{return new Set}}function Zn(e,t=[]){return e.flavor!=="privileges"?[]:t.length>0?t.slice(0,1):[false]}async function ze(){let e=Yn();if(!e)return;let t=Jn(e),n=Ce(),o=[];for(let i of Gn){if(!t.has(i.module))continue;let l=e[i.module];if(!l)continue;let c=new Set;for(let m of i.permissions){if(c.has(m.permission))continue;let d=l[m.get],u=d?.__buoyPermissionsOriginal??d;typeof u=="function"&&(c.add(m.permission),o.push(Promise.resolve().then(()=>u.apply(l,Zn(m))).then(S=>Ee(m.permission,bn(S,n),i.library)).catch(()=>{})))}}await Promise.all(o)}import{createSyncAdapter as Qn}from"@buoy-gg/shared-ui/web";import{BUOY_SYNTHETIC_MARK as Xn}from"@buoy-gg/shared-ui/web";var je=null;function de(e){try{je?.emit("appStateDidChange",{app_state:e,[Xn]:true})}catch{}}function eo(){Ce()==="ios"&&de("inactive"),de("background")}function to(){de("active")}var G=null,He=false,Ve=null;function no(){return He}function Y(){return Ve?(Ve(),true):false}function oo(){!je||He||(G&&clearTimeout(G),G=setTimeout(()=>{G=null,eo(),setTimeout(to,60)},120))}function J(e){return e&&typeof e=="object"?e:{}}function ue(e){return e.permission??e.id??e.permissionId??e.name}function B(e,t){let n=e[t];if(typeof n=="boolean")return n;if(n==="true")return true;if(n==="false")return false}var Ue=Qn({version:1,getSnapshot(){return y()},subscribe(e){return M(e)},actions:{async getState(){return await ze(),no()?{...y(),settingsStandInOpen:true}:y()},setOverride(e){let t=J(e),n=ue(t),o=t.state??t.status??t.value;if(n===void 0||o===void 0)throw new Error('setOverride needs `permission` (e.g. "location", "camera", "notifications") and `state` ("undetermined", "granted", "limited", "denied", "blocked" or "restricted").');return Y(),Ne(n,o)},clearOverride(e){let t=ue(J(e));if(t===void 0)throw new Error("clearOverride needs `permission`.");return Y(),De(t)},requestReal(e){let t=ue(J(e));if(t===void 0)throw new Error("requestReal needs `permission`.");return Rn(t)},resetAll(){return Y(),se()},updateSettings(e){let t=J(e);return Le({requestAnswer:t.requestAnswer??t.answer,persist:B(t,"persist"),showChip:B(t,"showChip"),notifyApp:B(t,"notifyApp"),enforce:B(t,"enforce"),interceptSettings:B(t,"interceptSettings")})},clearLog(){return Nn()},simulateReturnFromSettings(){return Y()||oo(),y()}}});import{useEffect as io,useReducer as ro,useState as Fe}from"react";import{Check as so,ChevronLeft as ao,ChevronRight as We,NightCard as O,NightFootnote as N,NightRows as pe,NightSectionLabel as Ke,night as a,useSafeAreaInsets as lo,useToolScreenHeader as co}from"@buoy-gg/shared-ui/web";import{Fragment as Ge,jsx as s,jsxs as f}from"react/jsx-runtime";var me=1500,uo=()=>{let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()};function po(e,t){return e.effective?e.once&&e.effective==="granted"?"Allowed Once":k(e.id,t,e.effective):"Not Checked"}function Ye({snapshot:e,onAction:t,onReload:n}){let o=lo({minBottom:16}),[i,l]=Fe(null),[c,m]=Fe({name:"list"}),d=(b,Q)=>{l(null),t(b,Q).catch(X=>{l(X instanceof Error?X.message:String(X))})},u=c.name==="detail"?e?.permissions.find(b=>b.id===c.id):void 0,S=()=>m(c.name==="detail"&&c.from==="other"?{name:"other"}:{name:"list"}),D=c.name==="other"?"Other Permissions":u?u.label:null,et=co(D?{title:D,onBack:S,searchable:false}:null,[D,c.name,c.name==="detail"?c.from:null]);if(!e)return s(g,{style:p.waiting,testID:"permissions-waiting",children:s(N,{centered:true,children:"Waiting for the app\u2026"})});let{platform:Z,permissions:he}=e,fe=he.filter(b=>b.calls>0||b.override!==null),$=he.filter(b=>!(b.calls>0||b.override!==null)),ge=(b,Q)=>m({name:"detail",id:b,from:Q}),z;return c.name==="detail"&&u?z=s(fo,{row:u,platform:Z,log:e.log,run:d,onPicked:S}):c.name==="other"?z=f(g,{children:[s(Je,{rows:$,platform:Z,onOpen:b=>ge(b,"other")}),s(N,{children:"Your app can ask for these but hasn't yet."})]}):z=f(Ge,{children:[fe.length>0?s(Je,{rows:fe,platform:Z,onOpen:b=>ge(b,"list"),onReload:n}):s(O,{padded:true,children:s(h,{style:p.empty,testID:"permissions-empty",children:"Your app hasn't checked any permissions yet. Open a screen that uses location, the camera or notifications and it will show up here."})}),$.length>0?s(O,{children:f(P,{testID:"permissions-other",accessibilityRole:"button",accessibilityLabel:`Other Permissions, ${$.length}`,activeOpacity:.6,onPress:()=>m({name:"other"}),style:p.row,children:[s(h,{style:p.rowTitle,children:"Other Permissions"}),f(g,{style:p.rowRight,children:[s(h,{style:p.rowValue,children:$.length}),s(We,{size:16,color:a.color.textTertiary})]})]})}):null,e.overriddenCount>0?s(O,{children:s(P,{testID:"permissions-reset",accessibilityRole:"button",accessibilityLabel:"Use Real Permissions",activeOpacity:.6,onPress:()=>d("resetAll"),style:p.row,children:s(h,{style:p.destructive,children:"Use Real Permissions"})})}):null]}),f(Se,{style:p.fill,contentContainerStyle:[p.content,{paddingBottom:o.bottom}],testID:"permissions-scroll",children:[!et&&c.name!=="list"?f(P,{testID:"permissions-back",accessibilityRole:"button",accessibilityLabel:"Back",onPress:S,style:p.inlineBack,children:[s(ao,{size:18,color:a.color.accent}),s(h,{style:p.inlineBackText,children:c.name==="detail"&&c.from==="other"?"Other Permissions":"Permissions"}),D?s(h,{style:p.inlineTitle,children:D}):null]}):null,i?s(N,{tone:"danger",centered:true,children:s(h,{testID:"permissions-error",children:i})}):null,z]})}function Je({rows:e,platform:t,onOpen:n,onReload:o}){let[,i]=ro(d=>d+1,0),l=uo(),c=e.filter(d=>d.stale&&d.changedAt!==null&&l-d.changedAt<me).map(d=>me-(l-d.changedAt)),m=c.length>0?Math.min(...c):null;return io(()=>{if(m===null)return;let d=setTimeout(i,m+50);return()=>clearTimeout(d)},[m]),s(O,{children:s(pe,{children:e.map(d=>{let u=d.stale&&d.changedAt!==null&&l-d.changedAt>=me;return f(g,{children:[s(mo,{row:d,platform:t,onPress:()=>n(d.id)}),u?f(g,{style:p.stale,testID:`permissions-stale-${d.id}`,children:[s(h,{style:p.staleText,children:"The app hasn't checked again since this changed."}),o?s(P,{testID:`permissions-reload-${d.id}`,accessibilityRole:"button",accessibilityLabel:"Reload App",onPress:o,hitSlop:{top:8,bottom:8,left:8,right:8},children:s(h,{style:p.staleAction,children:"Reload App"})}):null]}):null]},d.id)})})})}function mo({row:e,platform:t,onPress:n}){let o=e.override!==null,i=po(e,t),l=e.real?k(e.id,t,e.real):"Not Checked";return f(P,{testID:`permissions-row-${e.id}`,accessibilityRole:"button",accessibilityLabel:`${e.label}: ${i}${o?`, simulated. Phone: ${l}`:""}`,activeOpacity:.6,onPress:n,style:p.row,children:[f(g,{style:p.rowLeft,children:[s(h,{style:p.rowTitle,children:e.label}),o?f(h,{style:p.rowSub,testID:`permissions-phone-${e.id}`,children:["Phone: ",l]}):null]}),f(g,{style:p.rowRight,children:[o?s(g,{style:p.dot}):null,s(h,{style:[p.rowValue,o?p.rowValueSimulated:null],testID:`permissions-value-${e.id}`,numberOfLines:1,children:i}),s(We,{size:16,color:a.color.textTertiary})]})]})}function Ze({title:e,detail:t,selected:n,testID:o,onPress:i}){return f(P,{testID:o,accessibilityRole:"button",accessibilityLabel:`${e}. ${t}`,accessibilityState:{selected:n},activeOpacity:.6,onPress:i,style:p.option,children:[f(g,{style:p.optionText,children:[s(h,{style:p.rowTitle,children:e}),s(h,{style:p.optionDetail,children:t})]}),s(g,{style:p.check,children:n?s(so,{size:18,color:a.color.accent}):null})]})}var ho={check:"Checked",request:"Asked",settings:"Opened Settings",gated:"Needed it"};function fo({row:e,platform:t,log:n,run:o,onPicked:i}){let l=e.real?k(e.id,t,e.real):null,c=u=>{u===null?o("clearOverride",{permission:e.id}):o("setOverride",{permission:e.id,state:u}),i()},m=n.filter(u=>u.permission===e.id).slice(0,8),d=e.canRequestReal&&e.real==="undetermined";return f(Ge,{children:[f(g,{children:[s(Ke,{children:"What the app sees"}),s(O,{children:f(pe,{children:[s(Ze,{title:"Phone's Setting",detail:l?`Use what the phone says: ${l}.`:"Use what the phone says.",selected:e.override===null,testID:`permissions-state-${e.id}-real`,onPress:()=>c(null)},"real"),e.states.map(u=>s(Ze,{title:k(e.id,t,u),detail:yn(e.id,t,u),selected:e.override===u,testID:`permissions-state-${e.id}-${u}`,onPress:()=>c(u)},u))]})})]}),d?f(g,{children:[s(O,{children:s(P,{testID:`permissions-request-real-${e.id}`,accessibilityRole:"button",accessibilityLabel:`Show the real system prompt for ${e.label}`,activeOpacity:.6,onPress:()=>o("requestReal",{permission:e.id}),style:p.row,children:s(h,{style:p.action,children:"Show Real Prompt"})})}),s(N,{children:e.warning??"Asks the phone for real, so calls that need this permission work."})]}):e.warning?s(N,{tone:"warning",children:s(h,{testID:`permissions-warning-${e.id}`,children:e.warning})}):null,m.length>0?f(g,{children:[s(Ke,{children:"Recent"}),s(O,{children:s(pe,{children:m.map(u=>s(yo,{entry:u,platform:t},u.id))})}),e.sources.length>0?f(N,{children:["Read through ",e.sources.join(", ")]}):null]}):null]})}function go(e){let t=new Date(e),n=o=>String(o).padStart(2,"0");return`${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`}function yo({entry:e,platform:t}){let n=e.error?"Failed":e.returned&&e.permission?e.answer==="once"&&e.returned==="granted"?"Allowed Once":k(e.permission,t,e.returned):"";return f(g,{style:p.recentRow,testID:`permissions-log-${e.id}`,children:[s(h,{style:p.recentTime,children:go(e.at)}),s(h,{style:p.recentVerb,numberOfLines:1,children:ho[e.kind]}),s(h,{style:[p.recentResult,e.error?p.recentFailed:null],numberOfLines:1,children:n})]})}var p=j.create({fill:{flex:1},content:{paddingHorizontal:a.gutter,paddingTop:12,gap:a.groupGap},waiting:{flex:1,alignItems:"center",justifyContent:"center",padding:24},empty:{color:a.color.textSecondary,fontSize:a.font.body,lineHeight:20},row:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:50,paddingHorizontal:a.rowPadH,paddingVertical:10},rowLeft:{flexShrink:1,gap:2},rowTitle:{color:a.color.text,fontSize:a.font.row},rowSub:{color:a.color.textTertiary,fontSize:a.font.caption},rowRight:{flexDirection:"row",alignItems:"center",gap:6,flexShrink:1},rowValue:{color:a.color.textSecondary,fontSize:a.font.row},rowValueSimulated:{color:a.color.accent},dot:{width:7,height:7,borderRadius:4,backgroundColor:a.color.accent},stale:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",columnGap:10,rowGap:4,paddingHorizontal:a.rowPadH,paddingBottom:12,marginTop:-4},staleText:{color:a.color.textSecondary,fontSize:a.font.caption,flexShrink:1},staleAction:{color:a.color.accent,fontSize:a.font.caption,fontWeight:"600"},destructive:{color:a.color.danger,fontSize:a.font.row},action:{color:a.color.accent,fontSize:a.font.row},option:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:a.rowPadH,paddingVertical:11,minHeight:50},optionText:{flex:1,gap:2},optionDetail:{color:a.color.textTertiary,fontSize:a.font.caption,lineHeight:17},check:{width:20,alignItems:"center"},inlineBack:{flexDirection:"row",alignItems:"center",gap:4,marginBottom:-8},inlineBackText:{color:a.color.accent,fontSize:a.font.row},inlineTitle:{color:a.color.text,fontSize:a.font.row,fontWeight:"600",marginLeft:"auto"},recentRow:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:a.rowPadH,paddingVertical:10},recentTime:{color:a.color.textTertiary,fontSize:a.font.caption,fontVariant:["tabular-nums"]},recentVerb:{color:a.color.text,fontSize:a.font.body,flex:1},recentResult:{color:a.color.textSecondary,fontSize:a.font.body},recentFailed:{color:a.color.danger}});import{jsx as bo}from"react/jsx-runtime";var wo=Ue.actions;async function vo(e,t){let n=wo[e];if(!n)throw new Error(`Unknown permissions action: ${e}`);return n(t)}function Ao(){Kn("auto","buoy permissions").catch(()=>{})}function Qe(){Fn(()=>{ee(),ze()},[]);let e=Wn(M,y,y);return bo(Ye,{snapshot:e,onAction:vo,onReload:Ao})}import{jsx as So}from"react/jsx-runtime";var Xe=Un({id:"permissions",name:"PERMISSIONS",description:"Test denied, blocked, limited and not-asked permission states",slot:"both",color:Hn,icon:({size:e,color:t})=>So(jn,{size:e,color:t}),component:Qe,modal:{subtitle:"choose what the app is allowed to do"}}),Po=Vn(Xe);import{PermissionsIcon as xo,PERMISSIONS_ICON_COLOR as Ro}from"@buoy-gg/shared-ui/web";var ko=typeof navigator<"u"&&navigator.product==="ReactNative";ko&&typeof we<"u"&&we&&(ee(),zn());export{oe as KNOWN_PERMISSION_IDS,F as PERMISSIONS_CHIP_ID,Ro as PERMISSIONS_ICON_COLOR,te as PERMISSION_STATES,Qe as PermissionsBody,Be as PermissionsChip,xo as PermissionsIcon,Ye as PermissionsToolView,De as clearPermissionOverride,Po as createPermissionsTool,In as getPermissionOverride,y as getPermissionsSnapshot,ee as installPermissions,Tn as isPermissionOverridden,_n as openPermissionsChip,R as permissionInfo,Ue as permissionsSyncAdapter,Xe as permissionsToolPreset,se as resetPermissions,Ne as setPermissionOverride,k as stateLabel,M as subscribePermissions,H as supportedStates,Le as updatePermissionSettings};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buoy-gg/permissions",
3
- "version": "7.0.44",
3
+ "version": "7.0.46",
4
4
  "description": "Permission state overrides for React Native: make your app see not asked, allowed, limited, denied or blocked for location, camera, notifications and more, without touching device settings. Works with Expo modules, PermissionsAndroid and react-native-permissions.",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -17,7 +17,7 @@
17
17
  "./lib/web/**/*.mjs"
18
18
  ],
19
19
  "dependencies": {
20
- "@buoy-gg/shared-ui": "^7.0.44"
20
+ "@buoy-gg/shared-ui": "^7.0.46"
21
21
  },
22
22
  "peerDependencies": {
23
23
  "react": "*"