1import { css } from '@emotion/react'; 2import React from 'react'; 3 4import { androidPermissions, AndroidPermission, PermissionReference } from './data'; 5 6import Permalink from '~/components/Permalink'; 7import { InlineCode } from '~/components/base/code'; 8import { Quote } from '~/components/base/paragraph'; 9 10// TODO(cedric): all commented code is related to the "granter" column. 11// This column defines if the permission is granted by the system or user (requires notification). 12// We have to clearly communicate what it means before showing it to the user. 13 14// import { QuestionIcon } from '~/components/icons/QuestionIcon'; 15 16type AndroidPermissionsProps = { 17 permissions: PermissionReference<AndroidPermission>[]; 18}; 19 20// const grantedByInfo = 'Some permissions are granted by the system without user approval'; 21 22export function AndroidPermissions(props: AndroidPermissionsProps) { 23 const list = React.useMemo(() => getPermissions(props.permissions), [props.permissions]); 24 25 return ( 26 <table> 27 <thead> 28 <tr> 29 <th>Android Permission</th> 30 {/* <th> 31 <span css={grantedByInfoStyle} title={grantedByInfo}> 32 Granted by <QuestionIcon size={12} title={grantedByInfo} /> 33 </span> 34 </th> */} 35 <th>Description</th> 36 </tr> 37 </thead> 38 <tbody> 39 {list.map(permission => ( 40 <AndroidPermissionRow key={permission.name} {...permission} /> 41 ))} 42 </tbody> 43 </table> 44 ); 45} 46 47function AndroidPermissionRow(permission: AndroidPermission) { 48 const { name, description, explanation, warning, apiDeprecated } = permission; 49 50 return ( 51 <tr css={apiDeprecated && deprecatedStyle}> 52 <td> 53 <Permalink id={`permission-${name.toLowerCase()}`}> 54 <span> 55 <InlineCode>{name}</InlineCode> 56 </span> 57 </Permalink> 58 </td> 59 {/* <td> 60 <i>{getPermissionGranter(permission)}</i> 61 </td> */} 62 <td> 63 {!!description && ( 64 <p css={(warning || explanation) && descriptionSpaceStyle}>{description}</p> 65 )} 66 {!!warning && ( 67 <Quote css={quoteStyle}> 68 <span>⚠️ {warning}</span> 69 </Quote> 70 )} 71 {explanation && !warning && ( 72 <Quote css={quoteStyle}> 73 <span dangerouslySetInnerHTML={{ __html: explanation }} /> 74 </Quote> 75 )} 76 </td> 77 </tr> 78 ); 79} 80 81function getPermissions(permissions: AndroidPermissionsProps['permissions']) { 82 return permissions 83 .map(permission => 84 typeof permission === 'string' 85 ? androidPermissions[permission] 86 : { ...androidPermissions[permission.name], ...permission } 87 ) 88 .filter(Boolean); 89} 90 91// const grantedByInfoStyle = css` 92// white-space: nowrap; 93// `; 94 95const deprecatedStyle = css` 96 opacity: 0.5; 97`; 98 99const descriptionSpaceStyle = css` 100 margin-bottom: 1rem; 101`; 102 103const quoteStyle = css` 104 margin-bottom: 0; 105`; 106 107// function getPermissionGranter(permission: AndroidPermission): 'user' | 'system' | 'none' { 108// if (!permission.protection) return 'none'; 109// if (permission.protection.includes('dangerous')) return 'user'; 110// return 'system'; 111// } 112