Skip to content

Commit

Permalink
feature: notification width and position
Browse files Browse the repository at this point in the history
  • Loading branch information
DominikDanielewicz committed Oct 19, 2023
1 parent f6b02e9 commit 770c308
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 30 deletions.
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"
},
"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",
"react-native-modal": "^13.0.1",
"react-native-reanimated": "^2.14.4",
"react-native-safe-area-context": "^3.3.2",
Expand Down
25 changes: 21 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: {
errorConfig: {
globalConfig: {
notificationPosition: 'bottom',
titleSize: 40,
},
errorConfig: {
notificationPosition: 'top',
},
successConfig: {
notificationPosition: 'top',
titleSize: 20,
},
},
})
Expand All @@ -31,8 +39,11 @@ 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,
},
},
}).id
)
Expand All @@ -43,11 +54,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: 10,
},
},
config: {
duration: 2000,
notificationPosition: 'bottom',
notificationWidth: 100,
},
})
}
Expand All @@ -60,6 +76,7 @@ export const DefaultExamples = () => {
description: 'This is where the toast text goes',
title: 'Warning',
},
config: {},
})
}
/>
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==
[email protected]:
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
6 changes: 3 additions & 3 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,7 +29,7 @@ export const useNotificationsStates = () => {
return {
config,
dispatch,
topOffset,
notificationOffset,
panHandlerRef,
notificationEvent,
notificationsQueue,
Expand Down
43 changes: 38 additions & 5 deletions src/core/renderers/GestureHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { NotificationState } from '../hooks/useNotificationsStates'
import Animated from 'react-native-reanimated'
import { styles } from '../utils/styles'
import { Constants } from '../config'
import { useNotificationsStates } from '../hooks/useNotificationsStates'

type Props = {
children: ReactNode
Expand All @@ -14,7 +15,7 @@ type Props = {
| 'longPressHandlerRef'
| 'panHandlerRef'
| 'setNotificationHeight'
| 'topOffset'
| 'notificationOffset'
| 'isPortaitMode'
>
animationAPI: Pick<AnimationAPI, 'dragGestureHandler' | 'handleDragStateChange' | 'dragStyles'>
Expand All @@ -28,14 +29,44 @@ export const GestureHandler = ({
notificationTopPosition,
}: Props) => {
const { width } = useWindowDimensions()
const notificationWidth = state.isPortaitMode
? width - Constants.notificationSideMargin * 2
: Constants.maxNotificationWidth
const { config } = useNotificationsStates()

//Jeżeli ktoś poda za dużą szerokość to czy ma zostać zastosowana cała szerokość ekranu czy może defaultowa szerokość?

//Kiedy komunikat ma zajmować całą szerokość?

/*Jak ma się zachowywać komunikat przy:
1) portrait: cała szerokość domyślnie, chyba że notificationWith (jest różny od undefined)
2) landscape: maxNotificationWidth domyślnie chyba że notificationWith (jest różny od undefined)
*/

const hasNotificationWidth = config?.notificationWidth
const isWidthProvided = hasNotificationWidth && config.notificationWidth <= width

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

const getMaxWidth = () => {
if (hasNotificationWidth && config.notificationWidth > width) {
return width - Constants.notificationSideMargin * 2
}
return hasNotificationWidth ? config.notificationWidth : Constants.maxNotificationWidth
}

const notificationWidth = state.isPortraitMode
? isWidthProvided
? config.notificationWidth
: getDefaultWidth()
: getMaxWidth()

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 +82,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
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 }
}

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"

[email protected]:
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:
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

0 comments on commit 770c308

Please sign in to comment.