| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- import { computed, type CSSProperties, ref } from 'vue'
- import { onUnload } from '@dcloudio/uni-app'
- type KeyboardHeightChangeResult = {
- height?: number
- }
- type KeyboardHeightChangeCallback = (result: KeyboardHeightChangeResult) => void
- type MiniProgramKeyboardApi = {
- onKeyboardHeightChange?: (callback: KeyboardHeightChangeCallback) => void
- offKeyboardHeightChange?: (callback: KeyboardHeightChangeCallback) => void
- }
- type MiniProgramWindowInfo = UniApp.GetWindowInfoResult & {
- safeAreaInsets?: {
- bottom?: number
- }
- safeArea?: {
- bottom?: number
- }
- }
- const FOOTER_TOP_PADDING_RPX = 20
- const FOOTER_BOTTOM_PADDING_RPX = 20
- const FOOTER_BUTTON_HEIGHT_RPX = 88
- const CONTENT_EXTRA_BOTTOM_RPX = 24
- export const useTaskFormSafeArea = () => {
- const keyboardApi = uni as unknown as MiniProgramKeyboardApi
- const windowWidth = ref(375)
- const safeAreaBottom = ref(0)
- const keyboardHeight = ref(0)
- let keyboardListenerRegistered = false
- const rpxToPx = (rpx: number) => {
- return (windowWidth.value / 750) * rpx
- }
- const activeSafeAreaBottom = computed(() => {
- return keyboardHeight.value > 0 ? 0 : safeAreaBottom.value
- })
- const keyboardVisible = computed(() => keyboardHeight.value > 0)
- const footerHeightPx = computed(() => {
- return (
- rpxToPx(FOOTER_TOP_PADDING_RPX + FOOTER_BUTTON_HEIGHT_RPX + FOOTER_BOTTOM_PADDING_RPX) +
- activeSafeAreaBottom.value
- )
- })
- const contentStyle = computed<CSSProperties>(() => {
- const paddingBottom =
- footerHeightPx.value + keyboardHeight.value + rpxToPx(CONTENT_EXTRA_BOTTOM_RPX)
- return {
- paddingBottom: `${paddingBottom}px`,
- }
- })
- const footerStyle = computed<CSSProperties>(() => {
- return {
- bottom: `${keyboardHeight.value}px`,
- paddingBottom: `${rpxToPx(FOOTER_BOTTOM_PADDING_RPX) + activeSafeAreaBottom.value}px`,
- }
- })
- const initSystemLayout = () => {
- const windowInfo = uni.getWindowInfo() as MiniProgramWindowInfo
- windowWidth.value = windowInfo.windowWidth || 375
- if (typeof windowInfo.safeAreaInsets?.bottom === 'number') {
- safeAreaBottom.value = windowInfo.safeAreaInsets.bottom
- return
- }
- if (
- typeof windowInfo.safeArea?.bottom === 'number' &&
- typeof windowInfo.screenHeight === 'number'
- ) {
- safeAreaBottom.value = Math.max(windowInfo.screenHeight - windowInfo.safeArea.bottom, 0)
- return
- }
- safeAreaBottom.value = 0
- }
- const handleKeyboardHeightChange: KeyboardHeightChangeCallback = (result) => {
- const height = Number(result.height ?? 0)
- keyboardHeight.value = Number.isFinite(height) && height > 0 ? height : 0
- }
- const initSafeArea = () => {
- initSystemLayout()
- if (
- keyboardListenerRegistered ||
- !keyboardApi.onKeyboardHeightChange ||
- !keyboardApi.offKeyboardHeightChange
- ) {
- return
- }
- keyboardApi.onKeyboardHeightChange(handleKeyboardHeightChange)
- keyboardListenerRegistered = true
- }
- const disposeSafeArea = () => {
- if (!keyboardListenerRegistered) {
- return
- }
- keyboardApi.offKeyboardHeightChange?.(handleKeyboardHeightChange)
- keyboardListenerRegistered = false
- keyboardHeight.value = 0
- }
- onUnload(disposeSafeArea)
- return {
- contentStyle,
- footerStyle,
- keyboardVisible,
- initSafeArea,
- }
- }
|