@olea-bps/base 1.1.9 → 1.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,30 +12,53 @@
12
12
  * limitations under the License.
13
13
  */
14
14
 
15
- import React from 'react';
15
+ import React, { useCallback } from 'react'
16
16
  import {
17
- SafeAreaView,
18
- StyleSheet,
19
- View,
20
- Share,
21
- TouchableOpacity, ActivityIndicator
22
- } from 'react-native';
17
+ BackHandler,
18
+ Platform,
19
+ SafeAreaView,
20
+ StyleSheet,
21
+ View,
22
+ Share,
23
+ TouchableOpacity,
24
+ ActivityIndicator,
25
+ Alert
26
+ } from 'react-native'
23
27
  import { connect } from 'react-redux'
24
28
  import {
25
- Appbar,
26
- Headline,
27
- List,
28
- withTheme,
29
- } from "react-native-paper";
30
- import { withTranslation } from "react-i18next";
31
- import { WebView } from "react-native-webview";
32
- import merge from 'lodash/merge';
29
+ Appbar,
30
+ Headline,
31
+ List,
32
+ withTheme
33
+ } from 'react-native-paper'
34
+ import { withTranslation } from 'react-i18next'
35
+ import { WebView } from 'react-native-webview'
36
+ import { useFocusEffect } from '@react-navigation/native'
37
+ import merge from 'lodash/merge'
33
38
 
34
- import AppbarComponent from '../AppBar';
35
- import AppbarAction from '../AppbarAction';
36
- import IconsOpenasist from '../../libraries/icons-openasist';
39
+ import AppbarComponent from '../AppBar'
40
+ import AppbarAction from '../AppbarAction'
41
+ import IconsOpenasist from '../../libraries/icons-openasist'
37
42
 
38
- import componentStyles from './styles';
43
+ import componentStyles from './styles'
44
+
45
+ // Use the current screen's navigation context, not the search screen's props.
46
+ function RoomWebViewBackHandler ({ onBack }) {
47
+ useFocusEffect(useCallback(() => {
48
+ if (Platform.OS !== 'android') {
49
+ return
50
+ }
51
+
52
+ const subscription = BackHandler.addEventListener('hardwareBackPress', () => {
53
+ onBack()
54
+ return true
55
+ })
56
+
57
+ return () => subscription.remove()
58
+ }, [onBack]))
59
+
60
+ return null
61
+ }
39
62
 
40
63
  /**
41
64
  * Room Detail Component
@@ -49,240 +72,245 @@ import componentStyles from './styles';
49
72
  * - none
50
73
  */
