Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: notification width and position #220

Merged
merged 7 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"start": "react-native start",
"test": "jest",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
"postinstall": "patch-package"
"postinstall": "patch-package",
"clear": "yarn --clearCache"
PdoubleU marked this conversation as resolved.
Show resolved Hide resolved
},
"dependencies": {
"@react-native-masked-view/masked-view": "^0.2.6",
Expand All @@ -19,7 +20,7 @@
"@reduxjs/toolkit": "^1.7.1",
"react": "17.0.2",
"react-native": "0.68.5",
"react-native-gesture-handler": "^2.9.0",
"react-native-gesture-handler": "2.9.0",
PdoubleU marked this conversation as resolved.
Show resolved Hide resolved
"react-native-modal": "^13.0.1",
"react-native-reanimated": "^2.14.4",
"react-native-safe-area-context": "^3.3.2",
Expand Down
32 changes: 28 additions & 4 deletions example/src/screens/DefaultExamples.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,18 @@ import { RemoveButton } from '../components/basicExamples/RemoveButton'
import { styles } from './styles'

const { useNotifications, NotificationsProvider } = createNotifications({
notificationPosition: 'top',
notificationWidth: 300,
defaultStylesSettings: {
globalConfig: {
titleSize: 30,
},
successConfig: {
notificationPosition: 'center',
titleSize: 20,
},
PdoubleU marked this conversation as resolved.
Show resolved Hide resolved
errorConfig: {
notificationPosition: 'bottom',
titleSize: 10,
},
},
})
Expand All @@ -31,8 +39,16 @@ export const DefaultExamples = () => {
setId(
notify('success', {
params: {
description: 'This is where the toast text goes',
description: 'This is where the toast text goes.',
title: 'Success',
style: {
titleSize: 10,
},
},
config: {
duration: 2000,
notificationPosition: 'top-right',
notificationWidth: 200,
PdoubleU marked this conversation as resolved.
Show resolved Hide resolved
},
}).id
)
Expand All @@ -43,11 +59,16 @@ export const DefaultExamples = () => {
onPress={() =>
notify('error', {
params: {
description: 'This is where the toast text goes. ',
description: 'This is where the toast text goes.',
title: 'Error',
style: {
titleSize: 20,
},
},
config: {
duration: 2000,
notificationPosition: 'top',
notificationWidth: 2000,
},
})
}
Expand All @@ -60,6 +81,9 @@ export const DefaultExamples = () => {
description: 'This is where the toast text goes',
title: 'Warning',
},
config: {
notificationPosition: 'bottom-left',
},
})
}
/>
Expand All @@ -72,7 +96,7 @@ export const DefaultExamples = () => {
title: 'Info',
},
config: {
notificationPosition: 'bottom',
notificationPosition: 'bottom-right',
},
})
}
Expand Down
8 changes: 4 additions & 4 deletions example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6016,10 +6016,10 @@ react-native-codegen@^0.0.18:
jscodeshift "^0.13.1"
nullthrows "^1.1.1"

react-native-gesture-handler@^2.9.0:
version "2.12.0"
resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.12.0.tgz#59ca9d97e4c71f70b9c258f14a1a081f4c689976"
integrity sha512-rr+XwVzXAVpY8co25ukvyI38fKCxTQjz7WajeZktl8qUPdh1twnSExgpT47DqDi4n+m+OiJPAnHfZOkqqAQMOg==
react-native-gesture-handler@2.9.0:
PdoubleU marked this conversation as resolved.
Show resolved Hide resolved
version "2.9.0"
resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.9.0.tgz#2f63812e523c646f25b9ad660fc6f75948e51241"
integrity sha512-a0BcH3Qb1tgVqUutc6d3VuWQkI1AM3+fJx8dkxzZs9t06qA27QgURYFoklpabuWpsUTzuKRpxleykp25E8m7tg==
dependencies:
"@egjs/hammerjs" "^2.0.17"
hoist-non-react-statics "^3.3.0"
Expand Down
9 changes: 5 additions & 4 deletions src/core/hooks/useNotificationsStates.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useReducer, useRef, useState } from 'react'
import { useWindowDimensions } from 'react-native'
import { useNotificationConfig } from './useNotificationConfig'
import { getTopOffset, mergeConfigs } from '../utils/pickers'
import { getNotificationOffset, mergeConfigs } from '../utils/pickers'
import { queueReducer } from '../utils/queueReducer'
import { useStatusBarHeightDetector } from './useStatusBarHeightDetector'

