-
-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(useauthorize): add useAuthorize hook
- Loading branch information
Showing
11 changed files
with
348 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default { | ||
navigationBarTitleText: 'useAuthorize', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import React, { useCallback } from 'react'; | ||
import { AtCheckbox, AtButton, AtNoticebar } from 'taro-ui'; | ||
import DocPage from '@components/DocPage'; | ||
|
||
import { useModal, useAuthorize, useEnv } from 'taro-hooks'; | ||
import { AuthSetting, ENV_TYPE } from '@tarojs/taro'; | ||
|
||
import 'taro-ui/dist/style/components/icon.scss'; | ||
|
||
const transferOptions = (setting: AuthSetting) => | ||
Object.entries(setting).map(([key, value]) => ({ | ||
label: key, | ||
value: key, | ||
disabled: typeof value === 'boolean' ? !value : value !== 'accept', | ||
})); | ||
|
||
export default () => { | ||
const env = useEnv(); | ||
const [show] = useModal({ mask: true, title: '操作结果', showCancel: false }); | ||
const [{ authSetting, subscriptionsSetting }, { openSetting, authorize }] = | ||
useAuthorize({ withSubscriptions: true }); | ||
|
||
const options = transferOptions({ ...authSetting, ...subscriptionsSetting }); | ||
|
||
const handleAuth = useCallback(() => { | ||
authorize('scope.invoice').then(() => show({ content: '授权调用成功!' })); | ||
}, [authorize, show]); | ||
|
||
return ( | ||
<> | ||
<AtNoticebar marquee>小程序专用hook</AtNoticebar> | ||
<DocPage title="useAuthorize 用户授权" panelTitle="useAuthorize"> | ||
<AtButton | ||
disabled={env !== ENV_TYPE.WEAPP} | ||
onClick={() => openSetting()} | ||
> | ||
打开设置面板 | ||
</AtButton> | ||
<AtButton | ||
disabled={env !== ENV_TYPE.WEAPP} | ||
className="gap" | ||
onClick={handleAuth} | ||
> | ||
授权 | ||
</AtButton> | ||
{env === ENV_TYPE.WEAPP && ( | ||
<AtCheckbox | ||
options={options} | ||
selectedList={options | ||
.filter((v) => !v.disabled) | ||
.map((v) => v.value)} | ||
onChange={console.log} | ||
/> | ||
)} | ||
</DocPage> | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
--- | ||
title: useAuthorize | ||
nav: | ||
title: Hooks | ||
path: /hooks | ||
order: 2 | ||
group: | ||
title: 小程序 | ||
path: /wechat | ||
--- | ||
|
||
# useAuthorize | ||
|
||
直接调起用户授权信息、获取用户授权信息 | ||
|
||
## 何时使用 | ||
|
||
当需要在使用某些权限功能前进行授权或校验时 | ||
|
||
## API | ||
|
||
```jsx | pure | ||
const [ | ||
{ authSetting, subscriptionsSetting, miniprogramAuthSetting }, | ||
{ openSetting, authorize }, | ||
] = useAuthorize(option?); | ||
``` | ||
## 参数说明 | ||
| 参数 | 说明 | 类型 | 默认值 | | ||
| ----------------- | -------------------------------------------------------------------------------------------------------------------------- | --------- | ------- | | ||
| withSubscriptions | 是否同时获取用户订阅消息的订阅状态,默认不获取(注意: 该 hook 默认实时获取最新授权信息, 初始配置决定整个周期中获取配置行为) | `boolean` | `false` | | ||
## 返回值说明 | ||
| 返回值 | 说明 | 类型 | | ||
| ---------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | ||
| authSetting | 用户授权结果 | `AuthSetting` | | ||
| subscriptionsSetting | 用户订阅消息设置 | `ISubscriptionsSetting` | | ||
| miniprogramAuthSetting | 在插件中调用时,当前宿主小程序的用户授权结果 | `AuthSetting` | | ||
| openSetting | 调起客户端小程序设置界面 | `(withSubscriptions?: boolean) => Promise<IROpenSettingSuccessCallbackResult>` | | ||
| authorize | 提前向用户发起授权请求 | `(scope: keyof AuthSetting | keyof IAuthSettingForMiniProgram, miniprogram?: boolean) => Promise<General.CallbackResult>` | | ||
### ISubscriptionsSetting | ||
| 参数 | 类型 | 说明 | | ||
| ----------- | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| mainSwitch | `boolean` | 订阅消息总开关 | | ||
| itemSetting | `{[_: string]: 'accept' | 'reject' | 'ban';}` | 每一项订阅消息的订阅状态,对象的键为一次性订阅消息的模板 id 或系统订阅消息的类型,值为'accept'、'reject'、'ban'中的其中一种。'accept'表示用户同意订阅这条消息,'reject'表示用户拒绝订阅这条消息,'ban'表示已被后台封禁 | | ||
### IAuthSettingForMiniProgram | ||
| 参数 | 类型 | 说明 | | ||
| ---------------------- | --------- | ---------- | | ||
| scope.record | `boolean` | 录音 | | ||
| scope.writePhotosAlbum | `boolean` | 保存到相册 | | ||
| scope.camera | `boolean` | 摄像头 | | ||
### AuthSetting | ||
| 参数 | 类型 | 说明 | | ||
| ---------------------------- | --------- | -------------------------------------------- | | ||
| scope.userInfo | `boolean` | 用户信息 | | ||
| scope.userLocation | `boolean` | 地理位置 | | ||
| scope.userLocationBackground | `boolean` | 后台定位 | | ||
| scope.address | `boolean` | 通讯地址(已取消授权,可以直接调用对应接口) | | ||
| scope.invoiceTitle | `boolean` | 发票抬头(已取消授权,可以直接调用对应接口) | | ||
| scope.invoice | `boolean` | 获取发票(已取消授权,可以直接调用对应接口) | | ||
| scope.werun | `boolean` | 微信运动步数 | | ||
| scope.record | `boolean` | 录音功能 | | ||
| scope.writePhotosAlbum | `boolean` | 保存到相册 | | ||
| scope.camera | `boolean` | 摄像头 | | ||
## 代码演示 | ||
<code src="@pages/useAuthorize" /> | ||
## Hook 支持度 | ||
| 微信小程序 | H5 | ReactNative | | ||
| :--------: | :-: | :---------: | | ||
| ✔️ | | | | ||
## FAQ | ||
### 1. 更多说明 | ||
- [authorize](https://developers.weixin.qq.com/miniprogram/dev/api/open-api/authorize/wx.authorize.htmll) | ||
- [openSetting](https://developers.weixin.qq.com/miniprogram/dev/api/open-api/setting/wx.openSetting.html) | ||
- [getSetting](https://developers.weixin.qq.com/miniprogram/dev/api/open-api/setting/wx.openSetting.html) | ||
- [scope](https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/authorize.html#scope-%E5%88%97%E8%A1%A8) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
import { useCallback, useEffect, useState } from 'react'; | ||
import { | ||
getSetting, | ||
openSetting, | ||
AuthSetting, | ||
authorize, | ||
General, | ||
ENV_TYPE, | ||
} from '@tarojs/taro'; | ||
import useEnv from '../useEnv'; | ||
import useVisible from '../useVisible'; | ||
import { typeOf } from '../utils/tool'; | ||
|
||
declare var wx: any; | ||
|
||
// rewrite openSetting options | ||
interface ISubscriptionsSetting { | ||
mainSwitch?: boolean; | ||
itemSetting?: { | ||
[_: string]: 'accept' | 'reject' | 'ban'; | ||
}; | ||
} | ||
interface IROpenSettingSuccessCallbackResult | ||
extends openSetting.SuccessCallbackResult { | ||
subscriptionsSetting?: ISubscriptionsSetting; | ||
} | ||
|
||
interface IOption { | ||
withSubscriptions?: boolean; | ||
} | ||
|
||
interface IROpenSettingOption extends openSetting.Option { | ||
success?: (result: IROpenSettingSuccessCallbackResult) => void; | ||
} | ||
type ROpenSetting = ( | ||
options: IROpenSettingOption & IOption, | ||
) => Promise<IROpenSettingSuccessCallbackResult>; | ||
|
||
interface IRGetSettingSuccessCallbackResult | ||
extends openSetting.SuccessCallbackResult { | ||
subscriptionsSetting?: ISubscriptionsSetting; | ||
miniprogramAuthSetting?: AuthSetting; | ||
} | ||
interface IRGetSettingOption extends getSetting.Option { | ||
success?: (result: IRGetSettingSuccessCallbackResult) => void; | ||
} | ||
type RGetSetting = ( | ||
options: IRGetSettingOption & IOption, | ||
) => Promise<IRGetSettingSuccessCallbackResult>; | ||
|
||
export type IOpenSettingAction = ( | ||
withSubscriptions?: boolean, | ||
) => Promise<IROpenSettingSuccessCallbackResult>; | ||
|
||
// plugin scope | ||
export interface IAuthSettingForMiniProgram { | ||
'scope.record'?: boolean; | ||
'scope.writePhotosAlbum'?: boolean; | ||
'scope.camera'?: boolean; | ||
} | ||
export type IAuthorizeAction = ( | ||
scope: keyof AuthSetting | keyof IAuthSettingForMiniProgram, | ||
miniprogram?: boolean, | ||
) => Promise<General.CallbackResult>; | ||
|
||
export interface IAction { | ||
openSetting: IOpenSettingAction; | ||
authorize: IAuthorizeAction; | ||
} | ||
|
||
export interface IResult { | ||
authSetting: AuthSetting; | ||
subscriptionsSetting: ISubscriptionsSetting; | ||
miniprogramAuthSetting: AuthSetting; | ||
} | ||
|
||
function useAuthorize(option?: IOption): [IResult, IAction] { | ||
const env = useEnv(); | ||
const visible = useVisible(); | ||
const [authSetting, setAuthSetting] = useState<AuthSetting>({}); | ||
const [subscriptionsSetting, setSubscriptionsSetting] = | ||
useState<ISubscriptionsSetting>({}); | ||
const [miniprogramAuthSetting, setMiniprogramAuthSetting] = | ||
useState<AuthSetting>({}); | ||
|
||
useEffect(() => { | ||
if (env === ENV_TYPE.WEAPP) { | ||
getSettingAsync(); | ||
} | ||
}, [env, visible]); | ||
|
||
const getSettingAsync = useCallback(async () => { | ||
try { | ||
const { withSubscriptions = false } = option || {}; | ||
const { | ||
authSetting: totalAuthSetting = {}, | ||
subscriptionsSetting: totalSubscriptionsSetting, | ||
miniprogramAuthSetting: totalMiniprogramAuthSetting, | ||
} = await (getSetting as RGetSetting)({ | ||
withSubscriptions, | ||
}); | ||
setAuthSetting(totalAuthSetting); | ||
if (withSubscriptions && totalSubscriptionsSetting) { | ||
setSubscriptionsSetting(totalSubscriptionsSetting); | ||
} | ||
totalMiniprogramAuthSetting && | ||
setMiniprogramAuthSetting(totalMiniprogramAuthSetting); | ||
} catch (e) { | ||
console.log(e); | ||
} | ||
}, [option]); | ||
|
||
const openSettingAsync = useCallback<IOpenSettingAction>( | ||
(withSubscriptions = false) => { | ||
return new Promise((resolve, reject) => { | ||
if (env === ENV_TYPE.WEAPP) { | ||
try { | ||
(openSetting as ROpenSetting)({ | ||
withSubscriptions, | ||
success: (res) => { | ||
const { | ||
authSetting: totalAuthSetting, | ||
subscriptionsSetting: totalSubscriptionsSetting, | ||
} = res; | ||
if (withSubscriptions && totalSubscriptionsSetting) { | ||
setSubscriptionsSetting(totalSubscriptionsSetting); | ||
} | ||
setAuthSetting(totalAuthSetting); | ||
resolve(res); | ||
}, | ||
fail: reject, | ||
}).catch(reject); | ||
} catch (e) { | ||
reject({ errMsg: e }); | ||
} | ||
} else { | ||
reject({ errMsg: 'openSetting:fail' }); | ||
} | ||
}); | ||
}, | ||
[env], | ||
); | ||
|
||
const authorizeAysnc = useCallback<IAuthorizeAction>( | ||
(scope, miniprogram = false) => { | ||
return new Promise((resolve, reject) => { | ||
if (!scope || env === ENV_TYPE.WEAPP) { | ||
try { | ||
if (miniprogram && typeOf(wx, 'Object')) { | ||
wx.authorizeForMiniProgram({ | ||
scope, | ||
success: resolve, | ||
fail: reject, | ||
}); | ||
} else { | ||
authorize({ | ||
scope, | ||
success: resolve, | ||
fail: reject, | ||
}).catch(reject); | ||
} | ||
} catch (e) { | ||
reject(e); | ||
} | ||
} else { | ||
reject({ errMsg: 'authorize:fail' }); | ||
} | ||
}); | ||
}, | ||
[authSetting, miniprogramAuthSetting], | ||
); | ||
|
||
return [ | ||
{ authSetting, subscriptionsSetting, miniprogramAuthSetting }, | ||
{ | ||
openSetting: openSettingAsync, | ||
authorize: authorizeAysnc, | ||
}, | ||
]; | ||
} | ||
|
||
export default useAuthorize; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,5 @@ interface INavigator extends Navigator { | |
} | ||
|
||
declare var navigator: INavigator; | ||
|
||
declare var wx: any; |
Oops, something went wrong.
c0ec57c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
taro-hooks – ./
taro-hooks-innocces.vercel.app
taro-hooks-theta.vercel.app
taro-hooks-git-main-innocces.vercel.app
c0ec57c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
taro-hooks-h5 – ./
taro-hooks-h5-git-main-innocces.vercel.app
taro-hooks-h5-green.vercel.app
taro-hooks-h5-innocces.vercel.app