51
74
  class RoomDetailComponent extends React.Component {
52
- static navigationOptions = {
53
- header: null
54
- };
75
+ static navigationOptions = {
76
+ header: null
77
+ }
55
78
 
79
+ state = {
80
+ refreshing: false,
81
+ webview: {
82
+ url: '',
83
+ title: ''
84
+ }
85
+ }
56
86
 
57
- state = {
58
- refreshing: false,
59
- webview: {
60
- url: '',
61
- title: ''
62
- }
63
- };
87
+ // Styles of this component
88
+ styles
64
89
 
65
- // Styles of this component
66
- styles;
90
+ webView = {
91
+ canGoBack: false,
92
+ ref: null
93
+ }
67
94
 
68
- webView = {
69
- canGoBack: false,
70
- ref: null,
71
- };
95
+ constructor (props) {
96
+ super(props)
72
97
 
73
- constructor(props) {
74
- super(props);
98
+ // ------------------------------------------------------------------------
99
+ // PLUGIN FUNCTIONALITY
100
+ // ------------------------------------------------------------------------
75
101
 
76
- // ------------------------------------------------------------------------
77
- // PLUGIN FUNCTIONALITY
78
- // ------------------------------------------------------------------------
102
+ const { pluginStyles, theme } = this.props
103
+ this.styles = componentStyles(theme)
79
104
 
80
- const {pluginStyles, theme} = this.props;
81
- this.styles = componentStyles(theme);
105
+ if (pluginStyles) {
106
+ this.styles = merge(this.styles, pluginStyles)
107
+ }
82
108
 
83
- if (pluginStyles) {
84
- this.styles = merge(this.styles, pluginStyles);
85
- }
109
+ this.styles = StyleSheet.create(this.styles)
86
110
 
87
- this.styles = StyleSheet.create(this.styles);
111
+ // ------------------------------------------------------------------------
112
+ }
88
113
 
89
- // ------------------------------------------------------------------------
90
- }
114
+ handleCloseWebView = () => {
115
+ this.setState({ webview: { title: '', url: '' } })
116
+ }
91
117
 
92
- /**
118
+ /**
93
119
  * Share function for room
94
120
  *
95
121
  * @returns {Promise<void>}
96
122
  * @private
97
123
  */
98
- async _onShare() {
99
- try {
100
- const { room, theme, t } = this.props;
101
- let roomTitle = room.code2017 || room.title;
102
- roomTitle += room.codeDez1 ? ' (' + t('room:old') + ': ' + room.codeDez1 + ')' : '' ;
124
+ async _onShare () {
125
+ try {
126
+ const { room, theme, t } = this.props
127
+ let roomTitle = room.code2017 || room.title
128
+ roomTitle += room.codeDez1 ? ' (' + t('room:old') + ': ' + room.codeDez1 + ')' : ''
103
129
 
104
- let message = t('room:title') + ' - ' + roomTitle +
105
- ((room.building.name) ? "\n" + t('room:building') + ": " + room.building.name : '') +
106
- ((room.building.postaladdress) ? "\n" + t('room:address') + ": " + room.building.postaladdress + ", " + (room.building.postalcode ? "\n" + room.building.postalcode + ' ' + theme.appSettings.defaultCity : '') : '') +
107
- ((room.codeDez1) ? "\n" + t('room:campusFinderLink') + ": " + room.url : '') +
108
- ((room.codeDez1) ? "\n" + t('room:googleMapsLink') + ": " + theme.appSettings.googleMapsUrl + room.building.coordinates.replace(/\s/g,'') : '');
130
+ const message = t('room:title') + ' - ' + roomTitle +
131
+ ((room.building.name) ? '\n' + t('room:building') + ': ' + room.building.name : '') +
132
+ ((room.building.postaladdress) ? '\n' + t('room:address') + ': ' + room.building.postaladdress + ', ' + (room.building.postalcode ? '\n' + room.building.postalcode + ' ' + theme.appSettings.defaultCity : '') : '') +
133
+ ((room.codeDez1) ? '\n' + t('room:campusFinderLink') + ': ' + room.url : '') +
134
+ ((room.codeDez1) ? '\n' + t('room:googleMapsLink') + ': ' + theme.appSettings.googleMapsUrl + room.building.coordinates.replace(/\s/g, '') : '')
109
135
 
110
- const result = await Share.share({
111
- message: message
112
- });
136
+ const result = await Share.share({
137
+ message
138
+ })
113
139
 
114
- if (result.action === Share.sharedAction) {
115
- if (result.activityType) {
116
- // shared with activity type of result.activityType
117
- } else {
118
- // shared
119
- }
120
- } else if (result.action === Share.dismissedAction) {
121
- // dismissed
122
- }
123
- } catch (error) {
124
- alert(error.message);
140
+ if (result.action === Share.sharedAction) {
141
+ if (result.activityType) {
142
+ // shared with activity type of result.activityType
143
+ } else {
144
+ // shared
125
145
  }
126
- };
127
-
146
+ } else if (result.action === Share.dismissedAction) {
147
+ // dismissed
148
+ }
149
+ } catch (error) {
150
+ Alert.alert('', error.message)
151
+ }
152
+ };
128
153
 
129
- /**
154
+ /**
130
155
  * Render room details content
131
156
  *
132
157
  * @returns a view that includes the full name of the room, its building plus address, one button for opening the campus-navigator and one for opening google-maps
133
158
  * @private
134
159
  */
135
- _renderContent = () => {
136
- const { room, t, theme } = this.props;
137
- const { themeStyles } = theme;
138
- const { colors } = theme;
160
+ _renderContent = () => {
161
+ const { room, t, theme } = this.props
162
+ const { themeStyles } = theme
163
+ const { colors } = theme
139
164
 
140
- let roomTitle = room.code2017 || room.title;
141
- roomTitle += room.codeDez1 ? ' (' + t('room:old') + ': ' + room.codeDez1 + ')' : '';
165
+ let roomTitle = room.code2017 || room.title
166
+ roomTitle += room.codeDez1 ? ' (' + t('room:old') + ': ' + room.codeDez1 + ')' : ''
142
167
 
143
- return (
144
- <View style={this.styles.containerInner}>
145
- <Headline style={this.styles.titleHeadline}>{roomTitle}</Headline>
146
- {
147
- room?.building ?? null
148
- ? <>
149
- <List.Item
150
- key="building"
151
- title={t('room:building')}
152
- description={room.building.name}
153
- descriptionStyle={themeStyles.textLighter}
154
- titleStyle={themeStyles.searchDetailTitle}
155
- />
156
- <List.Item
157
- key="address"
158
- title={t('room:address')}
159
- description={
168
+ return (
169
+ <View style={this.styles.containerInner}>
170
+ <Headline style={this.styles.titleHeadline}>{roomTitle}</Headline>
171
+ {
172
+ (room?.building ?? null)
173
+ ? (
174
+ <>
175
+ <List.Item
176
+ key='building'
177
+ title={t('room:building')}
178
+ description={room.building.name}
179
+ descriptionStyle={themeStyles.textLighter}
180
+ titleStyle={themeStyles.searchDetailTitle}
181
+ />
182
+ <List.Item
183
+ key='address'
184
+ title={t('room:address')}
185
+ description={
160
186
  room.building.postaladdress + (
161
- room?.building?.postalcode ?? false
162
- ? "\n" + room.building.postalcode + ' ' + theme.appSettings.defaultCity
163
- : ''
187
+ (room?.building?.postalcode ?? false)
188
+ ? '\n' + room.building.postalcode + ' ' + theme.appSettings.defaultCity
189
+ : ''
164
190
  )
165
191
  }
166
- descriptionStyle={themeStyles.textLighter} titleStyle={themeStyles.searchDetailTitle}
167
- />
192
+ descriptionStyle={themeStyles.textLighter}
193
+ titleStyle={themeStyles.searchDetailTitle}
194
+ />
168
195
  </>
169
- : null
196
+ )
197
+ : null
170
198
  }
171
- <View style={this.styles.buttonContainer} key={'buttonContainer'}>
172
- {
173
- room?.url ?? null
174
- ? <TouchableOpacity
175
- style={{ ...this.styles.button, ...this.styles.campusFinderUrl }}
176
- key={'campusFinderUrl'}
177
- onPress={() => {
178
- this.setState({
179
- webview: {
180
- url: room.url,
181
- title: t('room:campusFinder')
182
- }
183
- })
184
- }}
185
- >
186
- <IconsOpenasist
187
- icon={'map-search'}
188
- size={25}
189
- color={colors.messages.noticeText}
190
- />
191
- <Headline
192
- style={this.styles.buttonText}
193
- >
194
- {t('room:campusFinderLink')}
195
- </Headline>
196
- </TouchableOpacity>
197
- : null
199
+ <View style={this.styles.buttonContainer} key='buttonContainer'>
200
+ {(room?.url ?? null)
201
+ ? (
202
+ <TouchableOpacity
203
+ style={{ ...this.styles.button, ...this.styles.campusFinderUrl }}
204
+ key='campusFinderUrl'
205
+ onPress={() => {
206
+ this.setState({
207
+ webview: {
208
+ url: room.url,
209
+ title: t('room:campusFinder')
198
210
  }
199
- {
200
- room?.building?.coordinates ?? null
201
- ? <TouchableOpacity
202
- style={this.styles.button}
203
- key={'googleMapsUrl'}
204
- onPress={() => {
205
- this.setState({
206
- webview: {
207
- url: theme.appSettings.googleMapsUrl + room.building.coordinates,
208
- title: t('room:googleMaps')
209
- }
210
- })
211
- }}
212
- >
213
- <IconsOpenasist
214
- icon={'location'}
215
- size={25}
216
- color={colors.messages.noticeText}
217
- />
218
- <Headline
219
- style={this.styles.buttonText}
220
- >
221
- {t('room:googleMapsLink')}
222
- </Headline>
223
- </TouchableOpacity>
224
- : null
211
+ })
212
+ }}
213
+ >
214
+ <IconsOpenasist
215
+ icon='map-search'
216
+ size={25}
217
+ color={colors.messages.noticeText}
218
+ />
219
+ <Headline style={this.styles.buttonText}>
220
+ {t('room:campusFinderLink')}
221
+ </Headline>
222
+ </TouchableOpacity>
223
+ )
224
+ : null}
225
+ {(room?.building?.coordinates ?? null)
226
+ ? (
227
+ <TouchableOpacity
228
+ style={this.styles.button}
229
+ key='googleMapsUrl'
230
+ onPress={() => {
231
+ this.setState({
232
+ webview: {
233
+ url: theme.appSettings.googleMapsUrl + room.building.coordinates,
234
+ title: t('room:googleMaps')
225
235
  }
226
- </View>
227
- </View>
228
- );
229
- };
230
-
231
-
232
- render() {
233
- // ------------------------------------------------------------------------
234
- // PLUGIN FUNCTIONALITY
235
- // ------------------------------------------------------------------------
236
- const PluginComponent = this.props.pluginComponent;
237
- if (PluginComponent) {
238
- return <PluginComponent />;
239
- }
240
- // ------------------------------------------------------------------------
241
-
242
- const {themeStyles, customScript} = this.props.theme;
243
- const {t} = this.props;
244
- const {title, url} = this.state.webview;
245
- const {colors} = this.props.theme;
236
+ })
237
+ }}
238
+ >
239
+ <IconsOpenasist
240
+ icon='location'
241
+ size={25}
242
+ color={colors.messages.noticeText}
243
+ />
244
+ <Headline style={this.styles.buttonText}>
245
+ {t('room:googleMapsLink')}
246
+ </Headline>
247
+ </TouchableOpacity>
248
+ )
249
+ : null}
250
+ </View>
251
+ </View>
252
+ )
253
+ }
246
254
 
247
- if(title && url) {
248
- return (
249
- <SafeAreaView style={[this.styles.container, themeStyles.safeAreaContainer]}>
250
- <AppbarComponent {...this.props}
251
- title={title}
252
- leftAction={<Appbar.Action
253
- icon={props => <IconsOpenasist {...props} icon={'back'} color={colors.primaryText} /> }
254
- onPress={() => this.setState({webview: {title: '', url: ''}})} />}/>
255
- <WebView
256
- ref={ref => this.webView.ref = ref}
257
- source={{uri: url}}
258
- injectedJavaScript={customScript}
259
- startInLoadingState={true}
260
- renderLoading={() => <ActivityIndicator style={this.styles.activity} size="large" color={colors.loadingIndicator}/>}
261
- onNavigationStateChange={(navState) => { this.webView.canGoBack = navState.canGoBack; }}
262
- />
263
- </SafeAreaView>
264
- );
265
- }
255
+ render () {
256
+ // ------------------------------------------------------------------------
257
+ // PLUGIN FUNCTIONALITY
258
+ // ------------------------------------------------------------------------
259
+ const PluginComponent = this.props.pluginComponent
260
+ if (PluginComponent) {
261
+ return <PluginComponent />
262
+ }
263
+ // ------------------------------------------------------------------------
266
264
 
265
+ const { themeStyles, customScript } = this.props.theme
266
+ const { t } = this.props
267
+ const { title, url } = this.state.webview
268
+ const { colors } = this.props.theme
267
269
 
268
- return (
269
- <SafeAreaView style={[this.styles.container, themeStyles.safeAreaContainer]}>
270
- <AppbarComponent
271
- {...this.props}
272
- title={t('room:directory')}
273
- rightAction={<AppbarAction icon='share' onPress={this._onShare.bind(this)} />}
274
- />
275
- {this._renderContent()}
276
- </SafeAreaView>
277
- );
270
+ if (title && url) {
271
+ return (
272
+ <SafeAreaView style={[this.styles.container, themeStyles.safeAreaContainer]}>
273
+ <RoomWebViewBackHandler onBack={this.handleCloseWebView} />
274
+ <AppbarComponent
275
+ {...this.props}
276
+ title={title}
277
+ leftAction={<Appbar.Action
278
+ icon={props => <IconsOpenasist {...props} icon='back' color={colors.primaryText} />}
279
+ onPress={this.handleCloseWebView}
280
+ />}
281
+ />
282
+ <WebView
283
+ ref={ref => {
284
+ this.webView.ref = ref
285
+ }}
286
+ source={{ uri: url }}
287
+ injectedJavaScript={customScript}
288
+ startInLoadingState
289
+ renderLoading={() => <ActivityIndicator style={this.styles.activity} size='large' color={colors.loadingIndicator} />}
290
+ onNavigationStateChange={(navState) => { this.webView.canGoBack = navState.canGoBack }}
291
+ />
292
+ </SafeAreaView>
293
+ )
278
294
  }
295
+
296
+ return (
297
+ <SafeAreaView style={[this.styles.container, themeStyles.safeAreaContainer]}>
298
+ <AppbarComponent
299
+ {...this.props}
300
+ title={t('room:directory')}
301
+ rightAction={<AppbarAction icon='share' onPress={this._onShare.bind(this)} />}
302
+ />
303
+ {this._renderContent()}
304
+ </SafeAreaView>
305
+ )
306
+ }
279
307
  }
280
308
 
281
309
  const mapStateToProps = state => {
282
- return {
283
- pluginComponent: state.pluginReducer.roomDirectory.component,
284
- pluginStyles: state.pluginReducer.roomDirectory.styles,
285
- };
286
- };
310
+ return {
311
+ pluginComponent: state.pluginReducer.roomDirectory.component,
312
+ pluginStyles: state.pluginReducer.roomDirectory.styles
313
+ }
314
+ }
287
315
 
288
316
  export default connect(mapStateToProps, null)(withTranslation()(withTheme(RoomDetailComponent)))