Expand All @@ -18,7 +18,7 @@ export const useNotificationsStates = () => {
const notificationEvent = notificationsQueue[0]
const config = mergeConfigs(globalConfig, notificationEvent)

const topOffset = getTopOffset({
const notificationOffset = getNotificationOffset({
globalConfig: config,
notificationHeight,
isPortraitMode,
Expand All @@ -29,13 +29,14 @@ export const useNotificationsStates = () => {
return {
config,
dispatch,
topOffset,
notificationOffset,
panHandlerRef,
notificationEvent,
notificationsQueue,
longPressHandlerRef,
setNotificationHeight,
isPortaitMode: isPortraitMode,
isPortrait: isPortraitMode,
notificationWidth: config.notificationWidth,
}
}

Expand Down
37 changes: 31 additions & 6 deletions src/core/renderers/GestureHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ type Props = {
| 'longPressHandlerRef'
| 'panHandlerRef'
| 'setNotificationHeight'
| 'topOffset'
| 'isPortaitMode'
| 'notificationOffset'
| 'isPortrait'
| 'notificationWidth'
>
animationAPI: Pick<AnimationAPI, 'dragGestureHandler' | 'handleDragStateChange' | 'dragStyles'>
notificationTopPosition?: number
Expand All @@ -28,14 +29,36 @@ export const GestureHandler = ({
notificationTopPosition,
}: Props) => {
const { width } = useWindowDimensions()
const notificationWidth = state.isPortaitMode
? width - Constants.notificationSideMargin * 2
: Constants.maxNotificationWidth

const getDefaultWidth = () => width - Constants.notificationSideMargin * 2

const notificationWidthFromState = state?.notificationWidth
const hasNotificationWidth = !!notificationWidthFromState

const isWidthWithinBounds = hasNotificationWidth && notificationWidthFromState <= width

const getMaxWidth = (): number => {
if (hasNotificationWidth && notificationWidthFromState > width) {
return getDefaultWidth()
}
return hasNotificationWidth ? notificationWidthFromState : Constants.maxNotificationWidth
}

let notificationWidth: number
if (state.isPortrait) {
notificationWidth = isWidthWithinBounds ? notificationWidthFromState : getDefaultWidth()
} else {
notificationWidth = getMaxWidth()
}
PdoubleU marked this conversation as resolved.
Show resolved Hide resolved

const top =
notificationTopPosition || notificationTopPosition === 0
? notificationTopPosition
: state.topOffset
: state.notificationOffset.top

const left = state.notificationOffset.left

const right = state.notificationOffset.right

return (
<PanGestureHandler
Expand All @@ -51,6 +74,8 @@ export const GestureHandler = ({
Constants.isAndroid ? styles.containerAndroid : styles.containerIos,
{
top,
left,
right,
width: notificationWidth,
},
]}>
Expand Down
38 changes: 31 additions & 7 deletions src/core/utils/pickers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,62 @@ import type { DefaultKeys, DefaultStylesConfigs } from '../../defaultConfig/type
import type { KeyType } from '../../types/misc'
import { Constants } from '../config'

type GetOffsetTopProps = {
type GetNotificationOffsetProps = {
globalConfig: NotificationsConfig<VariantsMap>
notificationHeight: number
isPortraitMode: boolean
windowHeight: number
statusBarHeight: number
}

export const getTopOffset = ({
export const getNotificationOffset = ({
globalConfig,
notificationHeight,
isPortraitMode,
windowHeight,
statusBarHeight,
}: GetOffsetTopProps) => {
}: GetNotificationOffsetProps) => {
const isNotch = globalConfig.isNotch
const extraSpace = statusBarHeight + 10

const shouldRenderExtraSpace = isNotch ?? (isPortraitMode && !Constants.isAndroid)
const topPosition = shouldRenderExtraSpace ? extraSpace : 10
const notificationPosition = globalConfig.notificationPosition

let topOffset, leftOffset, rightOffset

switch (notificationPosition) {
case 'top':
return topPosition
topOffset = topPosition
break
case 'top-left':
topOffset = topPosition
leftOffset = 10
break
case 'top-right':
topOffset = topPosition
rightOffset = 10
PdoubleU marked this conversation as resolved.
Show resolved Hide resolved
break
case 'center':
return windowHeight / 2 - (notificationHeight ? notificationHeight / 2 : 75)
topOffset = windowHeight / 2 - (notificationHeight ? notificationHeight / 2 + 10 : 75)
break
case 'bottom':
return windowHeight - (notificationHeight ? notificationHeight + extraSpace : 150)
topOffset = windowHeight - (notificationHeight ? notificationHeight + extraSpace : 150)
break
case 'bottom-left':
topOffset = windowHeight - (notificationHeight ? notificationHeight + extraSpace : 150)
leftOffset = 10
break
case 'bottom-right':
topOffset = windowHeight - (notificationHeight ? notificationHeight + extraSpace : 150)
rightOffset = 10
break
default:
return topPosition
topOffset = topPosition
break
}

return { top: topOffset, left: leftOffset, right: rightOffset }
PdoubleU marked this conversation as resolved.
Show resolved Hide resolved
}

export const pickVariant = (
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export type NotificationConfigBase = {
animationConfig: AnimationBuilder | CustomAnimationConfig
gestureConfig: GestureConfig
isNotch?: boolean
notificationWidth?: number
onClose?: () => void
}

Expand Down
9 changes: 8 additions & 1 deletion src/types/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
export type NotificationsType = 'default' | 'success' | 'warning' | 'error'
export type NotificationPosition = 'top' | 'center' | 'bottom'
export type NotificationPosition =
| 'top'
| 'center'
| 'bottom'
| 'top-left'
| 'top-right'
| 'bottom-left'
| 'bottom-right'

export type NotificationConfig = {
type: NotificationsType
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8503,10 +8503,10 @@ react-native-codegen@^0.0.18:
jscodeshift "^0.13.1"
nullthrows "^1.1.1"

react-native-gesture-handler@2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.9.0.tgz#2f63812e523c646f25b9ad660fc6f75948e51241"
integrity sha512-a0BcH3Qb1tgVqUutc6d3VuWQkI1AM3+fJx8dkxzZs9t06qA27QgURYFoklpabuWpsUTzuKRpxleykp25E8m7tg==
react-native-gesture-handler@^2.9.0:
PdoubleU marked this conversation as resolved.
Show resolved Hide resolved
version "2.13.2"
resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.13.2.tgz#06813c250922db258ce4ee255f757e7ef32a3ae0"
integrity sha512-EADHg1cFunvu47lyzlqCJQluQxUIGZwDpdq2GEBXxFmH8AWTI2ofurio5doWnFR+dLVEjaLAzI/dU2xQjP0/pA==
dependencies:
"@egjs/hammerjs" "^2.0.17"
hoist-non-react-statics "^3.3.0"
Expand Down
Loading