@buoy-gg/permissions 7.0.77 → 7.0.79
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.PermissionsToolView=PermissionsToolView;var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _model=require("../engine/model");var _jsxRuntime=require("react/jsx-runtime");const STALE_AFTER_MS=1500;const realNow=()=>{const e=globalThis.__buoyRealNow;return typeof e==="function"?e():Date.now()};function valueLabel(e,i){if(!e.effective)return"Not Checked";if(e.once&&e.effective==="granted")return"Allowed Once";return(0,_model.stateLabel)(e.id,i,e.effective)}function PermissionsToolView({snapshot:e,onAction:i,onReload:l,browserOnly:o}){const a=(0,_sharedUi.useSafeAreaInsets)({minBottom:16});const[c,h]=(0,_react.useState)(null);const[n,t]=(0,_react.useState)({name:"list"});const s=(r,f)=>{h(null);i(r,f).catch(y=>{h(y instanceof Error?y.message:String(y))})};const u=n.name==="detail"?e?.permissions.find(r=>r.id===n.id):void 0;const x=()=>t(n.name==="detail"&&n.from==="other"?{name:"other"}:{name:"list"});const d=n.name==="other"?"Other Permissions":u?u.label:null;const T=(0,_sharedUi.useToolScreenHeader)(d?{title:d,onBack:x,searchable:false}:null,[d,n.name,n.name==="detail"?n.from:null]);if(!e){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.waiting,testID:"permissions-waiting",children:(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{centered:true,children:"Waiting for the app\u2026"})})}const{platform:m,permissions:j}=e;const b=j.filter(r=>r.calls>0||r.override!==null);const p=j.filter(r=>!(r.calls>0||r.override!==null));const w=(r,f)=>t({name:"detail",id:r,from:f});let g;if(o){g=(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{padded:true,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.empty,testID:"permissions-browser-only",children:"This app runs in a plain browser. The browser keeps its own permissions. Buoy can't change them here. This tool works when the app runs on a phone with Capacitor."})})}else if(n.name==="detail"&&u){g=(0,_jsxRuntime.jsx)(DetailScreen,{row:u,platform:m,log:e.log,run:s,onPicked:x})}else if(n.name==="other"){g=(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(PermissionList,{rows:p,platform:m,onOpen:r=>w(r,"other")}),(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{children:"Your app can ask for these but hasn't yet."})]})}else{g=(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[b.length>0?(0,_jsxRuntime.jsx)(PermissionList,{rows:b,platform:m,onOpen:r=>w(r,"list"),onReload:l}):(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{padded:true,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.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."})}),p.length>0?(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"permissions-other",accessibilityRole:"button",accessibilityLabel:`Other Permissions, ${p.length}`,activeOpacity:.6,onPress:()=>t({name:"other"}),style:styles.row,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowTitle,children:"Other Permissions"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.rowRight,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowValue,children:p.length}),(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:16,color:_sharedUi.night.color.textTertiary})]})]})}):null,e.overriddenCount>0?(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:"permissions-reset",accessibilityRole:"button",accessibilityLabel:"Use Real Permissions",activeOpacity:.6,onPress:()=>s("resetAll"),style:styles.row,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.destructive,children:"Use Real Permissions"})})}):null]})}return(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{style:styles.fill,contentContainerStyle:[styles.content,{paddingBottom:a.bottom}],testID:"permissions-scroll",children:[!T&&n.name!=="list"?(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"permissions-back",accessibilityRole:"button",accessibilityLabel:"Back",onPress:x,style:styles.inlineBack,children:[(0,_jsxRuntime.jsx)(_sharedUi.ChevronLeft,{size:18,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.inlineBackText,children:n.name==="detail"&&n.from==="other"?"Other Permissions":"Permissions"}),d?(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.inlineTitle,children:d}):null]}):null,c?(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{tone:"danger",centered:true,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"permissions-error",children:c})}):null,g]})}function PermissionList({rows:e,platform:i,onOpen:l,onReload:o}){const[,a]=(0,_react.useReducer)(t=>t+1,0);const c=realNow();const h=e.filter(t=>t.stale&&t.changedAt!==null&&c-t.changedAt<STALE_AFTER_MS).map(t=>STALE_AFTER_MS-(c-t.changedAt));const n=h.length>0?Math.min(...h):null;(0,_react.useEffect)(()=>{if(n===null)return;const t=setTimeout(a,n+50);return()=>clearTimeout(t)},[n]);return(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_sharedUi.NightRows,{children:e.map(t=>{const s=t.stale&&t.changedAt!==null&&c-t.changedAt>=STALE_AFTER_MS;return(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(PermissionRowView,{row:t,platform:i,onPress:()=>l(t.id)}),s?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.stale,testID:`permissions-stale-${t.id}`,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.staleText,children:"The app hasn't checked again since this changed."}),o?(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`permissions-reload-${t.id}`,accessibilityRole:"button",accessibilityLabel:"Reload App",onPress:o,hitSlop:{top:8,bottom:8,left:8,right:8},children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.staleAction,children:"Reload App"})}):null]}):null]},t.id)})})})}function PermissionRowView({row:e,platform:i,onPress:l}){const o=e.override!==null;const a=valueLabel(e,i);const c=e.real?(0,_model.stateLabel)(e.id,i,e.real):"Not Checked";return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:`permissions-row-${e.id}`,accessibilityRole:"button",accessibilityLabel:`${e.label}: ${a}${o?`, simulated. Phone: ${c}`:""}`,activeOpacity:.6,onPress:l,style:styles.row,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.rowLeft,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowTitle,children:e.label}),o?(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.rowSub,testID:`permissions-phone-${e.id}`,children:["Phone: ",c]}):null]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.rowRight,children:[o?(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.dot}):null,(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.rowValue,o?styles.rowValueSimulated:null],testID:`permissions-value-${e.id}`,numberOfLines:1,children:a}),(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:16,color:_sharedUi.night.color.textTertiary})]})]})}function OptionRow({title:e,detail:i,selected:l,testID:o,onPress:a}){return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:o,accessibilityRole:"button",accessibilityLabel:`${e}. ${i}`,accessibilityState:{selected:l},activeOpacity:.6,onPress:a,style:styles.option,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.optionText,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowTitle,children:e}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.optionDetail,children:i})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.check,children:l?(0,_jsxRuntime.jsx)(_sharedUi.Check,{size:18,color:_sharedUi.night.color.accent}):null})]})}const VERBS={check:"Checked",request:"Asked",settings:"Opened Settings",gated:"Needed it"};function DetailScreen({row:e,platform:i,log:l,run:o,onPicked:a}){const c=e.real?(0,_model.stateLabel)(e.id,i,e.real):null;const h=s=>{if(s===null)o("clearOverride",{permission:e.id});else o("setOverride",{permission:e.id,state:s});a()};const n=l.filter(s=>s.permission===e.id).slice(0,8);const t=e.canRequestReal&&e.real==="undetermined";return(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(_sharedUi.NightSectionLabel,{children:"What the app sees"}),(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsxs)(_sharedUi.NightRows,{children:[(0,_jsxRuntime.jsx)(OptionRow,{title:"Phone's Setting",detail:c?`Use what the phone says: ${c}.`:"Use what the phone says.",selected:e.override===null,testID:`permissions-state-${e.id}-real`,onPress:()=>h(null)},"real"),e.states.map(s=>(0,_jsxRuntime.jsx)(OptionRow,{title:(0,_model.stateLabel)(e.id,i,s),detail:(0,_model.stateDescription)(e.id,i,s),selected:e.override===s,testID:`permissions-state-${e.id}-${s}`,onPress:()=>h(s)},s))]})})]}),t?(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{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:styles.row,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.action,children:"Show Real Prompt"})})}),(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{children:e.warning??"Asks the phone for real, so calls that need this permission work."})]}):e.warning?(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{tone:"warning",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:`permissions-warning-${e.id}`,children:e.warning})}):null,n.length>0?(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(_sharedUi.NightSectionLabel,{children:"Recent"}),(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_sharedUi.NightRows,{children:n.map(s=>(0,_jsxRuntime.jsx)(RecentRow,{entry:s,platform:i},s.id))})}),e.sources.length>0?(0,_jsxRuntime.jsxs)(_sharedUi.NightFootnote,{children:["Read through ",e.sources.join(", ")]}):null]}):null]})}function clockTime(e){const i=new Date(e);const l=o=>String(o).padStart(2,"0");return`${l(i.getHours())}:${l(i.getMinutes())}:${l(i.getSeconds())}`}function RecentRow({entry:e,platform:i}){const l=e.error?"Failed":e.returned&&e.permission?e.answer==="once"&&e.returned==="granted"?"Allowed Once":(0,_model.stateLabel)(e.permission,i,e.returned):"";return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.recentRow,testID:`permissions-log-${e.id}`,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.recentTime,children:clockTime(e.at)}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.recentVerb,numberOfLines:1,children:VERBS[e.kind]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.recentResult,e.error?styles.recentFailed:null],numberOfLines:1,children:l})]})}const styles=_reactNative.StyleSheet.create({fill:{flex:1},content:{paddingHorizontal:_sharedUi.night.gutter,paddingTop:12,gap:_sharedUi.night.groupGap},waiting:{flex:1,alignItems:"center",justifyContent:"center",padding:24},empty:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.body,lineHeight:20},row:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:50,paddingHorizontal:_sharedUi.night.rowPadH,paddingVertical:10},rowLeft:{flexShrink:1,gap:2},rowTitle:{color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.row},rowSub:{color:_sharedUi.night.color.textTertiary,fontSize:_sharedUi.night.font.caption},rowRight:{flexDirection:"row",alignItems:"center",gap:6,flexShrink:1},rowValue:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.row},rowValueSimulated:{color:_sharedUi.night.color.accent},dot:{width:7,height:7,borderRadius:4,backgroundColor:_sharedUi.night.color.accent},stale:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",columnGap:10,rowGap:4,paddingHorizontal:_sharedUi.night.rowPadH,paddingBottom:12,marginTop:-4},staleText:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.caption,flexShrink:1},staleAction:{color:_sharedUi.night.color.accent,fontSize:_sharedUi.night.font.caption,fontWeight:"600"},destructive:{color:_sharedUi.night.color.danger,fontSize:_sharedUi.night.font.row},action:{color:_sharedUi.night.color.accent,fontSize:_sharedUi.night.font.row},option:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:_sharedUi.night.rowPadH,paddingVertical:11,minHeight:50},optionText:{flex:1,gap:2},optionDetail:{color:_sharedUi.night.color.textTertiary,fontSize:_sharedUi.night.font.caption,lineHeight:17},check:{width:20,alignItems:"center"},inlineBack:{flexDirection:"row",alignItems:"center",gap:4,marginBottom:-8},inlineBackText:{color:_sharedUi.night.color.accent,fontSize:_sharedUi.night.font.row},inlineTitle:{color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.row,fontWeight:"600",marginLeft:"auto"},recentRow:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:_sharedUi.night.rowPadH,paddingVertical:10},recentTime:{color:_sharedUi.night.color.textTertiary,fontSize:_sharedUi.night.font.caption,fontVariant:["tabular-nums"]},recentVerb:{color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.body,flex:1},recentResult:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.body},recentFailed:{color:_sharedUi.night.color.danger}});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.PermissionsToolView=PermissionsToolView;var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _model=require("../engine/model");var _jsxRuntime=require("react/jsx-runtime");const STALE_AFTER_MS=1500;const realNow=()=>{const e=globalThis.__buoyRealNow;return typeof e==="function"?e():Date.now()};function valueLabel(e,i){if(!e.effective)return"Not Checked";if(e.once&&e.effective==="granted")return"Allowed Once";return(0,_model.stateLabel)(e.id,i,e.effective)}function PermissionsToolView({snapshot:e,onAction:i,onReload:l,browserOnly:o}){const a=(0,_sharedUi.useSafeAreaInsets)({minBottom:16});const[c,h]=(0,_react.useState)(null);const[n,t]=(0,_react.useState)({name:"list"});const s=(r,f)=>{h(null);i(r,f).catch(y=>{h(y instanceof Error?y.message:String(y))})};const u=n.name==="detail"?e?.permissions.find(r=>r.id===n.id):void 0;const x=()=>t(n.name==="detail"&&n.from==="other"?{name:"other"}:{name:"list"});const d=n.name==="other"?"Other Permissions":u?u.label:null;const T=(0,_sharedUi.useToolScreenHeader)(d?{title:d,onBack:x,searchable:false}:null,[d,n.name,n.name==="detail"?n.from:null]);if(!e){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.waiting,testID:"permissions-waiting",children:(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{centered:true,children:"Waiting for the app\u2026"})})}const{platform:m,permissions:j}=e;const b=j.filter(r=>r.calls>0||r.override!==null);const p=j.filter(r=>!(r.calls>0||r.override!==null));const w=(r,f)=>t({name:"detail",id:r,from:f});let g;if(o){g=(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{padded:true,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.empty,testID:"permissions-browser-only",children:"This app runs in a plain browser. The browser keeps its own permissions. Buoy can't change them here. This tool works when the app runs on a phone with Capacitor."})})}else if(n.name==="detail"&&u){g=(0,_jsxRuntime.jsx)(DetailScreen,{row:u,platform:m,log:e.log,run:s,onPicked:x})}else if(n.name==="other"){g=(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(PermissionList,{rows:p,platform:m,onOpen:r=>w(r,"other")}),(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{children:"Your app can ask for these but hasn't yet."})]})}else{g=(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[b.length>0?(0,_jsxRuntime.jsx)(PermissionList,{rows:b,platform:m,onOpen:r=>w(r,"list"),onReload:l}):(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{padded:true,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.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."})}),p.length>0?(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"permissions-other",accessibilityRole:"button",accessibilityLabel:`Other Permissions, ${p.length}`,activeOpacity:.6,onPress:()=>t({name:"other"}),style:styles.row,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowTitle,children:"Other Permissions"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.rowRight,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowValue,children:p.length}),(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:16,color:_sharedUi.night.color.textTertiary})]})]})}):null,e.overriddenCount>0?(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:"permissions-reset",accessibilityRole:"button",accessibilityLabel:"Use Real Permissions",activeOpacity:.6,onPress:()=>s("resetAll"),style:styles.row,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.destructive,children:"Use Real Permissions"})})}):null]})}return(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{keyboardShouldPersistTaps:"handled",style:styles.fill,contentContainerStyle:[styles.content,{paddingBottom:a.bottom}],testID:"permissions-scroll",children:[!T&&n.name!=="list"?(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"permissions-back",accessibilityRole:"button",accessibilityLabel:"Back",onPress:x,style:styles.inlineBack,children:[(0,_jsxRuntime.jsx)(_sharedUi.ChevronLeft,{size:18,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.inlineBackText,children:n.name==="detail"&&n.from==="other"?"Other Permissions":"Permissions"}),d?(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.inlineTitle,children:d}):null]}):null,c?(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{tone:"danger",centered:true,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"permissions-error",children:c})}):null,g]})}function PermissionList({rows:e,platform:i,onOpen:l,onReload:o}){const[,a]=(0,_react.useReducer)(t=>t+1,0);const c=realNow();const h=e.filter(t=>t.stale&&t.changedAt!==null&&c-t.changedAt<STALE_AFTER_MS).map(t=>STALE_AFTER_MS-(c-t.changedAt));const n=h.length>0?Math.min(...h):null;(0,_react.useEffect)(()=>{if(n===null)return;const t=setTimeout(a,n+50);return()=>clearTimeout(t)},[n]);return(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_sharedUi.NightRows,{children:e.map(t=>{const s=t.stale&&t.changedAt!==null&&c-t.changedAt>=STALE_AFTER_MS;return(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(PermissionRowView,{row:t,platform:i,onPress:()=>l(t.id)}),s?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.stale,testID:`permissions-stale-${t.id}`,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.staleText,children:"The app hasn't checked again since this changed."}),o?(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`permissions-reload-${t.id}`,accessibilityRole:"button",accessibilityLabel:"Reload App",onPress:o,hitSlop:{top:8,bottom:8,left:8,right:8},children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.staleAction,children:"Reload App"})}):null]}):null]},t.id)})})})}function PermissionRowView({row:e,platform:i,onPress:l}){const o=e.override!==null;const a=valueLabel(e,i);const c=e.real?(0,_model.stateLabel)(e.id,i,e.real):"Not Checked";return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:`permissions-row-${e.id}`,accessibilityRole:"button",accessibilityLabel:`${e.label}: ${a}${o?`, simulated. Phone: ${c}`:""}`,activeOpacity:.6,onPress:l,style:styles.row,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.rowLeft,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowTitle,children:e.label}),o?(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.rowSub,testID:`permissions-phone-${e.id}`,children:["Phone: ",c]}):null]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.rowRight,children:[o?(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.dot}):null,(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.rowValue,o?styles.rowValueSimulated:null],testID:`permissions-value-${e.id}`,numberOfLines:1,children:a}),(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:16,color:_sharedUi.night.color.textTertiary})]})]})}function OptionRow({title:e,detail:i,selected:l,testID:o,onPress:a}){return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:o,accessibilityRole:"button",accessibilityLabel:`${e}. ${i}`,accessibilityState:{selected:l},activeOpacity:.6,onPress:a,style:styles.option,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.optionText,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.rowTitle,children:e}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.optionDetail,children:i})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.check,children:l?(0,_jsxRuntime.jsx)(_sharedUi.Check,{size:18,color:_sharedUi.night.color.accent}):null})]})}const VERBS={check:"Checked",request:"Asked",settings:"Opened Settings",gated:"Needed it"};function DetailScreen({row:e,platform:i,log:l,run:o,onPicked:a}){const c=e.real?(0,_model.stateLabel)(e.id,i,e.real):null;const h=s=>{if(s===null)o("clearOverride",{permission:e.id});else o("setOverride",{permission:e.id,state:s});a()};const n=l.filter(s=>s.permission===e.id).slice(0,8);const t=e.canRequestReal&&e.real==="undetermined";return(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(_sharedUi.NightSectionLabel,{children:"What the app sees"}),(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsxs)(_sharedUi.NightRows,{children:[(0,_jsxRuntime.jsx)(OptionRow,{title:"Phone's Setting",detail:c?`Use what the phone says: ${c}.`:"Use what the phone says.",selected:e.override===null,testID:`permissions-state-${e.id}-real`,onPress:()=>h(null)},"real"),e.states.map(s=>(0,_jsxRuntime.jsx)(OptionRow,{title:(0,_model.stateLabel)(e.id,i,s),detail:(0,_model.stateDescription)(e.id,i,s),selected:e.override===s,testID:`permissions-state-${e.id}-${s}`,onPress:()=>h(s)},s))]})})]}),t?(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{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:styles.row,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.action,children:"Show Real Prompt"})})}),(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{children:e.warning??"Asks the phone for real, so calls that need this permission work."})]}):e.warning?(0,_jsxRuntime.jsx)(_sharedUi.NightFootnote,{tone:"warning",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:`permissions-warning-${e.id}`,children:e.warning})}):null,n.length>0?(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(_sharedUi.NightSectionLabel,{children:"Recent"}),(0,_jsxRuntime.jsx)(_sharedUi.NightCard,{children:(0,_jsxRuntime.jsx)(_sharedUi.NightRows,{children:n.map(s=>(0,_jsxRuntime.jsx)(RecentRow,{entry:s,platform:i},s.id))})}),e.sources.length>0?(0,_jsxRuntime.jsxs)(_sharedUi.NightFootnote,{children:["Read through ",e.sources.join(", ")]}):null]}):null]})}function clockTime(e){const i=new Date(e);const l=o=>String(o).padStart(2,"0");return`${l(i.getHours())}:${l(i.getMinutes())}:${l(i.getSeconds())}`}function RecentRow({entry:e,platform:i}){const l=e.error?"Failed":e.returned&&e.permission?e.answer==="once"&&e.returned==="granted"?"Allowed Once":(0,_model.stateLabel)(e.permission,i,e.returned):"";return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.recentRow,testID:`permissions-log-${e.id}`,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.recentTime,children:clockTime(e.at)}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.recentVerb,numberOfLines:1,children:VERBS[e.kind]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.recentResult,e.error?styles.recentFailed:null],numberOfLines:1,children:l})]})}const styles=_reactNative.StyleSheet.create({fill:{flex:1},content:{paddingHorizontal:_sharedUi.night.gutter,paddingTop:12,gap:_sharedUi.night.groupGap},waiting:{flex:1,alignItems:"center",justifyContent:"center",padding:24},empty:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.body,lineHeight:20},row:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:50,paddingHorizontal:_sharedUi.night.rowPadH,paddingVertical:10},rowLeft:{flexShrink:1,gap:2},rowTitle:{color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.row},rowSub:{color:_sharedUi.night.color.textTertiary,fontSize:_sharedUi.night.font.caption},rowRight:{flexDirection:"row",alignItems:"center",gap:6,flexShrink:1},rowValue:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.row},rowValueSimulated:{color:_sharedUi.night.color.accent},dot:{width:7,height:7,borderRadius:4,backgroundColor:_sharedUi.night.color.accent},stale:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",columnGap:10,rowGap:4,paddingHorizontal:_sharedUi.night.rowPadH,paddingBottom:12,marginTop:-4},staleText:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.caption,flexShrink:1},staleAction:{color:_sharedUi.night.color.accent,fontSize:_sharedUi.night.font.caption,fontWeight:"600"},destructive:{color:_sharedUi.night.color.danger,fontSize:_sharedUi.night.font.row},action:{color:_sharedUi.night.color.accent,fontSize:_sharedUi.night.font.row},option:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:_sharedUi.night.rowPadH,paddingVertical:11,minHeight:50},optionText:{flex:1,gap:2},optionDetail:{color:_sharedUi.night.color.textTertiary,fontSize:_sharedUi.night.font.caption,lineHeight:17},check:{width:20,alignItems:"center"},inlineBack:{flexDirection:"row",alignItems:"center",gap:4,marginBottom:-8},inlineBackText:{color:_sharedUi.night.color.accent,fontSize:_sharedUi.night.font.row},inlineTitle:{color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.row,fontWeight:"600",marginLeft:"auto"},recentRow:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:_sharedUi.night.rowPadH,paddingVertical:10},recentTime:{color:_sharedUi.night.color.textTertiary,fontSize:_sharedUi.night.font.caption,fontVariant:["tabular-nums"]},recentVerb:{color:_sharedUi.night.color.text,fontSize:_sharedUi.night.font.body,flex:1},recentResult:{color:_sharedUi.night.color.textSecondary,fontSize:_sharedUi.night.font.body},recentFailed:{color:_sharedUi.night.color.danger}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{useEffect as _,useReducer as E,useState as V}from"react";import{ScrollView as W,StyleSheet as q,Text as c,TouchableOpacity as b,View as u}from"react-native";import{Check as U,ChevronLeft as G,ChevronRight as H,NightCard as y,NightFootnote as S,NightRows as z,NightSectionLabel as C,night as n,useSafeAreaInsets as M,useToolScreenHeader as Y}from"@buoy-gg/shared-ui";import{stateDescription as J,stateLabel as R}from"../engine/model";import{jsx as t,jsxs as r,Fragment as B}from"react/jsx-runtime";const $=1500;const K=()=>{const e=globalThis.__buoyRealNow;return typeof e==="function"?e():Date.now()};function Q(e,l){if(!e.effective)return"Not Checked";if(e.once&&e.effective==="granted")return"Allowed Once";return R(e.id,l,e.effective)}export function PermissionsToolView({snapshot:e,onAction:l,onReload:h,browserOnly:d}){const f=M({minBottom:16});const[m,g]=V(null);const[s,o]=V({name:"list"});const a=(p,I)=>{g(null);l(p,I).catch(v=>{g(v instanceof Error?v.message:String(v))})};const T=s.name==="detail"?e?.permissions.find(p=>p.id===s.id):void 0;const D=()=>o(s.name==="detail"&&s.from==="other"?{name:"other"}:{name:"list"});const w=s.name==="other"?"Other Permissions":T?T.label:null;const F=Y(w?{title:w,onBack:D,searchable:false}:null,[w,s.name,s.name==="detail"?s.from:null]);if(!e){return t(u,{style:i.waiting,testID:"permissions-waiting",children:t(S,{centered:true,children:"Waiting for the app\u2026"})})}const{platform:P,permissions:O}=e;const L=O.filter(p=>p.calls>0||p.override!==null);const k=O.filter(p=>!(p.calls>0||p.override!==null));const A=(p,I)=>o({name:"detail",id:p,from:I});let x;if(d){x=t(y,{padded:true,children:t(c,{style:i.empty,testID:"permissions-browser-only",children:"This app runs in a plain browser. The browser keeps its own permissions. Buoy can't change them here. This tool works when the app runs on a phone with Capacitor."})})}else if(s.name==="detail"&&T){x=t(ee,{row:T,platform:P,log:e.log,run:a,onPicked:D})}else if(s.name==="other"){x=r(u,{children:[t(N,{rows:k,platform:P,onOpen:p=>A(p,"other")}),t(S,{children:"Your app can ask for these but hasn't yet."})]})}else{x=r(B,{children:[L.length>0?t(N,{rows:L,platform:P,onOpen:p=>A(p,"list"),onReload:h}):t(y,{padded:true,children:t(c,{style:i.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."})}),k.length>0?t(y,{children:r(b,{testID:"permissions-other",accessibilityRole:"button",accessibilityLabel:`Other Permissions, ${k.length}`,activeOpacity:.6,onPress:()=>o({name:"other"}),style:i.row,children:[t(c,{style:i.rowTitle,children:"Other Permissions"}),r(u,{style:i.rowRight,children:[t(c,{style:i.rowValue,children:k.length}),t(H,{size:16,color:n.color.textTertiary})]})]})}):null,e.overriddenCount>0?t(y,{children:t(b,{testID:"permissions-reset",accessibilityRole:"button",accessibilityLabel:"Use Real Permissions",activeOpacity:.6,onPress:()=>a("resetAll"),style:i.row,children:t(c,{style:i.destructive,children:"Use Real Permissions"})})}):null]})}return r(W,{style:i.fill,contentContainerStyle:[i.content,{paddingBottom:f.bottom}],testID:"permissions-scroll",children:[!F&&s.name!=="list"?r(b,{testID:"permissions-back",accessibilityRole:"button",accessibilityLabel:"Back",onPress:D,style:i.inlineBack,children:[t(G,{size:18,color:n.color.accent}),t(c,{style:i.inlineBackText,children:s.name==="detail"&&s.from==="other"?"Other Permissions":"Permissions"}),w?t(c,{style:i.inlineTitle,children:w}):null]}):null,m?t(S,{tone:"danger",centered:true,children:t(c,{testID:"permissions-error",children:m})}):null,x]})}function N({rows:e,platform:l,onOpen:h,onReload:d}){const[,f]=E(o=>o+1,0);const m=K();const g=e.filter(o=>o.stale&&o.changedAt!==null&&m-o.changedAt<$).map(o=>$-(m-o.changedAt));const s=g.length>0?Math.min(...g):null;_(()=>{if(s===null)return;const o=setTimeout(f,s+50);return()=>clearTimeout(o)},[s]);return t(y,{children:t(z,{children:e.map(o=>{const a=o.stale&&o.changedAt!==null&&m-o.changedAt>=$;return r(u,{children:[t(X,{row:o,platform:l,onPress:()=>h(o.id)}),a?r(u,{style:i.stale,testID:`permissions-stale-${o.id}`,children:[t(c,{style:i.staleText,children:"The app hasn't checked again since this changed."}),d?t(b,{testID:`permissions-reload-${o.id}`,accessibilityRole:"button",accessibilityLabel:"Reload App",onPress:d,hitSlop:{top:8,bottom:8,left:8,right:8},children:t(c,{style:i.staleAction,children:"Reload App"})}):null]}):null]},o.id)})})})}function X({row:e,platform:l,onPress:h}){const d=e.override!==null;const f=Q(e,l);const m=e.real?R(e.id,l,e.real):"Not Checked";return r(b,{testID:`permissions-row-${e.id}`,accessibilityRole:"button",accessibilityLabel:`${e.label}: ${f}${d?`, simulated. Phone: ${m}`:""}`,activeOpacity:.6,onPress:h,style:i.row,children:[r(u,{style:i.rowLeft,children:[t(c,{style:i.rowTitle,children:e.label}),d?r(c,{style:i.rowSub,testID:`permissions-phone-${e.id}`,children:["Phone: ",m]}):null]}),r(u,{style:i.rowRight,children:[d?t(u,{style:i.dot}):null,t(c,{style:[i.rowValue,d?i.rowValueSimulated:null],testID:`permissions-value-${e.id}`,numberOfLines:1,children:f}),t(H,{size:16,color:n.color.textTertiary})]})]})}function j({title:e,detail:l,selected:h,testID:d,onPress:f}){return r(b,{testID:d,accessibilityRole:"button",accessibilityLabel:`${e}. ${l}`,accessibilityState:{selected:h},activeOpacity:.6,onPress:f,style:i.option,children:[r(u,{style:i.optionText,children:[t(c,{style:i.rowTitle,children:e}),t(c,{style:i.optionDetail,children:l})]}),t(u,{style:i.check,children:h?t(U,{size:18,color:n.color.accent}):null})]})}const Z={check:"Checked",request:"Asked",settings:"Opened Settings",gated:"Needed it"};function ee({row:e,platform:l,log:h,run:d,onPicked:f}){const m=e.real?R(e.id,l,e.real):null;const g=a=>{if(a===null)d("clearOverride",{permission:e.id});else d("setOverride",{permission:e.id,state:a});f()};const s=h.filter(a=>a.permission===e.id).slice(0,8);const o=e.canRequestReal&&e.real==="undetermined";return r(B,{children:[r(u,{children:[t(C,{children:"What the app sees"}),t(y,{children:r(z,{children:[t(j,{title:"Phone's Setting",detail:m?`Use what the phone says: ${m}.`:"Use what the phone says.",selected:e.override===null,testID:`permissions-state-${e.id}-real`,onPress:()=>g(null)},"real"),e.states.map(a=>t(j,{title:R(e.id,l,a),detail:J(e.id,l,a),selected:e.override===a,testID:`permissions-state-${e.id}-${a}`,onPress:()=>g(a)},a))]})})]}),o?r(u,{children:[t(y,{children:t(b,{testID:`permissions-request-real-${e.id}`,accessibilityRole:"button",accessibilityLabel:`Show the real system prompt for ${e.label}`,activeOpacity:.6,onPress:()=>d("requestReal",{permission:e.id}),style:i.row,children:t(c,{style:i.action,children:"Show Real Prompt"})})}),t(S,{children:e.warning??"Asks the phone for real, so calls that need this permission work."})]}):e.warning?t(S,{tone:"warning",children:t(c,{testID:`permissions-warning-${e.id}`,children:e.warning})}):null,s.length>0?r(u,{children:[t(C,{children:"Recent"}),t(y,{children:t(z,{children:s.map(a=>t(ne,{entry:a,platform:l},a.id))})}),e.sources.length>0?r(S,{children:["Read through ",e.sources.join(", ")]}):null]}):null]})}function te(e){const l=new Date(e);const h=d=>String(d).padStart(2,"0");return`${h(l.getHours())}:${h(l.getMinutes())}:${h(l.getSeconds())}`}function ne({entry:e,platform:l}){const h=e.error?"Failed":e.returned&&e.permission?e.answer==="once"&&e.returned==="granted"?"Allowed Once":R(e.permission,l,e.returned):"";return r(u,{style:i.recentRow,testID:`permissions-log-${e.id}`,children:[t(c,{style:i.recentTime,children:te(e.at)}),t(c,{style:i.recentVerb,numberOfLines:1,children:Z[e.kind]}),t(c,{style:[i.recentResult,e.error?i.recentFailed:null],numberOfLines:1,children:h})]})}const i=q.create({fill:{flex:1},content:{paddingHorizontal:n.gutter,paddingTop:12,gap:n.groupGap},waiting:{flex:1,alignItems:"center",justifyContent:"center",padding:24},empty:{color:n.color.textSecondary,fontSize:n.font.body,lineHeight:20},row:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:50,paddingHorizontal:n.rowPadH,paddingVertical:10},rowLeft:{flexShrink:1,gap:2},rowTitle:{color:n.color.text,fontSize:n.font.row},rowSub:{color:n.color.textTertiary,fontSize:n.font.caption},rowRight:{flexDirection:"row",alignItems:"center",gap:6,flexShrink:1},rowValue:{color:n.color.textSecondary,fontSize:n.font.row},rowValueSimulated:{color:n.color.accent},dot:{width:7,height:7,borderRadius:4,backgroundColor:n.color.accent},stale:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",columnGap:10,rowGap:4,paddingHorizontal:n.rowPadH,paddingBottom:12,marginTop:-4},staleText:{color:n.color.textSecondary,fontSize:n.font.caption,flexShrink:1},staleAction:{color:n.color.accent,fontSize:n.font.caption,fontWeight:"600"},destructive:{color:n.color.danger,fontSize:n.font.row},action:{color:n.color.accent,fontSize:n.font.row},option:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:n.rowPadH,paddingVertical:11,minHeight:50},optionText:{flex:1,gap:2},optionDetail:{color:n.color.textTertiary,fontSize:n.font.caption,lineHeight:17},check:{width:20,alignItems:"center"},inlineBack:{flexDirection:"row",alignItems:"center",gap:4,marginBottom:-8},inlineBackText:{color:n.color.accent,fontSize:n.font.row},inlineTitle:{color:n.color.text,fontSize:n.font.row,fontWeight:"600",marginLeft:"auto"},recentRow:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:n.rowPadH,paddingVertical:10},recentTime:{color:n.color.textTertiary,fontSize:n.font.caption,fontVariant:["tabular-nums"]},recentVerb:{color:n.color.text,fontSize:n.font.body,flex:1},recentResult:{color:n.color.textSecondary,fontSize:n.font.body},recentFailed:{color:n.color.danger}});
|
|
1
|
+
"use strict";import{useEffect as _,useReducer as E,useState as V}from"react";import{ScrollView as W,StyleSheet as q,Text as c,TouchableOpacity as b,View as u}from"react-native";import{Check as U,ChevronLeft as G,ChevronRight as H,NightCard as y,NightFootnote as S,NightRows as z,NightSectionLabel as C,night as n,useSafeAreaInsets as M,useToolScreenHeader as Y}from"@buoy-gg/shared-ui";import{stateDescription as J,stateLabel as R}from"../engine/model";import{jsx as t,jsxs as r,Fragment as B}from"react/jsx-runtime";const $=1500;const K=()=>{const e=globalThis.__buoyRealNow;return typeof e==="function"?e():Date.now()};function Q(e,l){if(!e.effective)return"Not Checked";if(e.once&&e.effective==="granted")return"Allowed Once";return R(e.id,l,e.effective)}export function PermissionsToolView({snapshot:e,onAction:l,onReload:h,browserOnly:d}){const f=M({minBottom:16});const[m,g]=V(null);const[s,o]=V({name:"list"});const a=(p,I)=>{g(null);l(p,I).catch(v=>{g(v instanceof Error?v.message:String(v))})};const T=s.name==="detail"?e?.permissions.find(p=>p.id===s.id):void 0;const D=()=>o(s.name==="detail"&&s.from==="other"?{name:"other"}:{name:"list"});const w=s.name==="other"?"Other Permissions":T?T.label:null;const F=Y(w?{title:w,onBack:D,searchable:false}:null,[w,s.name,s.name==="detail"?s.from:null]);if(!e){return t(u,{style:i.waiting,testID:"permissions-waiting",children:t(S,{centered:true,children:"Waiting for the app\u2026"})})}const{platform:P,permissions:O}=e;const L=O.filter(p=>p.calls>0||p.override!==null);const k=O.filter(p=>!(p.calls>0||p.override!==null));const A=(p,I)=>o({name:"detail",id:p,from:I});let x;if(d){x=t(y,{padded:true,children:t(c,{style:i.empty,testID:"permissions-browser-only",children:"This app runs in a plain browser. The browser keeps its own permissions. Buoy can't change them here. This tool works when the app runs on a phone with Capacitor."})})}else if(s.name==="detail"&&T){x=t(ee,{row:T,platform:P,log:e.log,run:a,onPicked:D})}else if(s.name==="other"){x=r(u,{children:[t(N,{rows:k,platform:P,onOpen:p=>A(p,"other")}),t(S,{children:"Your app can ask for these but hasn't yet."})]})}else{x=r(B,{children:[L.length>0?t(N,{rows:L,platform:P,onOpen:p=>A(p,"list"),onReload:h}):t(y,{padded:true,children:t(c,{style:i.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."})}),k.length>0?t(y,{children:r(b,{testID:"permissions-other",accessibilityRole:"button",accessibilityLabel:`Other Permissions, ${k.length}`,activeOpacity:.6,onPress:()=>o({name:"other"}),style:i.row,children:[t(c,{style:i.rowTitle,children:"Other Permissions"}),r(u,{style:i.rowRight,children:[t(c,{style:i.rowValue,children:k.length}),t(H,{size:16,color:n.color.textTertiary})]})]})}):null,e.overriddenCount>0?t(y,{children:t(b,{testID:"permissions-reset",accessibilityRole:"button",accessibilityLabel:"Use Real Permissions",activeOpacity:.6,onPress:()=>a("resetAll"),style:i.row,children:t(c,{style:i.destructive,children:"Use Real Permissions"})})}):null]})}return r(W,{keyboardShouldPersistTaps:"handled",style:i.fill,contentContainerStyle:[i.content,{paddingBottom:f.bottom}],testID:"permissions-scroll",children:[!F&&s.name!=="list"?r(b,{testID:"permissions-back",accessibilityRole:"button",accessibilityLabel:"Back",onPress:D,style:i.inlineBack,children:[t(G,{size:18,color:n.color.accent}),t(c,{style:i.inlineBackText,children:s.name==="detail"&&s.from==="other"?"Other Permissions":"Permissions"}),w?t(c,{style:i.inlineTitle,children:w}):null]}):null,m?t(S,{tone:"danger",centered:true,children:t(c,{testID:"permissions-error",children:m})}):null,x]})}function N({rows:e,platform:l,onOpen:h,onReload:d}){const[,f]=E(o=>o+1,0);const m=K();const g=e.filter(o=>o.stale&&o.changedAt!==null&&m-o.changedAt<$).map(o=>$-(m-o.changedAt));const s=g.length>0?Math.min(...g):null;_(()=>{if(s===null)return;const o=setTimeout(f,s+50);return()=>clearTimeout(o)},[s]);return t(y,{children:t(z,{children:e.map(o=>{const a=o.stale&&o.changedAt!==null&&m-o.changedAt>=$;return r(u,{children:[t(X,{row:o,platform:l,onPress:()=>h(o.id)}),a?r(u,{style:i.stale,testID:`permissions-stale-${o.id}`,children:[t(c,{style:i.staleText,children:"The app hasn't checked again since this changed."}),d?t(b,{testID:`permissions-reload-${o.id}`,accessibilityRole:"button",accessibilityLabel:"Reload App",onPress:d,hitSlop:{top:8,bottom:8,left:8,right:8},children:t(c,{style:i.staleAction,children:"Reload App"})}):null]}):null]},o.id)})})})}function X({row:e,platform:l,onPress:h}){const d=e.override!==null;const f=Q(e,l);const m=e.real?R(e.id,l,e.real):"Not Checked";return r(b,{testID:`permissions-row-${e.id}`,accessibilityRole:"button",accessibilityLabel:`${e.label}: ${f}${d?`, simulated. Phone: ${m}`:""}`,activeOpacity:.6,onPress:h,style:i.row,children:[r(u,{style:i.rowLeft,children:[t(c,{style:i.rowTitle,children:e.label}),d?r(c,{style:i.rowSub,testID:`permissions-phone-${e.id}`,children:["Phone: ",m]}):null]}),r(u,{style:i.rowRight,children:[d?t(u,{style:i.dot}):null,t(c,{style:[i.rowValue,d?i.rowValueSimulated:null],testID:`permissions-value-${e.id}`,numberOfLines:1,children:f}),t(H,{size:16,color:n.color.textTertiary})]})]})}function j({title:e,detail:l,selected:h,testID:d,onPress:f}){return r(b,{testID:d,accessibilityRole:"button",accessibilityLabel:`${e}. ${l}`,accessibilityState:{selected:h},activeOpacity:.6,onPress:f,style:i.option,children:[r(u,{style:i.optionText,children:[t(c,{style:i.rowTitle,children:e}),t(c,{style:i.optionDetail,children:l})]}),t(u,{style:i.check,children:h?t(U,{size:18,color:n.color.accent}):null})]})}const Z={check:"Checked",request:"Asked",settings:"Opened Settings",gated:"Needed it"};function ee({row:e,platform:l,log:h,run:d,onPicked:f}){const m=e.real?R(e.id,l,e.real):null;const g=a=>{if(a===null)d("clearOverride",{permission:e.id});else d("setOverride",{permission:e.id,state:a});f()};const s=h.filter(a=>a.permission===e.id).slice(0,8);const o=e.canRequestReal&&e.real==="undetermined";return r(B,{children:[r(u,{children:[t(C,{children:"What the app sees"}),t(y,{children:r(z,{children:[t(j,{title:"Phone's Setting",detail:m?`Use what the phone says: ${m}.`:"Use what the phone says.",selected:e.override===null,testID:`permissions-state-${e.id}-real`,onPress:()=>g(null)},"real"),e.states.map(a=>t(j,{title:R(e.id,l,a),detail:J(e.id,l,a),selected:e.override===a,testID:`permissions-state-${e.id}-${a}`,onPress:()=>g(a)},a))]})})]}),o?r(u,{children:[t(y,{children:t(b,{testID:`permissions-request-real-${e.id}`,accessibilityRole:"button",accessibilityLabel:`Show the real system prompt for ${e.label}`,activeOpacity:.6,onPress:()=>d("requestReal",{permission:e.id}),style:i.row,children:t(c,{style:i.action,children:"Show Real Prompt"})})}),t(S,{children:e.warning??"Asks the phone for real, so calls that need this permission work."})]}):e.warning?t(S,{tone:"warning",children:t(c,{testID:`permissions-warning-${e.id}`,children:e.warning})}):null,s.length>0?r(u,{children:[t(C,{children:"Recent"}),t(y,{children:t(z,{children:s.map(a=>t(ne,{entry:a,platform:l},a.id))})}),e.sources.length>0?r(S,{children:["Read through ",e.sources.join(", ")]}):null]}):null]})}function te(e){const l=new Date(e);const h=d=>String(d).padStart(2,"0");return`${h(l.getHours())}:${h(l.getMinutes())}:${h(l.getSeconds())}`}function ne({entry:e,platform:l}){const h=e.error?"Failed":e.returned&&e.permission?e.answer==="once"&&e.returned==="granted"?"Allowed Once":R(e.permission,l,e.returned):"";return r(u,{style:i.recentRow,testID:`permissions-log-${e.id}`,children:[t(c,{style:i.recentTime,children:te(e.at)}),t(c,{style:i.recentVerb,numberOfLines:1,children:Z[e.kind]}),t(c,{style:[i.recentResult,e.error?i.recentFailed:null],numberOfLines:1,children:h})]})}const i=q.create({fill:{flex:1},content:{paddingHorizontal:n.gutter,paddingTop:12,gap:n.groupGap},waiting:{flex:1,alignItems:"center",justifyContent:"center",padding:24},empty:{color:n.color.textSecondary,fontSize:n.font.body,lineHeight:20},row:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:50,paddingHorizontal:n.rowPadH,paddingVertical:10},rowLeft:{flexShrink:1,gap:2},rowTitle:{color:n.color.text,fontSize:n.font.row},rowSub:{color:n.color.textTertiary,fontSize:n.font.caption},rowRight:{flexDirection:"row",alignItems:"center",gap:6,flexShrink:1},rowValue:{color:n.color.textSecondary,fontSize:n.font.row},rowValueSimulated:{color:n.color.accent},dot:{width:7,height:7,borderRadius:4,backgroundColor:n.color.accent},stale:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",columnGap:10,rowGap:4,paddingHorizontal:n.rowPadH,paddingBottom:12,marginTop:-4},staleText:{color:n.color.textSecondary,fontSize:n.font.caption,flexShrink:1},staleAction:{color:n.color.accent,fontSize:n.font.caption,fontWeight:"600"},destructive:{color:n.color.danger,fontSize:n.font.row},action:{color:n.color.accent,fontSize:n.font.row},option:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:n.rowPadH,paddingVertical:11,minHeight:50},optionText:{flex:1,gap:2},optionDetail:{color:n.color.textTertiary,fontSize:n.font.caption,lineHeight:17},check:{width:20,alignItems:"center"},inlineBack:{flexDirection:"row",alignItems:"center",gap:4,marginBottom:-8},inlineBackText:{color:n.color.accent,fontSize:n.font.row},inlineTitle:{color:n.color.text,fontSize:n.font.row,fontWeight:"600",marginLeft:"auto"},recentRow:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:n.rowPadH,paddingVertical:10},recentTime:{color:n.color.textTertiary,fontSize:n.font.caption,fontVariant:["tabular-nums"]},recentVerb:{color:n.color.text,fontSize:n.font.body,flex:1},recentResult:{color:n.color.textSecondary,fontSize:n.font.body},recentFailed:{color:n.color.danger}});
|
package/lib/web/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";var ot=Object.defineProperty;var wn=Object.getOwnPropertyDescriptor;var vn=Object.getOwnPropertyNames;var An=Object.prototype.hasOwnProperty;var Sn=(e,t)=>{for(var n in t)ot(e,n,{get:t[n],enumerable:true})},rt=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of vn(t))!An.call(e,o)&&o!==n&&ot(e,o,{get:()=>t[o],enumerable:!(i=wn(t,o))||i.enumerable});return e},Pn=(e,t,n)=>(rt(e,t,"default"),n&&rt(n,t,"default"));var st=(()=>{try{let e=globalThis.Capacitor;if(e&&typeof e.isNativePlatform=="function"&&e.isNativePlatform())return e.DEBUG===true}catch{}return process.env.NODE_ENV!=="production"})();typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import{callCapacitorNative as xn,capacitorPlatform as kn,emitCapacitorEvent as ae,hasCapacitorPlugin as En,loadCapacitorAppHost as Cn}from"@buoy-gg/license/web";function Ee(e){let t=e;if(!t?.coords||typeof t.coords.latitude!="number"||typeof t.coords.longitude!="number")return e;let n=i=>Math.round(i/.02)*.02;return{...t,coords:{...t.coords,latitude:Number(n(t.coords.latitude).toFixed(4)),longitude:Number(n(t.coords.longitude).toFixed(4)),accuracy:Math.max(t.coords.accuracy??0,3e3),altitude:null,altitudeAccuracy:null,heading:null,speed:null}}}import{callCapacitorNative as K,hasCapacitorPlugin as at,installCapacitorBridge as On,interceptCapacitor as le,makeCapacitorCallbackId as In}from"@buoy-gg/license/web";var ce=["undetermined","granted","limited","denied","blocked","restricted"],Tn=["ask","allow","limited","deny"],Ce={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(Ce);function Ie(e){return typeof e=="string"&&(e in Ce||e.startsWith("android:")&&e.length>8)}function R(e){let t=Ce[e];if(t)return t;let n=e.slice(8).replace(/^android\.permission\./,"");return{id:e,label:n.toLowerCase().split("_").map(i=>i.charAt(0).toUpperCase()+i.slice(1)).join(" "),only:"android",purpose:`use ${n.toLowerCase().replace(/_/g," ")}`}}function de(e,t){let n=R(e),i=["undetermined","granted"];return n.limited?.[t]&&i.push("limited"),i.push("denied"),t==="android"&&i.push("blocked"),t==="ios"&&e!=="notifications"&&i.push("restricted"),i}function lt(e,t,n){return de(e,t).includes(n)}function ct(e,t,n){return lt(e,t,n)?n:n==="blocked"?"denied":n==="restricted"?t==="android"?"blocked":"denied":n==="limited"?"granted":n}function dt(e,t){return t==="undetermined"?true:e==="android"&&t==="denied"}function Rn(e,t,n,i){return dt(t,n)?i==="allow"||i==="once"?"granted":i==="limited"?lt(e,t,"limited")?"limited":"granted":t==="android"&&n==="denied"?"blocked":"denied":n}function ut(e,t){return t==="ios"?e==="location":e==="camera"||e==="microphone"}function Nn(e,t){let n=R(e).limited?.[t],i=t==="ios",o=[];if(i&&ut(e,t)&&o.push({answer:"once",label:"Allow Once"}),e==="location"||e==="locationBackground"?o.push({answer:"allow",label:i?"Allow While Using App":"While using the app"}):o.push({answer:"allow",label:"Allow"}),!i&&ut(e,t)&&o.push({answer:"once",label:"Only this time"}),n){let r=e==="location"?i?"Allow With Approximate Location":"Approximate location":e==="photos"?i?"Limit Access\u2026":"Select photos":e==="contacts"?"Select Contacts\u2026":`Allow ${n}`;o.push({answer:"limited",label:r})}return o.push({answer:"deny",label:i?"Don\u2019t Allow":"Don\u2019t allow"}),o}function Ln(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 Dn(e,t){if(!e||typeof e!="object")return null;let n=e,i=typeof n.ios?.status=="number"?n.ios.status:void 0;return i===3||i===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 M(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"}}var qn={location:"location",coarseLocation:"location",camera:"camera",photos:"photos",receive:"notifications",display:"notifications",notifications:"notifications",microphone:"microphone",contacts:"contacts",calendar:"calendar",reminders:"reminders",bluetooth:"bluetooth",motion:"motion",tracking:"tracking"};function G(e){return qn[e]??null}function Te(e,t){switch(e){case"granted":return"granted";case"limited":return"limited";case"prompt":return"undetermined";case"prompt-with-rationale":return t==="android"?"denied":"undetermined";case"denied":return t==="android"?"blocked":"denied";default:return null}}function $n(e,t){switch(e){case"granted":return"granted";case"limited":return"limited";case"undetermined":return"prompt";case"denied":return t==="android"?"prompt-with-rationale":"denied";case"blocked":case"restricted":return"denied"}}function Y(e,t,n){if(e==="location"&&"location"in t){let i=Te(t.location,n),o=Te(t.coarseLocation,n);return i!=="granted"&&o==="granted"?"limited":i}for(let[i,o]of Object.entries(t))if(G(i)===e)return Te(o,n);return null}function pt(e,t,n){let i={...e};for(let o of Object.keys(e)){let r=G(o);if(!r)continue;let s=t(r);s!==null&&(r==="location"&&s==="limited"?i[o]=o==="coarseLocation"||n==="ios"?"granted":"denied":s==="limited"&&r!=="photos"&&r!=="contacts"?i[o]="granted":i[o]=$n(s,n))}return i}import{devToolsStorageKeys as Mn,persistentStorage as mt}from"@buoy-gg/shared-ui/web";function jn(){try{let e=globalThis.localStorage;return e?ht(e.getItem(Re)):void 0}catch{return}}var j={requestAnswer:"ask",persist:true,showChip:true,notifyApp:true,enforce:true,interceptSettings:true},Re=Mn.permissions.state();function J(e,t){return typeof e=="boolean"?e:t}function ft(e){let t=e&&typeof e=="object"?e:{};return{requestAnswer:Tn.includes(t.requestAnswer)?t.requestAnswer:j.requestAnswer,persist:J(t.persist,j.persist),showChip:J(t.showChip,j.showChip),notifyApp:J(t.notifyApp,j.notifyApp),enforce:J(t.enforce,j.enforce),interceptSettings:J(t.interceptSettings,j.interceptSettings)}}function ht(e){if(!e)return null;try{let t=JSON.parse(e);if(!t||t.v!==1)return null;let n={};for(let[i,o]of Object.entries(t.overrides??{}))Ie(i)&&ce.includes(o)&&(n[i]=o);return{v:1,overrides:n,settings:ft(t.settings)}}catch{return null}}async function Un(){try{return ht(await mt.getItem(Re))}catch{return null}}var Ne=Promise.resolve();function gt(e){let t=JSON.stringify(e);return Ne=Ne.then(()=>mt.setItem(Re,t)).catch(()=>{}),Ne.then(()=>{})}var yt=200,Bn=50,bt="__buoyPermissionsStore",wt=globalThis,l=wt[bt]??(wt[bt]={platform:"ios",booted:false,overrides:new Map,settings:{...j},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});l.once??(l.once=new Set);var Z=()=>{let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()};function k(){l.snapshot=null;for(let e of Array.from(l.listeners))try{e()}catch{}}function B(){if(!l.settings.persist){gt({v:1,overrides:{},settings:l.settings});return}gt(_n())}function _n(){return{v:1,overrides:Object.fromEntries(Array.from(l.overrides,([e,t])=>[e,l.once.has(e)?"undetermined":t])),settings:l.settings}}function L(e){let t=l.seen.get(e);return t||(t={sources:new Set,real:null,calls:0,lastCallAt:null,lastReadAt:null,changedAt:null},l.seen.set(e,t)),t}function vt(e){if(e&&(l.settings=e.settings,l.overrides.clear(),!!e.settings.persist))for(let[t,n]of Object.entries(e.overrides)){let i=t;l.overrides.set(i,ct(i,l.platform,n))}}function Le(e){l.platform=e.platform,e.host&&(l.host=e.host),k()}function At(){if(l.booted)return;l.booted=true;let e=jn();if(e!==void 0){vt(e),k();return}Un().then(t=>{l.overrides.size>0||(vt(t),k())})}function zn(e,t){l.realRequesters.has(e)||l.realRequesters.set(e,t)}async function Hn(e){let t=De(e),n=l.realRequesters.get(t);if(!n)throw new Error(`No installed library can ask the system for ${R(t).label}.`);let i=await n();return i!==null&&q(t,i),A()}function St(e){l.prompter=e}function Pt(e){return l.changeHooks.add(e),()=>l.changeHooks.delete(e)}function X(e,t){for(let n of Array.from(l.changeHooks))try{n({id:e,from:t})}catch{}}function ue(e,t){let n=!l.libraries.has(e);l.libraries.add(e);for(let i of t){let o=L(i);o.sources.has(e)||(o.sources.add(e),n=true)}n&&k()}function Q(){return l.platform}function D(){return l.settings}function v(e){return l.overrides.get(e)??null}function Fn(e){return l.overrides.has(e)}function Vn(){return l.overrides.size>0}function q(e,t,n){if(t===null)return;let i=L(e);n&&i.sources.add(n),i.real!==t&&(i.real=t,k())}function I(e){let t={...e,id:l.nextLogId++,at:Z()};if(l.log.unshift(t),l.log.length>yt&&(l.log.length=yt),e.permission){let n=L(e.permission);(e.kind==="check"||e.kind==="request")&&n.sources.add(e.source),n.calls+=1,n.lastCallAt=t.at,(e.kind==="check"||e.kind==="request")&&(n.lastReadAt=t.at),e.real!==null&&e.kind!=="gated"&&(n.real=e.real)}return k(),t}async function xt(e){let t=l.overrides.get(e);if(t===void 0)throw new Error(`${e} is not overridden`);if(!dt(l.platform,t))return{state:t};let n,i=l.settings.requestAnswer;i==="ask"&&l.prompter?n=await l.prompter(e):n=i==="ask"?"allow":i;let o=l.overrides.get(e);if(o===void 0)return{state:t,answer:n};let r=Rn(e,l.platform,o,n);return n==="once"&&r==="granted"&&l.once.add(e),r!==o&&(l.overrides.set(e,r),B(),k(),X(e,"request")),{state:r,answer:n}}function De(e){if(!Ie(e))throw new Error(`Unknown permission "${String(e)}". Use one of: ${Oe.join(", ")}, or android:<android.permission.NAME>.`);return e}function kt(e,t){let n=De(e);if(!ce.includes(t))throw new Error(`Unknown state "${String(t)}". Use one of: ${ce.join(", ")}.`);let i=t,o=de(n,l.platform),r=l.platform==="ios"&&i==="blocked"?"denied":i;if(!o.includes(r))throw new Error(`${R(n).label} can't be "${i}" on ${l.platform}. It can be: ${o.join(", ")}.`);return(l.overrides.get(n)!==r||l.once.has(n))&&(l.overrides.set(n,r),l.once.delete(n),L(n).changedAt=Z(),B(),k(),X(n,"tool")),A()}function Et(e){let t=De(e);return l.overrides.delete(t)&&(l.once.delete(t),L(t).changedAt=Z(),B(),k(),X(t,"tool")),A()}function qe(){if(l.overrides.size>0){let e=Z();for(let t of l.overrides.keys())L(t).changedAt=e;l.overrides.clear(),l.once.clear(),B(),k(),X(null,"tool")}return A()}function Wn(){return Object.fromEntries(l.overrides)}function Kn(e){let t=Z();for(let n of l.overrides.keys())L(n).changedAt=t;l.overrides.clear(),l.once.clear();for(let[n,i]of Object.entries(e)){let o=n;!i||!Ie(o)||(l.overrides.set(o,ct(o,l.platform,i)),L(o).changedAt=t)}return B(),k(),X(null,"tool"),A()}function Ct(e){let t={};for(let[i,o]of Object.entries(e))o!==void 0&&(t[i]=o);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=ft({...l.settings,...t});return l.settings=n,B(),k(),A()}function Gn(){l.log=[];for(let e of l.seen.values())e.calls=0,e.lastCallAt=null;return k(),A()}function Yn(e,t){if(!e||!t)return null;let n=i=>i==="granted"||i==="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 A(){if(l.snapshot)return l.snapshot;let e=new Set([...l.seen.keys(),...l.overrides.keys()]),t=i=>{let o=Oe.indexOf(i);return o===-1?1e3:o},n=Array.from(e).filter(i=>{let o=R(i).only;return!o||o===l.platform}).sort((i,o)=>t(i)-t(o)||i.localeCompare(o)).map(i=>{let o=l.seen.get(i),r=l.overrides.get(i)??null,s=o?.real??null;return{id:i,label:R(i).label,states:de(i,l.platform),override:r,real:s,effective:r??s,sources:o?Array.from(o.sources).sort():[],calls:o?.calls??0,lastCallAt:o?.lastCallAt??null,lastReadAt:o?.lastReadAt??null,changedAt:o?.changedAt??null,stale:o?.changedAt!=null&&o.lastReadAt!=null&&o.lastReadAt<o.changedAt,once:l.once.has(i),warning:Yn(r,s),canRequestReal:l.realRequesters.has(i)}});return l.snapshot={platform:l.platform,host:l.host,libraries:Array.from(l.libraries).sort(),permissions:n,overriddenCount:l.overrides.size,settings:l.settings,log:l.log.slice(0,Bn)},l.snapshot}function ee(e){return l.listeners.add(e),()=>l.listeners.delete(e)}var pe=10,$e=[{plugin:"Geolocation",library:"@capacitor/geolocation",aliases:{location:"location"}},{plugin:"Camera",library:"@capacitor/camera",aliases:{camera:"camera",photos:"photos"}},{plugin:"PushNotifications",library:"@capacitor/push-notifications",aliases:{notifications:"receive"}},{plugin:"LocalNotifications",library:"@capacitor/local-notifications",aliases:{notifications:"display"}}],Jn=[{plugin:"Geolocation",methods:["getCurrentPosition"],permission:()=>"location",message:()=>"Location permission was denied"},{plugin:"Camera",methods:["getPhoto","pickImages","pickLimitedLibraryPhotos"],permission:e=>e.source==="CAMERA"?"camera":"photos",message:e=>e==="camera"?"User denied access to camera":"User denied access to photos"}];function N(e){return $e.find(t=>t.plugin===e)?.library??`Capacitor ${e}`}var Ot=e=>e==="denied"||e==="blocked"||e==="restricted";function me(e){let t=new Set;for(let n of Object.keys(e)){let i=G(n);i&&t.add(i)}return Array.from(t)}function U(e){return e&&typeof e=="object"?e:{}}var It=false;function Zn(){if(It)return true;if(!On())return false;It=true;let e=Q();le({plugin:"*",methods:["checkPermissions"],order:pe,promise:async(t,n)=>{let i=U(await n()),o=me(i);if(o.length===0)return i;for(let r of o){let s=Y(r,i,e);q(r,s,N(t.plugin));let a=v(r);I({source:N(t.plugin),method:`${t.plugin}.checkPermissions`,permission:r,kind:"check",real:s,returned:a??s,overridden:a!==null})}return pt(i,v,e)}}),le({plugin:"*",methods:["requestPermissions"],order:pe,promise:async(t,n)=>{let i=Array.isArray(t.options.permissions)?t.options.permissions.map(String):null,o=u=>{let c=G(u);return c!==null&&v(c)!==null},r=i??Object.keys(U(await K(t.plugin,"checkPermissions").catch(()=>({}))));if(!r.some(o)){let u=U(await n());for(let c of me(u)){let f=Y(c,u,e);q(c,f,N(t.plugin)),I({source:N(t.plugin),method:`${t.plugin}.requestPermissions`,permission:c,kind:"request",real:f,returned:f,overridden:false})}return u}let s=r.filter(u=>!o(u)),a=s.length?U(await K(t.plugin,"requestPermissions",{...t.options,permissions:s})):U(await K(t.plugin,"checkPermissions").catch(()=>({})));for(let u of me(a)){if(v(u)!==null)continue;let c=Y(u,a,e);q(u,c,N(t.plugin)),I({source:N(t.plugin),method:`${t.plugin}.requestPermissions`,permission:u,kind:"request",real:c,returned:c,overridden:false})}let d=new Set;for(let u of r.filter(o)){let c=G(u);if(d.has(c))continue;d.add(c);let{state:f,answer:w}=await xt(c);I({source:N(t.plugin),method:`${t.plugin}.requestPermissions`,permission:c,kind:"request",real:null,returned:f,overridden:true,answer:w})}for(let u of r)u in a||(a={...a,[u]:"prompt"});return pt(a,v,e)}});for(let t of Jn)le({plugin:t.plugin,methods:t.methods,order:pe,promise:(n,i)=>{let o=t.permission(n.options),r=v(o);if(D().enforce&&r==="limited"&&t.plugin==="Geolocation")return i().then(a=>Ee(a));if(!D().enforce||!Ot(r))return i();let s=t.message(o);return I({source:N(t.plugin),method:`${t.plugin}.${n.method}`,permission:o,kind:"gated",real:null,returned:r,overridden:true,error:s}),Promise.reject(new Error(s))}});le({plugin:"Geolocation",methods:["watchPosition"],order:pe,callback:(t,n,i)=>{let o=v("location");if(D().enforce&&o==="limited")return i((s,a)=>n(a?s:Ee(s),a));if(!D().enforce||!Ot(o))return i(n);let r="Location permission was denied";return I({source:N("Geolocation"),method:"Geolocation.watchPosition",permission:"location",kind:"gated",real:null,returned:o,overridden:true,error:r}),setTimeout(()=>n(null,new Error(r)),0),In()}});for(let t of $e){if(!at(t.plugin))continue;let n=Object.keys(t.aliases);ue(t.library,n);for(let i of n){let o=t.aliases[i];zn(i,async()=>{let r=U(await K(t.plugin,"requestPermissions",{permissions:[o]})),s=Y(i,r,e);return I({source:t.library,method:`${t.plugin}.requestPermissions (system)`,permission:i,kind:"request",real:s,returned:s,overridden:false}),s})}}return true}async function Xn(){let e=Q();for(let t of $e)if(at(t.plugin))try{let n=U(await K(t.plugin,"checkPermissions"));for(let i of me(n))q(i,Y(i,n,e),t.library)}catch{}}var Tt={geolocation:"location",camera:"camera",microphone:"microphone",notifications:"notifications",push:"notifications"},Me=e=>e==="denied"||e==="blocked"||e==="restricted";function je(e){return e==="undetermined"?"prompt":Me(e)?"denied":"granted"}function fe(e){return e==="prompt"?"undetermined":e==="granted"?"granted":e==="denied"?"denied":null}var Rt=()=>globalThis.navigator;function Qn(){return{code:1,message:"User denied Geolocation",PERMISSION_DENIED:1,POSITION_UNAVAILABLE:2,TIMEOUT:3}}function ei(e){let t=globalThis.DOMException;return t?new t(e,"NotAllowedError"):Object.assign(new Error(e),{name:"NotAllowedError"})}async function Ue(e){let t=v(e);return t!=="undetermined"?t:(await xt(e)).state}var Be=new Map;function ti(e,t,n){let i=globalThis.EventTarget,o=new i;o.onchange=null,o.name=t,Object.defineProperty(o,"state",{enumerable:true,get:()=>{let a=v(e);return a===null?n?.state??"prompt":je(a)}}),o.addEventListener("change",a=>o.onchange?.(a));let r=globalThis.Event;n?.addEventListener?.("change",()=>{v(e)===null&&r&&o.dispatchEvent(new r("change"))});let s=globalThis.WeakRef;if(s){let a=Be.get(e);a||Be.set(e,a=new Set),a.add(new s(o))}return o}function ni(e){let t=globalThis.Event;if(t){for(let[n,i]of Be)if(!(e!==null&&n!==e))for(let o of i){let r=o.deref();r?r.dispatchEvent(new t("change")):i.delete(o)}}}var Nt=new WeakMap,he=new WeakSet;function te(e,t,n){if(!e)return;let i=e[t];if(typeof i!="function"||he.has(i))return;let o=n(i);he.add(o),Nt.set(o,i);try{e[t]=o}catch{Object.defineProperty(e,t,{configurable:true,writable:true,value:o})}}function _e(){let e=Rt();if(!e)return;e.permissions?.query&&te(e.permissions,"query",o=>async function(r){let s=Tt[String(r?.name)];if(!s)return o.call(this,r);let a=await o.call(this,r).catch(()=>null);a&&q(s,fe(a.state),"navigator.permissions");let d=v(s);return I({source:"navigator.permissions",method:"permissions.query",permission:s,kind:"check",real:a?fe(a.state):null,returned:d??(a?fe(a.state):null),overridden:d!==null}),ti(s,r.name,a)});let t=e.geolocation,n=o=>te(t,o,r=>function(s,a,d){if(v("location")===null||!D().enforce)return r.call(this,s,a,d);let u=0,c=false;if(Ue("location").then(w=>{if(c)return;if(Me(w)){I({source:"navigator.geolocation",method:`geolocation.${o}`,permission:"location",kind:"gated",real:null,returned:w,overridden:true,error:"User denied Geolocation"}),a?.(Qn());return}let P=w==="limited";u=r.call(this,P?V=>s(Ee(V)):s,a,d)}),o!=="watchPosition")return;let f=Math.floor(Math.random()*1e9)+1;return ze.set(f,()=>{c=true,u&&e.geolocation.clearWatch(u)}),f});n("getCurrentPosition"),n("watchPosition"),te(t,"clearWatch",o=>function(r){let s=ze.get(r);if(s){ze.delete(r),s();return}return o.call(this,r)}),te(e.mediaDevices,"getUserMedia",o=>async function(r){let s=[];if(r?.video&&s.push("camera"),r?.audio&&s.push("microphone"),D().enforce)for(let a of s){if(v(a)===null)continue;let d=await Ue(a);if(Me(d))throw I({source:"navigator.mediaDevices",method:"mediaDevices.getUserMedia",permission:a,kind:"gated",real:null,returned:d,overridden:true,error:"Permission denied"}),ei("Permission denied")}return o.call(this,r)});let i=globalThis.Notification;if(i&&!he.has(i)){he.add(i);let o=(()=>{let r=Object.getPrototypeOf(i),s=Object.getOwnPropertyDescriptor(i,"permission")??Object.getOwnPropertyDescriptor(r??{},"permission");return s?.get?String(s.get.call(i)):String(s?.value??"default")})();Object.defineProperty(i,"permission",{configurable:true,get:()=>{let r=v("notifications");if(r===null)return o;let s=je(r);return s==="prompt"?"default":s}}),te(i,"requestPermission",r=>async function(...s){if(v("notifications")===null)return r.apply(this,s);let a=je(await Ue("notifications")??"undetermined"),d=a==="prompt"?"default":a,u=s[0];return typeof u=="function"&&u(d),d})}}var ze=new Map,Lt=false;function ii(){if(Lt)return true;let e=Rt();if(!e)return false;Lt=true,_e(),setTimeout(_e,0),Pt(({id:t})=>{_e(),ni(t??null)}),e.geolocation&&ue("navigator.geolocation",["location"]),e.mediaDevices?.getUserMedia&&ue("navigator.mediaDevices",["camera","microphone"]),globalThis.Notification&&ue("Notification",["notifications"]);for(let[t,n]of Object.entries(Tt))t!=="push"&&Nt.get(e.permissions?.query)?.call(e.permissions,{name:t})?.then(i=>q(n,fe(i.state),"navigator.permissions"))?.catch(()=>{});return true}function ne(e,t,n,i){let o=e.createElement(t);return Object.assign(o.style,n),i!==void 0&&(o.textContent=i),o}var Dt={alert(e,t,n,i){let o=globalThis.document;if(!o?.body){i?.onDismiss?.();return}let r=ne(o,"div",{position:"fixed",inset:"0",zIndex:"2147483000",background:"rgba(0,0,0,0.45)",display:"flex",alignItems:"center",justifyContent:"center",padding:"24px",fontFamily:"-apple-system, system-ui, Roboto, sans-serif"});r.setAttribute("role","alertdialog"),r.setAttribute("data-testid","buoy-permission-prompt");let s=ne(o,"div",{width:"100%",maxWidth:"290px",background:"#f2f2f7",color:"#000",borderRadius:"14px",overflow:"hidden",textAlign:"center"});s.appendChild(ne(o,"div",{padding:"18px 16px 4px",fontWeight:"600",fontSize:"17px",lineHeight:"22px"},e)),t&&s.appendChild(ne(o,"div",{padding:"0 16px 16px",fontSize:"13px",lineHeight:"18px",whiteSpace:"pre-line"},t));let a=false,d=()=>{a=true,r.remove()},u=n?.length?n:[{text:"OK"}];for(let c of u){let f=ne(o,"button",{display:"block",width:"100%",padding:"11px 8px",border:"0",borderTop:"0.5px solid rgba(60,60,67,0.29)",background:"transparent",color:"#007aff",fontSize:"17px",fontWeight:c.style==="cancel"?"600":"400",cursor:"pointer"},c.text);f.addEventListener("click",()=>{a||(d(),c.onPress?.())}),s.appendChild(f)}r.appendChild(s),i?.cancelable&&r.addEventListener("click",c=>{a||c.target!==r||(d(),i.onDismiss?.())}),o.body.appendChild(r)}};var He=null;function Fe(e){He=e&&e.trim()?e.trim():null}function qt(){return He?{name:He}:null}function $t(){let e=qt()?.name;return typeof e=="string"&&e?e:"This app"}var oi={location:{plist:["NSLocationWhenInUseUsageDescription"],plugins:[["expo-location","locationWhenInUsePermission"]]},locationBackground:{plist:["NSLocationAlwaysAndWhenInUseUsageDescription"],plugins:[["expo-location","locationAlwaysAndWhenInUsePermission"]]},camera:{plist:["NSCameraUsageDescription"],plugins:[["expo-camera","cameraPermission"],["expo-image-picker","cameraPermission"]]},microphone:{plist:["NSMicrophoneUsageDescription"],plugins:[["expo-audio","microphonePermission"],["expo-camera","microphonePermission"],["expo-image-picker","microphonePermission"]]},photos:{plist:["NSPhotoLibraryUsageDescription"],plugins:[["expo-image-picker","photosPermission"],["expo-media-library","photosPermission"]]},contacts:{plist:["NSContactsUsageDescription"],plugins:[["expo-contacts","contactsPermission"]]},calendar:{plist:["NSCalendarsFullAccessUsageDescription","NSCalendarsUsageDescription"],plugins:[["expo-calendar","calendarPermission"]]},reminders:{plist:["NSRemindersFullAccessUsageDescription","NSRemindersUsageDescription"],plugins:[["expo-calendar","remindersPermission"]]},tracking:{plist:["NSUserTrackingUsageDescription"],plugins:[["expo-tracking-transparency","userTrackingPermission"]]},motion:{plist:["NSMotionUsageDescription"],plugins:[["expo-sensors","motionPermission"]]},bluetooth:{plist:["NSBluetoothAlwaysUsageDescription"],plugins:[]}};function ri(e){let t=oi[e],n=qt();if(!t||!n)return null;let i=$t(),o=r=>typeof r=="string"&&r.trim()?r.replace(/\$\(PRODUCT_NAME\)/g,i).trim():null;for(let r of t.plist){let s=o(n.ios?.infoPlist?.[r]);if(s)return s}for(let[r,s]of t.plugins)for(let a of n.plugins??[])if(Array.isArray(a)&&a[0]===r&&a[1]&&typeof a[1]=="object"){let d=o(a[1][s]);if(d)return d}return null}var Mt="Test prompt from Buoy. Your phone's settings won't change.",jt=Promise.resolve();function Ut(e){return t=>{let n=()=>new Promise(o=>{let r=Q(),s=R(t),a=$t(),d=r==="ios"?`Allow \u201C${a}\u201D to ${s.purpose}?`:`Allow ${a} to ${s.purpose}?`,u=Nn(t,r),c=false,f=P=>{c||(c=true,o(P))},w=r==="ios"?ri(t):null;e.alert(d,w?`${w}
|
|
2
2
|
|
|
3
|
-
${Mt}`:Mt,u.map(P=>({text:P.label,style:P.answer==="deny"?"cancel":"default",onPress:()=>f(P.answer)})),{cancelable:r==="android",onDismiss:()=>f("deny")})}),i=jt.then(n,n);return jt=i.catch(()=>{}),i}}var ge="__buoyPermissionsInstalled";function si(){ae("App","appStateChange",{isActive:false}),ae("App","pause",{}),setTimeout(()=>{ae("App","resume",{}),ae("App","appStateChange",{isActive:true})},60)}function Ve(){let e=kn(),t=globalThis;if(!e)return ai(t);if(t[ge])return false;t[ge]=true,Le({platform:e,host:{isSimulator:null,deviceName:null,bundleId:null}}),At(),St(Ut(Dt));let n=globalThis.document?.title??null;return Fe(n),En("App")&&xn("App","getInfo").then(i=>Fe(i?.name??n)).catch(()=>{}),Zn()?(Pt(({from:i})=>{i==="tool"&&D().notifyApp&&si()}),Cn().then(i=>{i&&Le({platform:e,host:{isSimulator:i.isSimulator,deviceName:i.deviceName,bundleId:i.bundleId}})}),setTimeout(()=>{Xn()},1500),true):false}function ai(e){return e[ge]||typeof globalThis.document>"u"?false:(e[ge]=true,Le({platform:"android",host:{isSimulator:null,deviceName:null,bundleId:null}}),At(),St(Ut(Dt)),Fe(globalThis.document?.title??null),ii())}import{useEffect as li,useSyncExternalStore as Bt}from"react";var _t={};Sn(_t,{AccessibilityInfo:()=>pi,ActivityIndicator:()=>ho,Alert:()=>bo,Animated:()=>ao,AppRegistry:()=>fi,AppState:()=>hi,Appearance:()=>mi,BackHandler:()=>gi,Button:()=>go,CheckBox:()=>Ri,Clipboard:()=>yi,DeviceEventEmitter:()=>Ki,Dimensions:()=>bi,Easing:()=>wi,FlatList:()=>Ni,I18nManager:()=>vi,Image:()=>Li,ImageBackground:()=>Di,InteractionManager:()=>Si,Keyboard:()=>Ai,KeyboardAvoidingView:()=>qi,LayoutAnimation:()=>Pi,Linking:()=>xi,LogBox:()=>Wi,Modal:()=>mo,NativeEventEmitter:()=>ki,NativeModules:()=>ui,PanResponder:()=>Ei,Picker:()=>$i,PixelRatio:()=>Ci,Platform:()=>zt,Pressable:()=>po,ProgressBar:()=>Mi,RefreshControl:()=>ji,SafeAreaView:()=>Ui,ScrollView:()=>Kt,SectionList:()=>Bi,Share:()=>Oi,StatusBar:()=>_i,StyleSheet:()=>ye,Switch:()=>fo,Text:()=>g,TextInput:()=>lo,Touchable:()=>zi,TouchableHighlight:()=>co,TouchableNativeFeedback:()=>Hi,TouchableOpacity:()=>O,TouchableWithoutFeedback:()=>uo,UIManager:()=>Ii,Vibration:()=>Ti,View:()=>b,VirtualizedList:()=>Fi,YellowBox:()=>Vi,findNodeHandle:()=>yo,unstable_createElement:()=>di,useColorScheme:()=>Gi,useLocaleContext:()=>Yi,useWindowDimensions:()=>Ji});Pn(_t,ci);import*as ci from"react-native-web";import{unstable_createElement as di,NativeModules as ui,AccessibilityInfo as pi,Appearance as mi,AppRegistry as fi,AppState as hi,BackHandler as gi,Clipboard as yi,Dimensions as bi,Easing as wi,I18nManager as vi,Keyboard as Ai,InteractionManager as Si,LayoutAnimation as Pi,Linking as xi,NativeEventEmitter as ki,PanResponder as Ei,PixelRatio as Ci,Platform as zt,Share as Oi,UIManager as Ii,Vibration as Ti,CheckBox as Ri,FlatList as Ni,Image as Li,ImageBackground as Di,KeyboardAvoidingView as qi,Picker as $i,ProgressBar as Mi,RefreshControl as ji,SafeAreaView as Ui,SectionList as Bi,StatusBar as _i,Touchable as zi,TouchableNativeFeedback as Hi,VirtualizedList as Fi,YellowBox as Vi,LogBox as Wi,DeviceEventEmitter as Ki,useColorScheme as Gi,useLocaleContext as Yi,useWindowDimensions as Ji}from"react-native-web";import*as x from"react-native-web";import{createElement as We,forwardRef as Ht,useCallback as Zi,useRef as Xi}from"react";import{useEffect as Qi,useState as eo}from"react";import{createPortal as to}from"react-dom";var no='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';import{jsx as io}from"react/jsx-runtime";var ie=Symbol.for("@buoy-gg/portal-host"),Ft=e=>{if(!(e instanceof Element))return false;if(e.closest("input, textarea, select"))return true;let t=e.closest("[contenteditable]")?.getAttribute("contenteditable")?.toLowerCase();return t===""||t==="true"||t==="plaintext-only"};function Vt(){let e=document;if(e[ie])return e[ie].host;let t=document.createElement("div");t.dataset.buoyPortalHost="",Object.assign(t.style,{position:"fixed",inset:"0",zIndex:"2147483647",pointerEvents:"none",fontFamily:no});let n=()=>{let c=document.fullscreenElement,f=c&&c.tagName!=="CANVAS"?c:document.body;t.parentElement!==f&&f.appendChild(t)},i=new Map,o=c=>{(!t.contains(c.target)||!Ft(c.target))&&i.set(c.code||c.key,{key:c.key,code:c.code,location:c.location,keyCode:c.keyCode,which:c.which,altKey:c.altKey,ctrlKey:c.ctrlKey,metaKey:c.metaKey,shiftKey:c.shiftKey})},r=c=>{i.delete(c.code||c.key)},s=()=>i.clear(),a=()=>{let c=[...i.values()];i.clear();for(let f of c)document.dispatchEvent(new KeyboardEvent("keyup",{...f,bubbles:true}))},d=c=>{Ft(c.target)&&c.stopPropagation()},u=c=>c.stopPropagation();return n(),document.addEventListener("fullscreenchange",n),document.addEventListener("keydown",o,true),document.addEventListener("keyup",r,true),window.addEventListener("blur",s),t.addEventListener("focusin",a),t.addEventListener("keydown",d),t.addEventListener("keyup",d),t.addEventListener("keypress",d),t.addEventListener("wheel",u,{passive:true}),e[ie]={host:t,users:0,dispose:()=>{document.removeEventListener("fullscreenchange",n),document.removeEventListener("keydown",o,true),document.removeEventListener("keyup",r,true),window.removeEventListener("blur",s),t.remove(),delete e[ie]}},t}function oo({children:e}){let[t,n]=eo(null);return Qi(()=>{let i=Vt(),o=document[ie];return o.users++,n(i),()=>{--o.users===0&&o.dispose()}},[]),t?to(io("div",{"data-buoy-root":"",style:{display:"contents",pointerEvents:"auto"},children:e}),t):null}var _=x,ro=["shadowColor","shadowOffset","shadowOpacity","shadowRadius","textShadowColor","textShadowOffset","textShadowRadius"],z=e=>typeof e=="number"?`${e}px`:e;function Ke(e){if(Array.isArray(e)){let f=e.map(Ke);return f.some((w,P)=>w!==e[P])?f:e}if(!e||typeof e!="object"||!ro.some(f=>e[f]!=null))return e;let{shadowColor:t,shadowOffset:n,shadowOpacity:i,shadowRadius:o,textShadowColor:r,textShadowOffset:s,textShadowRadius:a,...d}=e;if(t!=null||n!=null||i!=null||o!=null){let f=t??"black",w=i==null?f:`color-mix(in srgb, ${f} ${Math.min(i,1)*100}%, transparent)`,P=`${z(n?.width??0)} ${z(n?.height??0)} ${z(o??0)} ${w}`;d.boxShadow=typeof d.boxShadow=="string"?`${d.boxShadow}, ${P}`:d.boxShadow??P}let{width:u=0,height:c=0}=s??{};if(r&&(u||c||a)){let f=`${z(u)} ${z(c)} ${z(a??0)} ${r}`;d.textShadow=d.textShadow?`${d.textShadow}, ${f}`:f}return d}var so=_.StyleSheet.create({auto:{pointerEvents:"auto"},none:{pointerEvents:"none"},"box-none":{pointerEvents:"box-none"},"box-only":{pointerEvents:"box-only"}});function Wt(e,t){if(typeof e=="function")return i=>Wt(e(i),t);let n=Ke(e);return t?[n,so[t]]:n}var ye={..._.StyleSheet,create:e=>_.StyleSheet.create(Object.fromEntries(Object.entries(e).map(([t,n])=>[t,Ke(n)])))};function C(e){let t=Ht((i,o)=>{let{accessibilityState:r,accessibilityValue:s,pointerEvents:a,...d}=i;for(let c of["busy","checked","disabled","expanded","selected"])r?.[c]!==void 0&&d[`aria-${c}`]===void 0&&(d[`aria-${c}`]=r[c]);for(let[c,f]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))s?.[c]!==void 0&&d[`aria-${f}`]===void 0&&(d[`aria-${f}`]=s[c]);let u=Wt(d.style,a);return u!==d.style&&(d.style=u),We(e,{...d,ref:o})}),n=e.State;return n&&Object.assign(t,{State:n}),t.displayName=e.displayName??e.name??"NativeWebView",t}var b=C(x.View),g=C(x.Text),ao={..._.Animated,View:_.Animated.createAnimatedComponent(b),Text:_.Animated.createAnimatedComponent(g)},lo=C(x.TextInput),O=C(x.TouchableOpacity),co=C(x.TouchableHighlight),uo=C(x.TouchableWithoutFeedback),po=C(x.Pressable),Kt=C(x.ScrollView),Gt=Ht((e,t)=>{let n=Xi(null),i=Zi(o=>{if(o){let r=o;for(;r.parentElement&&r.parentElement!==document.body;)r=r.parentElement;r.parentElement===document.body&&(n.current=r,Object.assign(r.style,{position:"relative",zIndex:"2147483647",pointerEvents:"auto"}),Vt().appendChild(r))}else n.current&&(document.body.appendChild(n.current),n.current=null);typeof t=="function"?t(o):t&&(t.current=o)},[t]);return We(oo,null,We(x.Modal,{...e,ref:i}))});Gt.displayName="Modal";var mo=C(Gt),fo=C(x.Switch),ho=C(x.ActivityIndicator),go=C(x.Button),yo=x.findNodeHandle,bo={alert(e,t,n,i){if(typeof document>"u")return;let o=document.createElement("dialog");o.dataset.buoyRoot="",o.setAttribute("aria-label",e),o.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 r=document.createElement("h2");if(r.textContent=e,r.style.cssText="font-size:18px;margin:0 0 12px",o.appendChild(r),t){let u=document.createElement("p");u.textContent=t,u.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",o.appendChild(u)}let s=document.createElement("div");s.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let a=n?.length?n:[{text:"OK"}],d=()=>{o.close?.(),o.remove()};for(let u of a){let c=document.createElement("button");c.type="button",c.textContent=u.text??"OK",c.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${u.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,c.onclick=()=>{d(),u.onPress?.()},s.appendChild(c)}o.addEventListener("cancel",u=>{u.preventDefault(),i?.cancelable!==false&&(d(),i?.onDismiss?.())}),o.appendChild(s),document.body.appendChild(o),o.showModal?o.showModal():o.setAttribute("open","")}};import{FloatingTool as Yt,PermissionsIcon as Jt,X as wo,dismissFloatingTool as vo,getFloatingTools as Ao,night as oe,openBuoyTool as So,openFloatingTool as Zt}from"@buoy-gg/shared-ui/web";import{jsx as E,jsxs as Ge}from"react/jsx-runtime";var be="permissions-chip",Po=8e3,Xt={id:be,render:e=>E(tn,{...e})},xo=()=>Ao().some(e=>e.id===be);function ko(){Zt(Xt)}var H=null,Ye=new Set,we=()=>{};function ve(e){H&&clearTimeout(H.timer),H=e;for(let t of Array.from(Ye))t();we()}function Eo(e){return Ye.add(e),()=>{Ye.delete(e)}}var Qt=()=>H;function Co(){ve({overrides:Wn(),timer:setTimeout(()=>ve(null),Po)}),qe()}function Oo(){let e=H;e&&(ve(null),Kn(e.overrides))}var en=false;function Io(){if(en)return;en=true;let e=false;we=()=>{let t=(Vn()||H!==null)&&D().showChip;t&&!e?Zt(Xt):!t&&xo()&&vo(be),e=t},ee(we),we()}function tn({id:e,revealToken:t}){let n=Bt(ee,A,A),i=Bt(Eo,Qt,Qt);li(()=>{i&&n.overriddenCount>0&&ve(null)},[i,n.overriddenCount]);let o=n.permissions.filter(a=>a.override!==null),r=o.length===1?o[0]:null,s=r?`${r.label}: ${r.once&&r.override==="granted"?"Allowed Once":M(r.id,n.platform,r.override)}`:`${o.length} permissions simulated`;return i&&o.length===0?E(Yt,{id:e,revealToken:t,variant:"strip",dragFromSurface:true,defaultPlacement:"top",accessibilityLabel:"Move or hide the permissions strip",handleAdornment:E(Jt,{size:12}),children:Ge(b,{style:T.row,children:[E(g,{style:T.title,numberOfLines:1,testID:"permissions-chip-summary",children:"Real permissions"}),E(O,{testID:"permissions-chip-undo",accessibilityRole:"button",accessibilityLabel:"Undo, put the simulated permissions back",onPress:Oo,style:T.undo,hitSlop:{top:8,bottom:8,left:8,right:8},children:E(g,{style:T.undoText,children:"Undo"})})]})}):E(Yt,{id:e,revealToken:t,variant:"strip",dragFromSurface:true,defaultPlacement:"top",accessibilityLabel:`Move or hide the permissions strip. ${s}`,handleAdornment:E(Jt,{size:12}),children:Ge(b,{style:T.row,children:[Ge(O,{testID:"permissions-chip-open",accessibilityRole:"button",accessibilityLabel:`${s}. Open Permissions`,onPress:()=>{So("permissions")},style:T.open,children:[E(b,{style:T.dot}),E(g,{style:T.title,numberOfLines:1,testID:"permissions-chip-summary",children:s})]}),E(b,{style:T.separator}),E(O,{testID:"permissions-chip-reset",accessibilityRole:"button",accessibilityLabel:"Use real permissions",onPress:Co,style:T.button,hitSlop:{top:8,bottom:8,left:4,right:8},children:E(wo,{size:16,color:oe.color.textSecondary})})]})})}var T=ye.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:oe.color.accent},title:{color:oe.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:oe.color.accent,fontSize:14,fontWeight:"600"},separator:{width:ye.hairlineWidth,height:20,backgroundColor:oe.color.separator}});import{PermissionsIcon as To,PERMISSIONS_ICON_COLOR as Ro,createToolFactory as No,defineToolPreset as Lo}from"@buoy-gg/shared-ui/web";import{useEffect as Do,useState as qo,useSyncExternalStore as $o}from"react";import{capacitorPlatform as Mo}from"@buoy-gg/license/web";import{reloadApp as jo}from"@buoy-gg/shared-ui/web";var Je={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"}},nn={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"}},Uo=[{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",...Je},{method:"getLastKnownPositionAsync",permission:"location",...Je},{method:"watchPositionImplAsync",permission:"location",...Je},{method:"startGeofencingAsync",permission:"locationBackground",...nn},{method:"startLocationUpdatesAsync",permission:"locationBackground",...nn}]},{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 Bo(){let e=globalThis.expo?.modules;return e&&typeof e=="object"?e:null}function _o(e){try{return new Set(Object.keys(e))}catch{return new Set}}function zo(e,t=[]){return e.flavor!=="privileges"?[]:t.length>0?t.slice(0,1):[false]}async function on(){let e=Bo();if(!e)return;let t=_o(e),n=Q(),i=[];for(let o of Uo){if(!t.has(o.module))continue;let r=e[o.module];if(!r)continue;let s=new Set;for(let a of o.permissions){if(s.has(a.permission))continue;let d=r[a.get],u=d?.__buoyPermissionsOriginal??d;typeof u=="function"&&(s.add(a.permission),i.push(Promise.resolve().then(()=>u.apply(r,zo(a))).then(c=>q(a.permission,Dn(c,n),o.library)).catch(()=>{})))}}await Promise.all(i)}import{createSyncAdapter as Ho}from"@buoy-gg/shared-ui/web";import{BUOY_SYNTHETIC_MARK as Fo}from"@buoy-gg/shared-ui/web";var rn=null;function Ze(e){try{rn?.emit("appStateDidChange",{app_state:e,[Fo]:true})}catch{}}function Vo(){Q()==="ios"&&Ze("inactive"),Ze("background")}function Wo(){Ze("active")}var Ae=null,sn=false,an=null;function Ko(){return sn}function Se(){return an?(an(),true):false}function Go(){!rn||sn||(Ae&&clearTimeout(Ae),Ae=setTimeout(()=>{Ae=null,Vo(),setTimeout(Wo,60)},120))}function Pe(e){return e&&typeof e=="object"?e:{}}function Xe(e){return e.permission??e.id??e.permissionId??e.name}function re(e,t){let n=e[t];if(typeof n=="boolean")return n;if(n==="true")return true;if(n==="false")return false}var ln=Ho({version:1,getSnapshot(){return A()},subscribe(e){return ee(e)},actions:{async getState(){return await on(),Ko()?{...A(),settingsStandInOpen:true}:A()},setOverride(e){let t=Pe(e),n=Xe(t),i=t.state??t.status??t.value;if(n===void 0||i===void 0)throw new Error('setOverride needs `permission` (e.g. "location", "camera", "notifications") and `state` ("undetermined", "granted", "limited", "denied", "blocked" or "restricted").');return Se(),kt(n,i)},clearOverride(e){let t=Xe(Pe(e));if(t===void 0)throw new Error("clearOverride needs `permission`.");return Se(),Et(t)},requestReal(e){let t=Xe(Pe(e));if(t===void 0)throw new Error("requestReal needs `permission`.");return Hn(t)},resetAll(){return Se(),qe()},updateSettings(e){let t=Pe(e);return Ct({requestAnswer:t.requestAnswer??t.answer,persist:re(t,"persist"),showChip:re(t,"showChip"),notifyApp:re(t,"notifyApp"),enforce:re(t,"enforce"),interceptSettings:re(t,"interceptSettings")})},clearLog(){return Gn()},simulateReturnFromSettings(){return Se()||Go(),A()}}});import{useEffect as Yo,useReducer as Jo,useState as cn}from"react";import{Check as Zo,ChevronLeft as Xo,ChevronRight as dn,NightCard as $,NightFootnote as F,NightRows as Qe,NightSectionLabel as un,night as m,useSafeAreaInsets as Qo,useToolScreenHeader as er}from"@buoy-gg/shared-ui/web";import{Fragment as pn,jsx as p,jsxs as y}from"react/jsx-runtime";var et=1500,tr=()=>{let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()};function nr(e,t){return e.effective?e.once&&e.effective==="granted"?"Allowed Once":M(e.id,t,e.effective):"Not Checked"}function mn({snapshot:e,onAction:t,onReload:n,browserOnly:i}){let o=Qo({minBottom:16}),[r,s]=cn(null),[a,d]=cn({name:"list"}),u=(S,xe)=>{s(null),t(S,xe).catch(ke=>{s(ke instanceof Error?ke.message:String(ke))})},c=a.name==="detail"?e?.permissions.find(S=>S.id===a.id):void 0,f=()=>d(a.name==="detail"&&a.from==="other"?{name:"other"}:{name:"list"}),w=a.name==="other"?"Other Permissions":c?c.label:null,P=er(w?{title:w,onBack:f,searchable:false}:null,[w,a.name,a.name==="detail"?a.from:null]);if(!e)return p(b,{style:h.waiting,testID:"permissions-waiting",children:p(F,{centered:true,children:"Waiting for the app\u2026"})});let{platform:V,permissions:tt}=e,nt=tt.filter(S=>S.calls>0||S.override!==null),se=tt.filter(S=>!(S.calls>0||S.override!==null)),it=(S,xe)=>d({name:"detail",id:S,from:xe}),W;return i?W=p($,{padded:true,children:p(g,{style:h.empty,testID:"permissions-browser-only",children:"This app runs in a plain browser. The browser keeps its own permissions. Buoy can't change them here. This tool works when the app runs on a phone with Capacitor."})}):a.name==="detail"&&c?W=p(rr,{row:c,platform:V,log:e.log,run:u,onPicked:f}):a.name==="other"?W=y(b,{children:[p(fn,{rows:se,platform:V,onOpen:S=>it(S,"other")}),p(F,{children:"Your app can ask for these but hasn't yet."})]}):W=y(pn,{children:[nt.length>0?p(fn,{rows:nt,platform:V,onOpen:S=>it(S,"list"),onReload:n}):p($,{padded:true,children:p(g,{style:h.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."})}),se.length>0?p($,{children:y(O,{testID:"permissions-other",accessibilityRole:"button",accessibilityLabel:`Other Permissions, ${se.length}`,activeOpacity:.6,onPress:()=>d({name:"other"}),style:h.row,children:[p(g,{style:h.rowTitle,children:"Other Permissions"}),y(b,{style:h.rowRight,children:[p(g,{style:h.rowValue,children:se.length}),p(dn,{size:16,color:m.color.textTertiary})]})]})}):null,e.overriddenCount>0?p($,{children:p(O,{testID:"permissions-reset",accessibilityRole:"button",accessibilityLabel:"Use Real Permissions",activeOpacity:.6,onPress:()=>u("resetAll"),style:h.row,children:p(g,{style:h.destructive,children:"Use Real Permissions"})})}):null]}),y(Kt,{style:h.fill,contentContainerStyle:[h.content,{paddingBottom:o.bottom}],testID:"permissions-scroll",children:[!P&&a.name!=="list"?y(O,{testID:"permissions-back",accessibilityRole:"button",accessibilityLabel:"Back",onPress:f,style:h.inlineBack,children:[p(Xo,{size:18,color:m.color.accent}),p(g,{style:h.inlineBackText,children:a.name==="detail"&&a.from==="other"?"Other Permissions":"Permissions"}),w?p(g,{style:h.inlineTitle,children:w}):null]}):null,r?p(F,{tone:"danger",centered:true,children:p(g,{testID:"permissions-error",children:r})}):null,W]})}function fn({rows:e,platform:t,onOpen:n,onReload:i}){let[,o]=Jo(d=>d+1,0),r=tr(),s=e.filter(d=>d.stale&&d.changedAt!==null&&r-d.changedAt<et).map(d=>et-(r-d.changedAt)),a=s.length>0?Math.min(...s):null;return Yo(()=>{if(a===null)return;let d=setTimeout(o,a+50);return()=>clearTimeout(d)},[a]),p($,{children:p(Qe,{children:e.map(d=>{let u=d.stale&&d.changedAt!==null&&r-d.changedAt>=et;return y(b,{children:[p(ir,{row:d,platform:t,onPress:()=>n(d.id)}),u?y(b,{style:h.stale,testID:`permissions-stale-${d.id}`,children:[p(g,{style:h.staleText,children:"The app hasn't checked again since this changed."}),i?p(O,{testID:`permissions-reload-${d.id}`,accessibilityRole:"button",accessibilityLabel:"Reload App",onPress:i,hitSlop:{top:8,bottom:8,left:8,right:8},children:p(g,{style:h.staleAction,children:"Reload App"})}):null]}):null]},d.id)})})})}function ir({row:e,platform:t,onPress:n}){let i=e.override!==null,o=nr(e,t),r=e.real?M(e.id,t,e.real):"Not Checked";return y(O,{testID:`permissions-row-${e.id}`,accessibilityRole:"button",accessibilityLabel:`${e.label}: ${o}${i?`, simulated. Phone: ${r}`:""}`,activeOpacity:.6,onPress:n,style:h.row,children:[y(b,{style:h.rowLeft,children:[p(g,{style:h.rowTitle,children:e.label}),i?y(g,{style:h.rowSub,testID:`permissions-phone-${e.id}`,children:["Phone: ",r]}):null]}),y(b,{style:h.rowRight,children:[i?p(b,{style:h.dot}):null,p(g,{style:[h.rowValue,i?h.rowValueSimulated:null],testID:`permissions-value-${e.id}`,numberOfLines:1,children:o}),p(dn,{size:16,color:m.color.textTertiary})]})]})}function hn({title:e,detail:t,selected:n,testID:i,onPress:o}){return y(O,{testID:i,accessibilityRole:"button",accessibilityLabel:`${e}. ${t}`,accessibilityState:{selected:n},activeOpacity:.6,onPress:o,style:h.option,children:[y(b,{style:h.optionText,children:[p(g,{style:h.rowTitle,children:e}),p(g,{style:h.optionDetail,children:t})]}),p(b,{style:h.check,children:n?p(Zo,{size:18,color:m.color.accent}):null})]})}var or={check:"Checked",request:"Asked",settings:"Opened Settings",gated:"Needed it"};function rr({row:e,platform:t,log:n,run:i,onPicked:o}){let r=e.real?M(e.id,t,e.real):null,s=u=>{u===null?i("clearOverride",{permission:e.id}):i("setOverride",{permission:e.id,state:u}),o()},a=n.filter(u=>u.permission===e.id).slice(0,8),d=e.canRequestReal&&e.real==="undetermined";return y(pn,{children:[y(b,{children:[p(un,{children:"What the app sees"}),p($,{children:y(Qe,{children:[p(hn,{title:"Phone's Setting",detail:r?`Use what the phone says: ${r}.`:"Use what the phone says.",selected:e.override===null,testID:`permissions-state-${e.id}-real`,onPress:()=>s(null)},"real"),e.states.map(u=>p(hn,{title:M(e.id,t,u),detail:Ln(e.id,t,u),selected:e.override===u,testID:`permissions-state-${e.id}-${u}`,onPress:()=>s(u)},u))]})})]}),d?y(b,{children:[p($,{children:p(O,{testID:`permissions-request-real-${e.id}`,accessibilityRole:"button",accessibilityLabel:`Show the real system prompt for ${e.label}`,activeOpacity:.6,onPress:()=>i("requestReal",{permission:e.id}),style:h.row,children:p(g,{style:h.action,children:"Show Real Prompt"})})}),p(F,{children:e.warning??"Asks the phone for real, so calls that need this permission work."})]}):e.warning?p(F,{tone:"warning",children:p(g,{testID:`permissions-warning-${e.id}`,children:e.warning})}):null,a.length>0?y(b,{children:[p(un,{children:"Recent"}),p($,{children:p(Qe,{children:a.map(u=>p(ar,{entry:u,platform:t},u.id))})}),e.sources.length>0?y(F,{children:["Read through ",e.sources.join(", ")]}):null]}):null]})}function sr(e){let t=new Date(e),n=i=>String(i).padStart(2,"0");return`${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`}function ar({entry:e,platform:t}){let n=e.error?"Failed":e.returned&&e.permission?e.answer==="once"&&e.returned==="granted"?"Allowed Once":M(e.permission,t,e.returned):"";return y(b,{style:h.recentRow,testID:`permissions-log-${e.id}`,children:[p(g,{style:h.recentTime,children:sr(e.at)}),p(g,{style:h.recentVerb,numberOfLines:1,children:or[e.kind]}),p(g,{style:[h.recentResult,e.error?h.recentFailed:null],numberOfLines:1,children:n})]})}var h=ye.create({fill:{flex:1},content:{paddingHorizontal:m.gutter,paddingTop:12,gap:m.groupGap},waiting:{flex:1,alignItems:"center",justifyContent:"center",padding:24},empty:{color:m.color.textSecondary,fontSize:m.font.body,lineHeight:20},row:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:50,paddingHorizontal:m.rowPadH,paddingVertical:10},rowLeft:{flexShrink:1,gap:2},rowTitle:{color:m.color.text,fontSize:m.font.row},rowSub:{color:m.color.textTertiary,fontSize:m.font.caption},rowRight:{flexDirection:"row",alignItems:"center",gap:6,flexShrink:1},rowValue:{color:m.color.textSecondary,fontSize:m.font.row},rowValueSimulated:{color:m.color.accent},dot:{width:7,height:7,borderRadius:4,backgroundColor:m.color.accent},stale:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",columnGap:10,rowGap:4,paddingHorizontal:m.rowPadH,paddingBottom:12,marginTop:-4},staleText:{color:m.color.textSecondary,fontSize:m.font.caption,flexShrink:1},staleAction:{color:m.color.accent,fontSize:m.font.caption,fontWeight:"600"},destructive:{color:m.color.danger,fontSize:m.font.row},action:{color:m.color.accent,fontSize:m.font.row},option:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:m.rowPadH,paddingVertical:11,minHeight:50},optionText:{flex:1,gap:2},optionDetail:{color:m.color.textTertiary,fontSize:m.font.caption,lineHeight:17},check:{width:20,alignItems:"center"},inlineBack:{flexDirection:"row",alignItems:"center",gap:4,marginBottom:-8},inlineBackText:{color:m.color.accent,fontSize:m.font.row},inlineTitle:{color:m.color.text,fontSize:m.font.row,fontWeight:"600",marginLeft:"auto"},recentRow:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:m.rowPadH,paddingVertical:10},recentTime:{color:m.color.textTertiary,fontSize:m.font.caption,fontVariant:["tabular-nums"]},recentVerb:{color:m.color.text,fontSize:m.font.body,flex:1},recentResult:{color:m.color.textSecondary,fontSize:m.font.body},recentFailed:{color:m.color.danger}});import{jsx as lr}from"react/jsx-runtime";var cr=ln.actions;async function dr(e,t){let n=cr[e];if(!n)throw new Error(`Unknown permissions action: ${e}`);return n(t)}function ur(){jo("auto","buoy permissions").catch(()=>{})}function gn(){let[e]=qo(()=>zt.OS==="web"&&!Mo());Do(()=>{Ve(),on()},[]);let t=$o(ee,A,A);return lr(mn,{snapshot:t,onAction:dr,onReload:ur,browserOnly:e})}import{jsx as pr}from"react/jsx-runtime";var yn=Lo({id:"permissions",name:"PERMISSIONS",description:"Test denied, blocked, limited and not-asked permission states",slot:"both",color:Ro,icon:({size:e,color:t})=>pr(To,{size:e,color:t}),component:gn,modal:{subtitle:"choose what the app is allowed to do"}}),mr=No(yn);import{PermissionsIcon as fr,PERMISSIONS_ICON_COLOR as hr}from"@buoy-gg/shared-ui/web";var bn=typeof navigator<"u"&&navigator.product==="ReactNative",gr=(()=>{try{return globalThis.Capacitor?.isNativePlatform?.()===true}catch{return false}})(),yr=!bn&&typeof globalThis.document<"u";(bn||gr||yr)&&typeof st<"u"&&st&&(Ve(),Io());export{Oe as KNOWN_PERMISSION_IDS,be as PERMISSIONS_CHIP_ID,hr as PERMISSIONS_ICON_COLOR,ce as PERMISSION_STATES,gn as PermissionsBody,tn as PermissionsChip,fr as PermissionsIcon,mn as PermissionsToolView,Et as clearPermissionOverride,mr as createPermissionsTool,v as getPermissionOverride,A as getPermissionsSnapshot,Ve as installPermissions,Fn as isPermissionOverridden,ko as openPermissionsChip,R as permissionInfo,ln as permissionsSyncAdapter,yn as permissionsToolPreset,qe as resetPermissions,kt as setPermissionOverride,M as stateLabel,ee as subscribePermissions,de as supportedStates,Ct as updatePermissionSettings};
|
|
3
|
+
${Mt}`:Mt,u.map(P=>({text:P.label,style:P.answer==="deny"?"cancel":"default",onPress:()=>f(P.answer)})),{cancelable:r==="android",onDismiss:()=>f("deny")})}),i=jt.then(n,n);return jt=i.catch(()=>{}),i}}var ge="__buoyPermissionsInstalled";function si(){ae("App","appStateChange",{isActive:false}),ae("App","pause",{}),setTimeout(()=>{ae("App","resume",{}),ae("App","appStateChange",{isActive:true})},60)}function Ve(){let e=kn(),t=globalThis;if(!e)return ai(t);if(t[ge])return false;t[ge]=true,Le({platform:e,host:{isSimulator:null,deviceName:null,bundleId:null}}),At(),St(Ut(Dt));let n=globalThis.document?.title??null;return Fe(n),En("App")&&xn("App","getInfo").then(i=>Fe(i?.name??n)).catch(()=>{}),Zn()?(Pt(({from:i})=>{i==="tool"&&D().notifyApp&&si()}),Cn().then(i=>{i&&Le({platform:e,host:{isSimulator:i.isSimulator,deviceName:i.deviceName,bundleId:i.bundleId}})}),setTimeout(()=>{Xn()},1500),true):false}function ai(e){return e[ge]||typeof globalThis.document>"u"?false:(e[ge]=true,Le({platform:"android",host:{isSimulator:null,deviceName:null,bundleId:null}}),At(),St(Ut(Dt)),Fe(globalThis.document?.title??null),ii())}import{useEffect as li,useSyncExternalStore as Bt}from"react";var _t={};Sn(_t,{AccessibilityInfo:()=>pi,ActivityIndicator:()=>ho,Alert:()=>bo,Animated:()=>ao,AppRegistry:()=>fi,AppState:()=>hi,Appearance:()=>mi,BackHandler:()=>gi,Button:()=>go,CheckBox:()=>Ri,Clipboard:()=>yi,DeviceEventEmitter:()=>Ki,Dimensions:()=>bi,Easing:()=>wi,FlatList:()=>Ni,I18nManager:()=>vi,Image:()=>Li,ImageBackground:()=>Di,InteractionManager:()=>Si,Keyboard:()=>Ai,KeyboardAvoidingView:()=>qi,LayoutAnimation:()=>Pi,Linking:()=>xi,LogBox:()=>Wi,Modal:()=>mo,NativeEventEmitter:()=>ki,NativeModules:()=>ui,PanResponder:()=>Ei,Picker:()=>$i,PixelRatio:()=>Ci,Platform:()=>zt,Pressable:()=>po,ProgressBar:()=>Mi,RefreshControl:()=>ji,SafeAreaView:()=>Ui,ScrollView:()=>Kt,SectionList:()=>Bi,Share:()=>Oi,StatusBar:()=>_i,StyleSheet:()=>ye,Switch:()=>fo,Text:()=>g,TextInput:()=>lo,Touchable:()=>zi,TouchableHighlight:()=>co,TouchableNativeFeedback:()=>Hi,TouchableOpacity:()=>O,TouchableWithoutFeedback:()=>uo,UIManager:()=>Ii,Vibration:()=>Ti,View:()=>b,VirtualizedList:()=>Fi,YellowBox:()=>Vi,findNodeHandle:()=>yo,unstable_createElement:()=>di,useColorScheme:()=>Gi,useLocaleContext:()=>Yi,useWindowDimensions:()=>Ji});Pn(_t,ci);import*as ci from"react-native-web";import{unstable_createElement as di,NativeModules as ui,AccessibilityInfo as pi,Appearance as mi,AppRegistry as fi,AppState as hi,BackHandler as gi,Clipboard as yi,Dimensions as bi,Easing as wi,I18nManager as vi,Keyboard as Ai,InteractionManager as Si,LayoutAnimation as Pi,Linking as xi,NativeEventEmitter as ki,PanResponder as Ei,PixelRatio as Ci,Platform as zt,Share as Oi,UIManager as Ii,Vibration as Ti,CheckBox as Ri,FlatList as Ni,Image as Li,ImageBackground as Di,KeyboardAvoidingView as qi,Picker as $i,ProgressBar as Mi,RefreshControl as ji,SafeAreaView as Ui,SectionList as Bi,StatusBar as _i,Touchable as zi,TouchableNativeFeedback as Hi,VirtualizedList as Fi,YellowBox as Vi,LogBox as Wi,DeviceEventEmitter as Ki,useColorScheme as Gi,useLocaleContext as Yi,useWindowDimensions as Ji}from"react-native-web";import*as x from"react-native-web";import{createElement as We,forwardRef as Ht,useCallback as Zi,useRef as Xi}from"react";import{useEffect as Qi,useState as eo}from"react";import{createPortal as to}from"react-dom";var no='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';import{jsx as io}from"react/jsx-runtime";var ie=Symbol.for("@buoy-gg/portal-host"),Ft=e=>{if(!(e instanceof Element))return false;if(e.closest("input, textarea, select"))return true;let t=e.closest("[contenteditable]")?.getAttribute("contenteditable")?.toLowerCase();return t===""||t==="true"||t==="plaintext-only"};function Vt(){let e=document;if(e[ie])return e[ie].host;let t=document.createElement("div");t.dataset.buoyPortalHost="",Object.assign(t.style,{position:"fixed",inset:"0",zIndex:"2147483647",pointerEvents:"none",fontFamily:no});let n=()=>{let c=document.fullscreenElement,f=c&&c.tagName!=="CANVAS"?c:document.body;t.parentElement!==f&&f.appendChild(t)},i=new Map,o=c=>{(!t.contains(c.target)||!Ft(c.target))&&i.set(c.code||c.key,{key:c.key,code:c.code,location:c.location,keyCode:c.keyCode,which:c.which,altKey:c.altKey,ctrlKey:c.ctrlKey,metaKey:c.metaKey,shiftKey:c.shiftKey})},r=c=>{i.delete(c.code||c.key)},s=()=>i.clear(),a=()=>{let c=[...i.values()];i.clear();for(let f of c)document.dispatchEvent(new KeyboardEvent("keyup",{...f,bubbles:true}))},d=c=>{Ft(c.target)&&c.stopPropagation()},u=c=>c.stopPropagation();return n(),document.addEventListener("fullscreenchange",n),document.addEventListener("keydown",o,true),document.addEventListener("keyup",r,true),window.addEventListener("blur",s),t.addEventListener("focusin",a),t.addEventListener("keydown",d),t.addEventListener("keyup",d),t.addEventListener("keypress",d),t.addEventListener("wheel",u,{passive:true}),e[ie]={host:t,users:0,dispose:()=>{document.removeEventListener("fullscreenchange",n),document.removeEventListener("keydown",o,true),document.removeEventListener("keyup",r,true),window.removeEventListener("blur",s),t.remove(),delete e[ie]}},t}function oo({children:e}){let[t,n]=eo(null);return Qi(()=>{let i=Vt(),o=document[ie];return o.users++,n(i),()=>{--o.users===0&&o.dispose()}},[]),t?to(io("div",{"data-buoy-root":"",style:{display:"contents",pointerEvents:"auto"},children:e}),t):null}var _=x,ro=["shadowColor","shadowOffset","shadowOpacity","shadowRadius","textShadowColor","textShadowOffset","textShadowRadius"],z=e=>typeof e=="number"?`${e}px`:e;function Ke(e){if(Array.isArray(e)){let f=e.map(Ke);return f.some((w,P)=>w!==e[P])?f:e}if(!e||typeof e!="object"||!ro.some(f=>e[f]!=null))return e;let{shadowColor:t,shadowOffset:n,shadowOpacity:i,shadowRadius:o,textShadowColor:r,textShadowOffset:s,textShadowRadius:a,...d}=e;if(t!=null||n!=null||i!=null||o!=null){let f=t??"black",w=i==null?f:`color-mix(in srgb, ${f} ${Math.min(i,1)*100}%, transparent)`,P=`${z(n?.width??0)} ${z(n?.height??0)} ${z(o??0)} ${w}`;d.boxShadow=typeof d.boxShadow=="string"?`${d.boxShadow}, ${P}`:d.boxShadow??P}let{width:u=0,height:c=0}=s??{};if(r&&(u||c||a)){let f=`${z(u)} ${z(c)} ${z(a??0)} ${r}`;d.textShadow=d.textShadow?`${d.textShadow}, ${f}`:f}return d}var so=_.StyleSheet.create({auto:{pointerEvents:"auto"},none:{pointerEvents:"none"},"box-none":{pointerEvents:"box-none"},"box-only":{pointerEvents:"box-only"}});function Wt(e,t){if(typeof e=="function")return i=>Wt(e(i),t);let n=Ke(e);return t?[n,so[t]]:n}var ye={..._.StyleSheet,create:e=>_.StyleSheet.create(Object.fromEntries(Object.entries(e).map(([t,n])=>[t,Ke(n)])))};function C(e){let t=Ht((i,o)=>{let{accessibilityState:r,accessibilityValue:s,pointerEvents:a,...d}=i;for(let c of["busy","checked","disabled","expanded","selected"])r?.[c]!==void 0&&d[`aria-${c}`]===void 0&&(d[`aria-${c}`]=r[c]);for(let[c,f]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))s?.[c]!==void 0&&d[`aria-${f}`]===void 0&&(d[`aria-${f}`]=s[c]);let u=Wt(d.style,a);return u!==d.style&&(d.style=u),We(e,{...d,ref:o})}),n=e.State;return n&&Object.assign(t,{State:n}),t.displayName=e.displayName??e.name??"NativeWebView",t}var b=C(x.View),g=C(x.Text),ao={..._.Animated,View:_.Animated.createAnimatedComponent(b),Text:_.Animated.createAnimatedComponent(g)},lo=C(x.TextInput),O=C(x.TouchableOpacity),co=C(x.TouchableHighlight),uo=C(x.TouchableWithoutFeedback),po=C(x.Pressable),Kt=C(x.ScrollView),Gt=Ht((e,t)=>{let n=Xi(null),i=Zi(o=>{if(o){let r=o;for(;r.parentElement&&r.parentElement!==document.body;)r=r.parentElement;r.parentElement===document.body&&(n.current=r,Object.assign(r.style,{position:"relative",zIndex:"2147483647",pointerEvents:"auto"}),Vt().appendChild(r))}else n.current&&(document.body.appendChild(n.current),n.current=null);typeof t=="function"?t(o):t&&(t.current=o)},[t]);return We(oo,null,We(x.Modal,{...e,ref:i}))});Gt.displayName="Modal";var mo=C(Gt),fo=C(x.Switch),ho=C(x.ActivityIndicator),go=C(x.Button),yo=x.findNodeHandle,bo={alert(e,t,n,i){if(typeof document>"u")return;let o=document.createElement("dialog");o.dataset.buoyRoot="",o.setAttribute("aria-label",e),o.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 r=document.createElement("h2");if(r.textContent=e,r.style.cssText="font-size:18px;margin:0 0 12px",o.appendChild(r),t){let u=document.createElement("p");u.textContent=t,u.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",o.appendChild(u)}let s=document.createElement("div");s.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let a=n?.length?n:[{text:"OK"}],d=()=>{o.close?.(),o.remove()};for(let u of a){let c=document.createElement("button");c.type="button",c.textContent=u.text??"OK",c.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${u.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,c.onclick=()=>{d(),u.onPress?.()},s.appendChild(c)}o.addEventListener("cancel",u=>{u.preventDefault(),i?.cancelable!==false&&(d(),i?.onDismiss?.())}),o.appendChild(s),document.body.appendChild(o),o.showModal?o.showModal():o.setAttribute("open","")}};import{FloatingTool as Yt,PermissionsIcon as Jt,X as wo,dismissFloatingTool as vo,getFloatingTools as Ao,night as oe,openBuoyTool as So,openFloatingTool as Zt}from"@buoy-gg/shared-ui/web";import{jsx as E,jsxs as Ge}from"react/jsx-runtime";var be="permissions-chip",Po=8e3,Xt={id:be,render:e=>E(tn,{...e})},xo=()=>Ao().some(e=>e.id===be);function ko(){Zt(Xt)}var H=null,Ye=new Set,we=()=>{};function ve(e){H&&clearTimeout(H.timer),H=e;for(let t of Array.from(Ye))t();we()}function Eo(e){return Ye.add(e),()=>{Ye.delete(e)}}var Qt=()=>H;function Co(){ve({overrides:Wn(),timer:setTimeout(()=>ve(null),Po)}),qe()}function Oo(){let e=H;e&&(ve(null),Kn(e.overrides))}var en=false;function Io(){if(en)return;en=true;let e=false;we=()=>{let t=(Vn()||H!==null)&&D().showChip;t&&!e?Zt(Xt):!t&&xo()&&vo(be),e=t},ee(we),we()}function tn({id:e,revealToken:t}){let n=Bt(ee,A,A),i=Bt(Eo,Qt,Qt);li(()=>{i&&n.overriddenCount>0&&ve(null)},[i,n.overriddenCount]);let o=n.permissions.filter(a=>a.override!==null),r=o.length===1?o[0]:null,s=r?`${r.label}: ${r.once&&r.override==="granted"?"Allowed Once":M(r.id,n.platform,r.override)}`:`${o.length} permissions simulated`;return i&&o.length===0?E(Yt,{id:e,revealToken:t,variant:"strip",dragFromSurface:true,defaultPlacement:"top",accessibilityLabel:"Move or hide the permissions strip",handleAdornment:E(Jt,{size:12}),children:Ge(b,{style:T.row,children:[E(g,{style:T.title,numberOfLines:1,testID:"permissions-chip-summary",children:"Real permissions"}),E(O,{testID:"permissions-chip-undo",accessibilityRole:"button",accessibilityLabel:"Undo, put the simulated permissions back",onPress:Oo,style:T.undo,hitSlop:{top:8,bottom:8,left:8,right:8},children:E(g,{style:T.undoText,children:"Undo"})})]})}):E(Yt,{id:e,revealToken:t,variant:"strip",dragFromSurface:true,defaultPlacement:"top",accessibilityLabel:`Move or hide the permissions strip. ${s}`,handleAdornment:E(Jt,{size:12}),children:Ge(b,{style:T.row,children:[Ge(O,{testID:"permissions-chip-open",accessibilityRole:"button",accessibilityLabel:`${s}. Open Permissions`,onPress:()=>{So("permissions")},style:T.open,children:[E(b,{style:T.dot}),E(g,{style:T.title,numberOfLines:1,testID:"permissions-chip-summary",children:s})]}),E(b,{style:T.separator}),E(O,{testID:"permissions-chip-reset",accessibilityRole:"button",accessibilityLabel:"Use real permissions",onPress:Co,style:T.button,hitSlop:{top:8,bottom:8,left:4,right:8},children:E(wo,{size:16,color:oe.color.textSecondary})})]})})}var T=ye.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:oe.color.accent},title:{color:oe.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:oe.color.accent,fontSize:14,fontWeight:"600"},separator:{width:ye.hairlineWidth,height:20,backgroundColor:oe.color.separator}});import{PermissionsIcon as To,PERMISSIONS_ICON_COLOR as Ro,createToolFactory as No,defineToolPreset as Lo}from"@buoy-gg/shared-ui/web";import{useEffect as Do,useState as qo,useSyncExternalStore as $o}from"react";import{capacitorPlatform as Mo}from"@buoy-gg/license/web";import{reloadApp as jo}from"@buoy-gg/shared-ui/web";var Je={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"}},nn={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"}},Uo=[{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",...Je},{method:"getLastKnownPositionAsync",permission:"location",...Je},{method:"watchPositionImplAsync",permission:"location",...Je},{method:"startGeofencingAsync",permission:"locationBackground",...nn},{method:"startLocationUpdatesAsync",permission:"locationBackground",...nn}]},{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 Bo(){let e=globalThis.expo?.modules;return e&&typeof e=="object"?e:null}function _o(e){try{return new Set(Object.keys(e))}catch{return new Set}}function zo(e,t=[]){return e.flavor!=="privileges"?[]:t.length>0?t.slice(0,1):[false]}async function on(){let e=Bo();if(!e)return;let t=_o(e),n=Q(),i=[];for(let o of Uo){if(!t.has(o.module))continue;let r=e[o.module];if(!r)continue;let s=new Set;for(let a of o.permissions){if(s.has(a.permission))continue;let d=r[a.get],u=d?.__buoyPermissionsOriginal??d;typeof u=="function"&&(s.add(a.permission),i.push(Promise.resolve().then(()=>u.apply(r,zo(a))).then(c=>q(a.permission,Dn(c,n),o.library)).catch(()=>{})))}}await Promise.all(i)}import{createSyncAdapter as Ho}from"@buoy-gg/shared-ui/web";import{BUOY_SYNTHETIC_MARK as Fo}from"@buoy-gg/shared-ui/web";var rn=null;function Ze(e){try{rn?.emit("appStateDidChange",{app_state:e,[Fo]:true})}catch{}}function Vo(){Q()==="ios"&&Ze("inactive"),Ze("background")}function Wo(){Ze("active")}var Ae=null,sn=false,an=null;function Ko(){return sn}function Se(){return an?(an(),true):false}function Go(){!rn||sn||(Ae&&clearTimeout(Ae),Ae=setTimeout(()=>{Ae=null,Vo(),setTimeout(Wo,60)},120))}function Pe(e){return e&&typeof e=="object"?e:{}}function Xe(e){return e.permission??e.id??e.permissionId??e.name}function re(e,t){let n=e[t];if(typeof n=="boolean")return n;if(n==="true")return true;if(n==="false")return false}var ln=Ho({version:1,getSnapshot(){return A()},subscribe(e){return ee(e)},actions:{async getState(){return await on(),Ko()?{...A(),settingsStandInOpen:true}:A()},setOverride(e){let t=Pe(e),n=Xe(t),i=t.state??t.status??t.value;if(n===void 0||i===void 0)throw new Error('setOverride needs `permission` (e.g. "location", "camera", "notifications") and `state` ("undetermined", "granted", "limited", "denied", "blocked" or "restricted").');return Se(),kt(n,i)},clearOverride(e){let t=Xe(Pe(e));if(t===void 0)throw new Error("clearOverride needs `permission`.");return Se(),Et(t)},requestReal(e){let t=Xe(Pe(e));if(t===void 0)throw new Error("requestReal needs `permission`.");return Hn(t)},resetAll(){return Se(),qe()},updateSettings(e){let t=Pe(e);return Ct({requestAnswer:t.requestAnswer??t.answer,persist:re(t,"persist"),showChip:re(t,"showChip"),notifyApp:re(t,"notifyApp"),enforce:re(t,"enforce"),interceptSettings:re(t,"interceptSettings")})},clearLog(){return Gn()},simulateReturnFromSettings(){return Se()||Go(),A()}}});import{useEffect as Yo,useReducer as Jo,useState as cn}from"react";import{Check as Zo,ChevronLeft as Xo,ChevronRight as dn,NightCard as $,NightFootnote as F,NightRows as Qe,NightSectionLabel as un,night as m,useSafeAreaInsets as Qo,useToolScreenHeader as er}from"@buoy-gg/shared-ui/web";import{Fragment as pn,jsx as p,jsxs as y}from"react/jsx-runtime";var et=1500,tr=()=>{let e=globalThis.__buoyRealNow;return typeof e=="function"?e():Date.now()};function nr(e,t){return e.effective?e.once&&e.effective==="granted"?"Allowed Once":M(e.id,t,e.effective):"Not Checked"}function mn({snapshot:e,onAction:t,onReload:n,browserOnly:i}){let o=Qo({minBottom:16}),[r,s]=cn(null),[a,d]=cn({name:"list"}),u=(S,xe)=>{s(null),t(S,xe).catch(ke=>{s(ke instanceof Error?ke.message:String(ke))})},c=a.name==="detail"?e?.permissions.find(S=>S.id===a.id):void 0,f=()=>d(a.name==="detail"&&a.from==="other"?{name:"other"}:{name:"list"}),w=a.name==="other"?"Other Permissions":c?c.label:null,P=er(w?{title:w,onBack:f,searchable:false}:null,[w,a.name,a.name==="detail"?a.from:null]);if(!e)return p(b,{style:h.waiting,testID:"permissions-waiting",children:p(F,{centered:true,children:"Waiting for the app\u2026"})});let{platform:V,permissions:tt}=e,nt=tt.filter(S=>S.calls>0||S.override!==null),se=tt.filter(S=>!(S.calls>0||S.override!==null)),it=(S,xe)=>d({name:"detail",id:S,from:xe}),W;return i?W=p($,{padded:true,children:p(g,{style:h.empty,testID:"permissions-browser-only",children:"This app runs in a plain browser. The browser keeps its own permissions. Buoy can't change them here. This tool works when the app runs on a phone with Capacitor."})}):a.name==="detail"&&c?W=p(rr,{row:c,platform:V,log:e.log,run:u,onPicked:f}):a.name==="other"?W=y(b,{children:[p(fn,{rows:se,platform:V,onOpen:S=>it(S,"other")}),p(F,{children:"Your app can ask for these but hasn't yet."})]}):W=y(pn,{children:[nt.length>0?p(fn,{rows:nt,platform:V,onOpen:S=>it(S,"list"),onReload:n}):p($,{padded:true,children:p(g,{style:h.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."})}),se.length>0?p($,{children:y(O,{testID:"permissions-other",accessibilityRole:"button",accessibilityLabel:`Other Permissions, ${se.length}`,activeOpacity:.6,onPress:()=>d({name:"other"}),style:h.row,children:[p(g,{style:h.rowTitle,children:"Other Permissions"}),y(b,{style:h.rowRight,children:[p(g,{style:h.rowValue,children:se.length}),p(dn,{size:16,color:m.color.textTertiary})]})]})}):null,e.overriddenCount>0?p($,{children:p(O,{testID:"permissions-reset",accessibilityRole:"button",accessibilityLabel:"Use Real Permissions",activeOpacity:.6,onPress:()=>u("resetAll"),style:h.row,children:p(g,{style:h.destructive,children:"Use Real Permissions"})})}):null]}),y(Kt,{keyboardShouldPersistTaps:"handled",style:h.fill,contentContainerStyle:[h.content,{paddingBottom:o.bottom}],testID:"permissions-scroll",children:[!P&&a.name!=="list"?y(O,{testID:"permissions-back",accessibilityRole:"button",accessibilityLabel:"Back",onPress:f,style:h.inlineBack,children:[p(Xo,{size:18,color:m.color.accent}),p(g,{style:h.inlineBackText,children:a.name==="detail"&&a.from==="other"?"Other Permissions":"Permissions"}),w?p(g,{style:h.inlineTitle,children:w}):null]}):null,r?p(F,{tone:"danger",centered:true,children:p(g,{testID:"permissions-error",children:r})}):null,W]})}function fn({rows:e,platform:t,onOpen:n,onReload:i}){let[,o]=Jo(d=>d+1,0),r=tr(),s=e.filter(d=>d.stale&&d.changedAt!==null&&r-d.changedAt<et).map(d=>et-(r-d.changedAt)),a=s.length>0?Math.min(...s):null;return Yo(()=>{if(a===null)return;let d=setTimeout(o,a+50);return()=>clearTimeout(d)},[a]),p($,{children:p(Qe,{children:e.map(d=>{let u=d.stale&&d.changedAt!==null&&r-d.changedAt>=et;return y(b,{children:[p(ir,{row:d,platform:t,onPress:()=>n(d.id)}),u?y(b,{style:h.stale,testID:`permissions-stale-${d.id}`,children:[p(g,{style:h.staleText,children:"The app hasn't checked again since this changed."}),i?p(O,{testID:`permissions-reload-${d.id}`,accessibilityRole:"button",accessibilityLabel:"Reload App",onPress:i,hitSlop:{top:8,bottom:8,left:8,right:8},children:p(g,{style:h.staleAction,children:"Reload App"})}):null]}):null]},d.id)})})})}function ir({row:e,platform:t,onPress:n}){let i=e.override!==null,o=nr(e,t),r=e.real?M(e.id,t,e.real):"Not Checked";return y(O,{testID:`permissions-row-${e.id}`,accessibilityRole:"button",accessibilityLabel:`${e.label}: ${o}${i?`, simulated. Phone: ${r}`:""}`,activeOpacity:.6,onPress:n,style:h.row,children:[y(b,{style:h.rowLeft,children:[p(g,{style:h.rowTitle,children:e.label}),i?y(g,{style:h.rowSub,testID:`permissions-phone-${e.id}`,children:["Phone: ",r]}):null]}),y(b,{style:h.rowRight,children:[i?p(b,{style:h.dot}):null,p(g,{style:[h.rowValue,i?h.rowValueSimulated:null],testID:`permissions-value-${e.id}`,numberOfLines:1,children:o}),p(dn,{size:16,color:m.color.textTertiary})]})]})}function hn({title:e,detail:t,selected:n,testID:i,onPress:o}){return y(O,{testID:i,accessibilityRole:"button",accessibilityLabel:`${e}. ${t}`,accessibilityState:{selected:n},activeOpacity:.6,onPress:o,style:h.option,children:[y(b,{style:h.optionText,children:[p(g,{style:h.rowTitle,children:e}),p(g,{style:h.optionDetail,children:t})]}),p(b,{style:h.check,children:n?p(Zo,{size:18,color:m.color.accent}):null})]})}var or={check:"Checked",request:"Asked",settings:"Opened Settings",gated:"Needed it"};function rr({row:e,platform:t,log:n,run:i,onPicked:o}){let r=e.real?M(e.id,t,e.real):null,s=u=>{u===null?i("clearOverride",{permission:e.id}):i("setOverride",{permission:e.id,state:u}),o()},a=n.filter(u=>u.permission===e.id).slice(0,8),d=e.canRequestReal&&e.real==="undetermined";return y(pn,{children:[y(b,{children:[p(un,{children:"What the app sees"}),p($,{children:y(Qe,{children:[p(hn,{title:"Phone's Setting",detail:r?`Use what the phone says: ${r}.`:"Use what the phone says.",selected:e.override===null,testID:`permissions-state-${e.id}-real`,onPress:()=>s(null)},"real"),e.states.map(u=>p(hn,{title:M(e.id,t,u),detail:Ln(e.id,t,u),selected:e.override===u,testID:`permissions-state-${e.id}-${u}`,onPress:()=>s(u)},u))]})})]}),d?y(b,{children:[p($,{children:p(O,{testID:`permissions-request-real-${e.id}`,accessibilityRole:"button",accessibilityLabel:`Show the real system prompt for ${e.label}`,activeOpacity:.6,onPress:()=>i("requestReal",{permission:e.id}),style:h.row,children:p(g,{style:h.action,children:"Show Real Prompt"})})}),p(F,{children:e.warning??"Asks the phone for real, so calls that need this permission work."})]}):e.warning?p(F,{tone:"warning",children:p(g,{testID:`permissions-warning-${e.id}`,children:e.warning})}):null,a.length>0?y(b,{children:[p(un,{children:"Recent"}),p($,{children:p(Qe,{children:a.map(u=>p(ar,{entry:u,platform:t},u.id))})}),e.sources.length>0?y(F,{children:["Read through ",e.sources.join(", ")]}):null]}):null]})}function sr(e){let t=new Date(e),n=i=>String(i).padStart(2,"0");return`${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`}function ar({entry:e,platform:t}){let n=e.error?"Failed":e.returned&&e.permission?e.answer==="once"&&e.returned==="granted"?"Allowed Once":M(e.permission,t,e.returned):"";return y(b,{style:h.recentRow,testID:`permissions-log-${e.id}`,children:[p(g,{style:h.recentTime,children:sr(e.at)}),p(g,{style:h.recentVerb,numberOfLines:1,children:or[e.kind]}),p(g,{style:[h.recentResult,e.error?h.recentFailed:null],numberOfLines:1,children:n})]})}var h=ye.create({fill:{flex:1},content:{paddingHorizontal:m.gutter,paddingTop:12,gap:m.groupGap},waiting:{flex:1,alignItems:"center",justifyContent:"center",padding:24},empty:{color:m.color.textSecondary,fontSize:m.font.body,lineHeight:20},row:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,minHeight:50,paddingHorizontal:m.rowPadH,paddingVertical:10},rowLeft:{flexShrink:1,gap:2},rowTitle:{color:m.color.text,fontSize:m.font.row},rowSub:{color:m.color.textTertiary,fontSize:m.font.caption},rowRight:{flexDirection:"row",alignItems:"center",gap:6,flexShrink:1},rowValue:{color:m.color.textSecondary,fontSize:m.font.row},rowValueSimulated:{color:m.color.accent},dot:{width:7,height:7,borderRadius:4,backgroundColor:m.color.accent},stale:{flexDirection:"row",alignItems:"center",flexWrap:"wrap",columnGap:10,rowGap:4,paddingHorizontal:m.rowPadH,paddingBottom:12,marginTop:-4},staleText:{color:m.color.textSecondary,fontSize:m.font.caption,flexShrink:1},staleAction:{color:m.color.accent,fontSize:m.font.caption,fontWeight:"600"},destructive:{color:m.color.danger,fontSize:m.font.row},action:{color:m.color.accent,fontSize:m.font.row},option:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:m.rowPadH,paddingVertical:11,minHeight:50},optionText:{flex:1,gap:2},optionDetail:{color:m.color.textTertiary,fontSize:m.font.caption,lineHeight:17},check:{width:20,alignItems:"center"},inlineBack:{flexDirection:"row",alignItems:"center",gap:4,marginBottom:-8},inlineBackText:{color:m.color.accent,fontSize:m.font.row},inlineTitle:{color:m.color.text,fontSize:m.font.row,fontWeight:"600",marginLeft:"auto"},recentRow:{flexDirection:"row",alignItems:"center",gap:12,paddingHorizontal:m.rowPadH,paddingVertical:10},recentTime:{color:m.color.textTertiary,fontSize:m.font.caption,fontVariant:["tabular-nums"]},recentVerb:{color:m.color.text,fontSize:m.font.body,flex:1},recentResult:{color:m.color.textSecondary,fontSize:m.font.body},recentFailed:{color:m.color.danger}});import{jsx as lr}from"react/jsx-runtime";var cr=ln.actions;async function dr(e,t){let n=cr[e];if(!n)throw new Error(`Unknown permissions action: ${e}`);return n(t)}function ur(){jo("auto","buoy permissions").catch(()=>{})}function gn(){let[e]=qo(()=>zt.OS==="web"&&!Mo());Do(()=>{Ve(),on()},[]);let t=$o(ee,A,A);return lr(mn,{snapshot:t,onAction:dr,onReload:ur,browserOnly:e})}import{jsx as pr}from"react/jsx-runtime";var yn=Lo({id:"permissions",name:"PERMISSIONS",description:"Test denied, blocked, limited and not-asked permission states",slot:"both",color:Ro,icon:({size:e,color:t})=>pr(To,{size:e,color:t}),component:gn,modal:{subtitle:"choose what the app is allowed to do"}}),mr=No(yn);import{PermissionsIcon as fr,PERMISSIONS_ICON_COLOR as hr}from"@buoy-gg/shared-ui/web";var bn=typeof navigator<"u"&&navigator.product==="ReactNative",gr=(()=>{try{return globalThis.Capacitor?.isNativePlatform?.()===true}catch{return false}})(),yr=!bn&&typeof globalThis.document<"u";(bn||gr||yr)&&typeof st<"u"&&st&&(Ve(),Io());export{Oe as KNOWN_PERMISSION_IDS,be as PERMISSIONS_CHIP_ID,hr as PERMISSIONS_ICON_COLOR,ce as PERMISSION_STATES,gn as PermissionsBody,tn as PermissionsChip,fr as PermissionsIcon,mn as PermissionsToolView,Et as clearPermissionOverride,mr as createPermissionsTool,v as getPermissionOverride,A as getPermissionsSnapshot,Ve as installPermissions,Fn as isPermissionOverridden,ko as openPermissionsChip,R as permissionInfo,ln as permissionsSyncAdapter,yn as permissionsToolPreset,qe as resetPermissions,kt as setPermissionOverride,M as stateLabel,ee as subscribePermissions,de as supportedStates,Ct as updatePermissionSettings};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buoy-gg/permissions",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.79",
|
|
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,17 +17,17 @@
|
|
|
17
17
|
"./lib/web/**/*.mjs"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@buoy-gg/shared-ui": "^7.0.
|
|
20
|
+
"@buoy-gg/shared-ui": "^7.0.79"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
|
-
"@buoy-gg/license": "7.0.
|
|
23
|
+
"@buoy-gg/license": "7.0.79",
|
|
24
24
|
"react": "*"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/react": "^19.1.0",
|
|
28
28
|
"@types/react-native": "^0.73.0",
|
|
29
29
|
"typescript": "~5.8.3",
|
|
30
|
-
"@buoy-gg/license": "^7.0.
|
|
30
|
+
"@buoy-gg/license": "^7.0.79"
|
|
31
31
|
},
|
|
32
32
|
"react-native-builder-bob": {
|
|
33
33
|
"source": "src",
|