Skip to content
This repository was archived by the owner on Aug 13, 2018. It is now read-only.

Commit 05e6d2d

Browse files
authored
Merge pull request #4 from 9gag-open-source/feature/1-renderSnackBarDynamically
Fix race condition by setting up callback properly
2 parents a8992a3 + 41a0441 commit 05e6d2d

File tree

6 files changed

+878
-74
lines changed

6 files changed

+878
-74
lines changed

README.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,30 @@ SnackBar.show('Making the world happier', {
7777
})
7878
```
7979

80+
A SnackBar with nested actions. Always dismiss current SnackBar before showing a new one using the dismiss callback.
81+
```javascript
82+
SnackBar.add('Making the world happier', {
83+
confirmText: 'Learn more',
84+
onConfirm: () => {
85+
console.log('Thank you')
86+
SnackBar.dismiss(() => {
87+
SnackBar.show('Stay unstoppable!')
88+
})
89+
}
90+
})
91+
```
92+
8093
## Flow Control
8194

8295
This library handles messages order with peace of mind.
96+
Calling these functions will show the message immediately if there is no active item.
97+
Callback is optional, but it is suggested to use for flow control.
8398

84-
- `SnackBar.show(title, options)`
85-
<br />For some operations like taking a screenshot requires the message to show it immediately. Using this method to give highest order among all Snack message.
99+
- `SnackBar.show(title, options, [callback])`
100+
<br />Give highest priority to show among all Snack messages.
86101

87-
- `SnackBar.add(title, options)`
88-
<br />It will show it immediately if there isn't any active Snack message. Otherwise, it will enqueue and show it one by one when calling the `dismiss` function.
102+
- `SnackBar.add(title, options, [callback])`
103+
<br />Enqueue and show it one by one when calling the `dismiss` function.
89104

90-
- `SnackBar.dismiss()`
91-
<br />Adding it manually to `onConfirm` and `onCancel` props action to control the flow of show / hide.
105+
- `SnackBar.dismiss([callback])`
106+
<br />Control when and where to dismiss an active item, e.g. `onConfirm` and `onCancel` props action.

__tests__/manager.js

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,41 @@ const TITLE = 'Making the world happier'
66
it('shows Snack item properly', () => {
77
const SnackBar = new SnackBarManager()
88

9-
SnackBar.show(TITLE)
10-
11-
const { current, queue } = SnackBar.get()
12-
expect(current).toBeInstanceOf(RootSiblings)
13-
expect(queue).toHaveLength(0)
9+
SnackBar.show(TITLE, () => {
10+
const { current, queue } = SnackBar.get()
11+
expect(current).toBeInstanceOf(RootSiblings)
12+
expect(queue).toHaveLength(0)
13+
})
1414
})
1515

1616
it('adds Snack item immediately when there is no active item', () => {
1717
const SnackBar = new SnackBarManager()
1818

19-
SnackBar.add(TITLE)
20-
21-
const { current, queue } = SnackBar.get()
22-
expect(current).toBeInstanceOf(RootSiblings)
23-
expect(queue).toHaveLength(0)
19+
SnackBar.add(TITLE, () => {
20+
const { current, queue } = SnackBar.get()
21+
expect(current).toBeInstanceOf(RootSiblings)
22+
expect(queue).toHaveLength(0)
23+
})
2424
})
2525

2626
it('adds Snack item properly when there is an active item', () => {
2727
const SnackBar = new SnackBarManager()
2828
const newTitle = 'Making a happier world'
2929

30-
SnackBar.add(TITLE)
31-
SnackBar.add(newTitle)
32-
33-
const { current, queue } = SnackBar.get()
30+
SnackBar.add(TITLE, () => {
31+
SnackBar.add(newTitle, () => {
32+
const { current, queue } = SnackBar.get()
3433

35-
expect(current).toBeInstanceOf(RootSiblings)
36-
expect(queue).toHaveLength(1)
37-
expect(queue[0]).toMatchObject({
38-
title: newTitle
34+
expect(current).toBeInstanceOf(RootSiblings)
35+
expect(queue).toHaveLength(1)
36+
expect(queue[0]).toMatchObject({
37+
title: newTitle
38+
})
39+
})
3940
})
4041
})
4142

42-
it('should dismiss current item properly', () => {
43+
it('dismisses current item properly', () => {
4344
const SnackBar = new SnackBarManager()
4445

4546
SnackBar.add(TITLE, () => {
@@ -52,7 +53,7 @@ it('should dismiss current item properly', () => {
5253
})
5354
})
5455

55-
it('should show the next item when dismissing', () => {
56+
it('shows the next item when dismissing', () => {
5657
const SnackBar = new SnackBarManager()
5758
const newTitle = 'Making a happier world'
5859

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-snackbar-dialog",
3-
"version": "1.2.0",
3+
"version": "1.2.1",
44
"description": "A react native snackbar with dialog options",
55
"main": "dist/index.js",
66
"scripts": {

src/SnackBar.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ const INITIAL_POSITION: number = -180
2121

2222
const STYLE_BANNER_COLOR: string = '#000000'
2323
const TEXT_COLOR_ACCENT: string = '#0088ff'
24-
const HIT_SLOP = { top: 8, bottom: 8, left: 8, right: 8 }
2524

2625
const TIMEOUT_ID: string = 'snackBar'
2726

@@ -44,6 +43,11 @@ const styles = StyleSheet.create({
4443
fontSize: 16
4544
},
4645

46+
buttonContainer: {
47+
paddingHorizontal: 12,
48+
paddingVertical: 10
49+
},
50+
4751
button: {
4852
fontSize: 16,
4953
fontWeight: '500'
@@ -52,8 +56,8 @@ const styles = StyleSheet.create({
5256
actionRow: {
5357
flexDirection: 'row',
5458
justifyContent: 'flex-end',
55-
padding: 18,
56-
marginBottom: 6
59+
padding: 8,
60+
marginBottom: 8
5761
},
5862

5963
inlineRow: {
@@ -196,7 +200,7 @@ export default class SnackBar extends Component {
196200
const { buttonColor } = this.props
197201

198202
return (
199-
<TouchableOpacity hitSlop={HIT_SLOP} onPress={onPress}>
203+
<TouchableOpacity style={styles.buttonContainer} onPress={onPress}>
200204
<Text style={[styles.button, style, { color: buttonColor }]}>
201205
{text}
202206
</Text>

src/SnackBarManager.js

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@ export default class SnackBarManager {
1313
this.queue = []
1414
}
1515

16-
_hasQueue = (): boolean => {
17-
return Array.isArray(this.queue) && this.queue.length
18-
}
19-
20-
_addCurrent = (props: SnackItemType, callback?: Function = () => {}): void => {
21-
this.current = new RootSiblings(<SnackBar {...props} onAutoDismiss={this.dismiss} />, callback)
16+
_setCurrent = (props: SnackItemType, callback?: Function = () => {}): void => {
17+
const current = new RootSiblings(<SnackBar {...props} onAutoDismiss={this.dismiss} />, () => {
18+
this.current = current
19+
callback()
20+
})
2221
}
2322

2423
_removeCurrent = (callback?: Function = () => {}): void => {
@@ -53,31 +52,34 @@ export default class SnackBarManager {
5352
return
5453
}
5554

56-
this._addCurrent(props, callback)
55+
this._setCurrent(props, callback)
5756
}
5857

59-
show = (title: string, options?: SnackItemType): void => {
58+
show = (
59+
title: string,
60+
options?: SnackItemType,
61+
callback?: Function = () => {}
62+
): void => {
6063
const props = { title, ...options }
6164

62-
if (!this.current) {
63-
this._addCurrent(props)
65+
if (this.current) {
66+
this.queue.unshift(props)
67+
callback()
6468
return
6569
}
6670

67-
this._removeCurrent(() => {
68-
this._addCurrent(props)
69-
})
71+
this._setCurrent(props, callback)
7072
}
7173

7274
dismiss = (callback?: Function = () => {}): void => {
7375
this._removeCurrent(() => {
74-
if (!this._hasQueue()) {
76+
if (!this.queue.length) {
7577
callback()
7678
return
7779
}
7880

7981
const current = this.queue.shift()
80-
this._addCurrent(current, callback)
82+
this._setCurrent(current, callback)
8183
})
8284
}
8385
}

0 commit comments

Comments
 (0)