@olea-bps/components 1.0.0

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.
Files changed (79) hide show
  1. package/AppBar/index.js +83 -0
  2. package/AppBar/styles.js +27 -0
  3. package/BookDetail/index.js +268 -0
  4. package/BookDetail/styles.js +124 -0
  5. package/Component/342/200/216JobsFilter/index.js +188 -0
  6. package/Component/342/200/216JobsFilter/styles.js +12 -0
  7. package/ConnectivityWarning/index.js +65 -0
  8. package/ConnectivityWarning/styles.js +19 -0
  9. package/ContactDetail/index.js +232 -0
  10. package/ContactDetail/styles.js +32 -0
  11. package/CourseDetail/index.js +357 -0
  12. package/CourseDetail/styles.js +59 -0
  13. package/CourseDetailDialog/index.js +169 -0
  14. package/CourseDetailDialog/styles.js +116 -0
  15. package/CourseInfo/index.js +219 -0
  16. package/CourseInfo/styles.js +40 -0
  17. package/DevelopmentDialog/index.js +208 -0
  18. package/DevelopmentDialog/styles.js +10 -0
  19. package/EventCodeInput/index.js +146 -0
  20. package/EventCodeInput/styles.js +108 -0
  21. package/FlexMenuEntry/index.js +84 -0
  22. package/FlexMenuEntry/styles.js +27 -0
  23. package/MainMenuEntry/index.js +88 -0
  24. package/MainMenuEntry/styles.js +28 -0
  25. package/MealItem/index.js +87 -0
  26. package/MealItem/styles.js +73 -0
  27. package/MensaMenu/index.js +307 -0
  28. package/MensaMenu/styles.js +94 -0
  29. package/MensaSlider/index.js +184 -0
  30. package/MensaSlider/styles.js +53 -0
  31. package/Modal/index.js +106 -0
  32. package/Modal/styles.js +8 -0
  33. package/NewsDetail/index.js +377 -0
  34. package/NewsDetail/styles.js +77 -0
  35. package/NewsList/index.js +120 -0
  36. package/NewsList/styles.js +19 -0
  37. package/NewsListItem/index.js +89 -0
  38. package/NewsListItem/styles.js +32 -0
  39. package/OtherCourses/index.js +152 -0
  40. package/OtherCourses/styles.js +10 -0
  41. package/PtsDeparture/index.js +140 -0
  42. package/PtsDeparture/styles.js +7 -0
  43. package/PtsStation/index.js +183 -0
  44. package/PtsStation/styles.js +47 -0
  45. package/QuickLinks/index.js +127 -0
  46. package/QuickLinks/styles.js +45 -0
  47. package/RoomDetail/index.js +281 -0
  48. package/RoomDetail/styles.js +56 -0
  49. package/ScaledImage/index.js +92 -0
  50. package/SearchResults/index.js +362 -0
  51. package/SearchResults/styles.js +59 -0
  52. package/SettingSection/index.js +54 -0
  53. package/SettingSection/styles.js +15 -0
  54. package/SettingsDialog/index.js +52 -0
  55. package/SettingsDialog/styles.js +12 -0
  56. package/SettingsDialogRadio/index.js +66 -0
  57. package/SettingsDialogRadio/styles.js +7 -0
  58. package/SettingsDialogSelect/index.js +73 -0
  59. package/SettingsDialogSelect/styles.js +7 -0
  60. package/TimetableCodeInput/index.js +201 -0
  61. package/TimetableCodeInput/styles.js +28 -0
  62. package/TimetableDay/index.js +266 -0
  63. package/TimetableDay/styles.js +103 -0
  64. package/TimetableEvent/index.js +163 -0
  65. package/TimetableEvent/styles.js +108 -0
  66. package/TimetableList/index.js +116 -0
  67. package/TimetableList/styles.js +109 -0
  68. package/TimetableMonth/index.js +156 -0
  69. package/TimetableMonth/styles.js +29 -0
  70. package/TimetableWeek/index.js +245 -0
  71. package/TimetableWeek/styles.js +58 -0
  72. package/TopNews/index.js +282 -0
  73. package/TopNews/styles.js +125 -0
  74. package/TopNewsHtwk/index.js +279 -0
  75. package/TopNewsHtwk/styles.js +142 -0
  76. package/WebView/index.js +108 -0
  77. package/WebView/styles.js +11 -0
  78. package/index.js +39 -0
  79. package/package.json +37 -0
@@ -0,0 +1,19 @@
1
+ export default function(theme) {
2
+ return {
3
+ container: {
4
+ flex: 1
5
+ },
6
+ innerContainer: {
7
+ flex: 1,
8
+ },
9
+ activity: {
10
+ margin: 40
11
+ },
12
+ listSeperator: {
13
+ height: 1,
14
+ backgroundColor: theme.colors.listSeperator,
15
+ marginLeft: 20,
16
+ marginRight: 20
17
+ },
18
+ }
19
+ };
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * You may obtain a copy of the License at
5
+ *
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS,
10
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * See the License for the specific language governing permissions and
12
+ * limitations under the License.
13
+ */
14
+
15
+ import { useMemo } from 'react';
16
+ import {
17
+ Text,
18
+ StyleSheet,
19
+ View,
20
+ TouchableOpacity,
21
+ Image,
22
+ } from 'react-native';
23
+
24
+ import { useTheme } from 'react-native-paper';
25
+ import { useTranslation } from 'react-i18next';
26
+ import { useNavigation } from '@react-navigation/native';
27
+
28
+ import { DateTime } from 'luxon';
29
+
30
+ import { useLanguage } from '@olea-bps/core';
31
+ import IconsOpenasist from '@olea-bps/icons-openasist';
32
+
33
+ import componentStyles from './styles';
34
+
35
+ export default function NewsListItem({ news }) {
36
+ const componentName = NewsListItem.name;
37
+ const language = useLanguage();
38
+ const { t } = useTranslation();
39
+ const theme = useTheme()
40
+ const { themeStyles, colors, fontSizes } = theme;
41
+ const navigation = useNavigation();
42
+
43
+ const styles = useMemo(
44
+ () => StyleSheet.create(componentStyles(theme)),
45
+ [theme, componentStyles]
46
+ );
47
+
48
+ const description = news.shortDesc
49
+ .replace(/<(?:.|\n)*?>/gm, '')
50
+ .replace('Weiterlesen ›', '');
51
+
52
+ console.debug(componentName, ':', `news ${news?.guid} pub date`, ':', news.pubdate);
53
+ const publicationDate = news?.pubdate
54
+ ? DateTime.fromISO(news.pubdate, { locale: language }).toLocaleString(DateTime.DATETIME_SHORT)
55
+ : null;
56
+
57
+ return (
58
+ <TouchableOpacity
59
+ onPress={() => navigation.navigate('NewsDetail', { news: news })}
60
+ accessible={true}
61
+ accessibilityLabel={t('accessibility:feedNewsItem', { news: [news.title, description].join('. '), date: publicationDate })}
62
+ accessibilityHint={t('accessibility:feedNewsItemHint')}
63
+ >
64
+ <View style={themeStyles.flexRow}>
65
+ <View style={[themeStyles.cardContent, styles.contentContainer]}>
66
+ {
67
+ news?.imageUrl
68
+ ? <Image
69
+ source={{ uri: news.imageUrl }}
70
+ resizeMode="cover"
71
+ style={styles.image}>
72
+ </Image>
73
+ : null
74
+ }
75
+ <Text style={styles.title}>{news.title}</Text>
76
+ <Text style={styles.description}>{description}</Text>
77
+ {
78
+ publicationDate
79
+ ? <View style={[themeStyles.flexRow, { alignItems: 'center', alignContent: 'center' }]}>
80
+ <IconsOpenasist icon={'time'} size={fontSizes.l} color={colors.iconSubtitle} />
81
+ <Text style={[themeStyles.cardSubTitle, styles.publicationDate]}>{publicationDate}</Text>
82
+ </View>
83
+ : null
84
+ }
85
+ </View>
86
+ </View>
87
+ </TouchableOpacity>
88
+ );
89
+ }
@@ -0,0 +1,32 @@
1
+ export default function(theme) {
2
+ return {
3
+ contentContainer: {
4
+ paddingTop: theme.paddings.default,
5
+ paddingLeft: theme.paddings.default,
6
+ paddingRight: theme.paddings.default,
7
+ marginBottom: theme.paddings.default
8
+ },
9
+ publicationDate: {
10
+ ...theme.fonts.bold,
11
+ marginTop: 3,
12
+ paddingLeft: theme.paddings.small,
13
+ },
14
+ image: {
15
+ aspectRatio: 16/9,
16
+ paddingBottom: theme.paddings.small,
17
+ },
18
+ title: {
19
+ ...theme.fonts.bold,
20
+ fontSize: theme.fontSizes.subtitle,
21
+ lineHeight: theme.lineHeights.titleSmall,
22
+ marginTop: theme.paddings.default,
23
+ marginBottom: theme.paddings.small,
24
+ },
25
+ description: {
26
+ ...theme.fonts.regular,
27
+ fontSize: theme.fontSizes.itemText,
28
+ lineHeight: theme.lineHeights.s,
29
+ marginBottom: theme.paddings.small,
30
+ }
31
+ }
32
+ };
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * You may obtain a copy of the License at
5
+ *
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS,
10
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * See the License for the specific language governing permissions and
12
+ * limitations under the License.
13
+ */
14
+
15
+ import React from 'react';
16
+ import PropTypes from 'prop-types';
17
+
18
+ import {
19
+ ScrollView,
20
+ StyleSheet,
21
+ Text,
22
+ View,
23
+ SafeAreaView,
24
+ } from 'react-native';
25
+ import { Appbar, withTheme } from 'react-native-paper';
26
+
27
+ import { connect } from 'react-redux'
28
+ import { withTranslation } from 'react-i18next';
29
+
30
+ import merge from 'lodash/merge';
31
+
32
+ import { AppBar as AppbarComponent } from '@olea-bps/components';
33
+ import IconsOpenasist from '@olea-bps/icons-openasist';
34
+ import { TimetableList as TimetableListComponent } from '@olea-bps/components';
35
+
36
+ import componentStyles from './styles'
37
+
38
+ /**
39
+ * Course Detail Component
40
+ *
41
+ * Shows the detailed information of a course with room, time, lecturer and so on.
42
+ * Provides a share functionality.
43
+ *
44
+ * Parameters:
45
+ * - course: Course object with all information about the course
46
+ *
47
+ * Navigation-Parameters:
48
+ * - none
49
+ */
50
+ class OtherCoursesComponent extends React.Component {
51
+ static propTypes = {
52
+ course: PropTypes.array
53
+ };
54
+
55
+ // Styles of this component
56
+ styles;
57
+
58
+ course = null;
59
+
60
+ constructor(props) {
61
+ super(props);
62
+
63
+ // ------------------------------------------------------------------------
64
+ // PLUGIN FUNCTIONALITY
65
+ // ------------------------------------------------------------------------
66
+
67
+ const { pluginStyles, theme } = this.props;
68
+ this.styles = componentStyles(theme);
69
+
70
+ if (pluginStyles) {
71
+ this.styles = merge(componentStyles, pluginStyles);
72
+ }
73
+
74
+ this.styles = StyleSheet.create(this.styles);
75
+
76
+ // ------------------------------------------------------------------------
77
+ };
78
+
79
+ _renderList = () => {
80
+ var renderList = this.course?.map((course, courseIndex) =>
81
+ <TimetableListComponent
82
+ {...this.props}
83
+ key={'course_' + courseIndex}
84
+ course={course}
85
+ times={null} />
86
+ ) ?? [];
87
+
88
+ return (
89
+ <View style={this.styles.renderList}>
90
+ {renderList}
91
+ </View>
92
+ );
93
+ };
94
+
95
+ _renderContent = () => {
96
+ const { themeStyles } = this.props.theme;
97
+ return (
98
+ <View style={themeStyles.container}>
99
+ <ScrollView>
100
+ {this._renderList()}
101
+ </ScrollView>
102
+ </View>
103
+ );
104
+ };
105
+
106
+ render() {
107
+ // ------------------------------------------------------------------------
108
+ // PLUGIN FUNCTIONALITY
109
+ // ------------------------------------------------------------------------
110
+ const PluginComponent = this.props.pluginComponent;
111
+ if (PluginComponent) {
112
+ return <PluginComponent />;
113
+ }
114
+ // ------------------------------------------------------------------------
115
+
116
+ const { themeStyles } = this.props.theme;
117
+ const { course, t } = this.props;
118
+ const { colors } = this.props.theme;
119
+
120
+ if (!course) {
121
+ return (
122
+ <SafeAreaView style={[this.styles.container, themeStyles.safeAreaContainer]}>
123
+ <AppbarComponent {...this.props}
124
+ title={t('timetable:moreEvents')}
125
+ leftAction={<Appbar.Action
126
+ icon={props => <IconsOpenasist {...props} icon={'down'} color={colors.primaryText} />}
127
+ onPress={() => {
128
+ this.props.navigation.goBack(null);
129
+ }} />} />
130
+ <Text>{t('course:couldNotLoad')}</Text>
131
+ </SafeAreaView>
132
+ );
133
+ } else if (!this.course) {
134
+ this.course = course;
135
+ }
136
+
137
+ return (
138
+ <SafeAreaView style={[this.styles.container, themeStyles.safeAreaContainer]}>
139
+ <AppbarComponent {...this.props}
140
+ title={t('timetable:moreEvents')}
141
+ leftAction={<Appbar.Action
142
+ icon={props => <IconsOpenasist {...props} icon={'down'} color={colors.primaryText} />}
143
+ onPress={() => {
144
+ this.props.navigation.goBack(null);
145
+ }} />} />
146
+ {this._renderContent()}
147
+ </SafeAreaView>
148
+ );
149
+ }
150
+ }
151
+
152
+ export default withTranslation()(withTheme(OtherCoursesComponent))
@@ -0,0 +1,10 @@
1
+ export default function(theme) {
2
+ return {
3
+ container: {
4
+ flex: 1
5
+ },
6
+ renderList: {
7
+ marginBottom: theme.paddings.small
8
+ },
9
+ };
10
+ }
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * You may obtain a copy of the License at
5
+ *
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS,
10
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * See the License for the specific language governing permissions and
12
+ * limitations under the License.
13
+ */
14
+
15
+ import React from 'react';
16
+ import PropTypes from 'prop-types';
17
+
18
+ import { StyleSheet, Text } from 'react-native';
19
+ import {List, withTheme} from "react-native-paper";
20
+ import {withTranslation} from "react-i18next";
21
+ import { connect } from 'react-redux'
22
+ import merge from 'lodash/merge';
23
+
24
+ import componentStyles from "./styles"
25
+ import IconsOpenasist from "@olea-bps/icons-openasist";
26
+
27
+
28
+
29
+ class PtsDepartureComponent extends React.Component {
30
+ static propTypes = {
31
+ departure: PropTypes.object.isRequired,
32
+ currentTime: PropTypes.object.isRequired
33
+ };
34
+
35
+ // Styles of this component
36
+ styles;
37
+
38
+ constructor(props) {
39
+ super(props);
40
+ // ------------------------------------------------------------------------
41
+ // PLUGIN FUNCTIONALITY
42
+ // ------------------------------------------------------------------------
43
+
44
+ const { pluginStyles,theme } = this.props;
45
+ this.styles = componentStyles(theme);
46
+
47
+ if(pluginStyles) {
48
+ this.styles = merge(componentStyles, pluginStyles);
49
+ }
50
+
51
+ this.styles = StyleSheet.create(this.styles);
52
+ // ------------------------------------------------------------------------
53
+ };
54
+
55
+ /**
56
+ * Convert the timestamp to a string with the time to departure
57
+ *
58
+ * @param timestamp
59
+ * @returns {string}
60
+ * @private
61
+ */
62
+ _getDepartureTime(timestamp, asObject = false) {
63
+ let { currentTime, t } = this.props;
64
+ let departureTime = new Date(timestamp);
65
+
66
+ if(departureTime - currentTime <= 0 && !asObject) {
67
+ return <Text style={this.styles.departureExceeded}>{t('pts:isDeparted')}</Text>;
68
+ }
69
+
70
+ let minutesToDeparture = Math.floor((departureTime - currentTime) / 1000 / 60);
71
+
72
+
73
+ let departureHour = departureTime.getHours() > 9 ? departureTime.getHours() : '0' + departureTime.getHours();
74
+ let departureMinutes = departureTime.getMinutes() > 9 ? departureTime.getMinutes() : '0' + departureTime.getMinutes();
75
+
76
+ if(asObject) {
77
+ return {
78
+ time: departureHour + ':' + departureMinutes,
79
+ accessibilityLabelTime: departureHour + ' ' + t('accessibility:pts:speechTime') + departureMinutes,
80
+ minutesUntilDeparture: minutesToDeparture,
81
+ isDeparted: minutesToDeparture <= 0
82
+ }
83
+ }
84
+
85
+ return departureHour + ':' + departureMinutes +
86
+ ((minutesToDeparture > 0) ? ' ' + t('common:time') + ' - ' : '') +
87
+ ((minutesToDeparture > 0) ? minutesToDeparture + t('common:minutes') + ' ' : '');
88
+
89
+ }
90
+
91
+
92
+ render() {
93
+ // ------------------------------------------------------------------------
94
+ // PLUGIN FUNCTIONALITY
95
+ // ------------------------------------------------------------------------
96
+ const PluginComponent = this.props.pluginComponent;
97
+ if (PluginComponent) {
98
+ return <PluginComponent />;
99
+ }
100
+ // ------------------------------------------------------------------------
101
+
102
+ const { departure, t } = this.props;
103
+ const {colors} = this.props.theme;
104
+ const departureTime = this._getDepartureTime(departure.departureTime, true);
105
+ const departureDetails = {
106
+ time:departureTime.accessibilityLabelTime,
107
+ direction: departure.direction,
108
+ line: departure.number,
109
+ type: departure.type.toUpperCase() === 'TRAM' ? t('pts:tram') : t('pts:bus'),
110
+ minutes:departureTime.minutesUntilDeparture
111
+ };
112
+
113
+ return (
114
+ <List.Item
115
+ title={this._getDepartureTime(departure.departureTime)}
116
+ description={t('pts:direction') + ": " + departure.direction + "\n" + t('pts:line') + ": " + departure.number}
117
+ left={props => <List.Icon {...props}
118
+ style={{paddingTop: 4, backgroundColor: (departure.type.toUpperCase() === 'TRAM' ? colors.primary : colors.secondary)}}
119
+ color={(departure.type.toUpperCase() === 'TRAM' ? colors.primaryText : colors.secondaryText)}
120
+ icon={ props => <IconsOpenasist icon={(departure.type.toUpperCase() === 'TRAM' ? 'tram': 'bus')} size={30}/>}
121
+ />}
122
+ accessible={true}
123
+ accessibilityLabel={departureTime.isDeparted ?
124
+ t('accessibility:pts.isDeparted', departureDetails) :
125
+ t('accessibility:pts.departureTime', departureDetails)}
126
+ accessibilityHint={departureTime.isDeparted ? '' : t('accessibility:pts.minutesUntilDeparture', departureDetails)}
127
+ />
128
+ );
129
+ }
130
+ }
131
+
132
+
133
+ const mapStateToProps = state => {
134
+ return {
135
+ pluginComponent: state.pluginReducer.ptsDeparture.component,
136
+ pluginStyles: state.pluginReducer.ptsDeparture.styles
137
+ };
138
+ };
139
+
140
+ export default connect(mapStateToProps, null)(withTranslation()(withTheme(PtsDepartureComponent)))
@@ -0,0 +1,7 @@
1
+ export default function(theme) {
2
+ return {
3
+ departureExceeded: {
4
+ color: 'red'
5
+ }
6
+ };
7
+ }
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * You may obtain a copy of the License at
5
+ *
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Unless required by applicable law or agreed to in writing, software
9
+ * distributed under the License is distributed on an "AS IS" BASIS,
10
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ * See the License for the specific language governing permissions and
12
+ * limitations under the License.
13
+ */
14
+
15
+ import React from 'react';
16
+ import PropTypes from 'prop-types';
17
+
18
+ import {StyleSheet, TouchableOpacity} from 'react-native';
19
+ import {Card, IconButton, withTheme} from "react-native-paper";
20
+ import {withTranslation} from "react-i18next";
21
+ import {connect} from 'react-redux'
22
+ import concat from "lodash/concat";
23
+ import merge from 'lodash/merge';
24
+
25
+ import {onSettingPtsStationOverride, store} from "@olea-bps/core";
26
+ import { PtsDeparture as PtsDepartureComponent } from '@olea-bps/components';
27
+ import IconsOpenasist from "@olea-bps/icons-openasist";
28
+
29
+ import componentStyles from "./styles"
30
+
31
+ /**
32
+ * PTS Station Component
33
+ *
34
+ * Shows a single station with a list of its departure times and directions
35
+ *
36
+ * Parameters:
37
+ * - station: Station object with all information about it
38
+ * - currentTime: Date object of the current time (to prevent different times across all components)
39
+ *
40
+ * Navigation-Parameters:
41
+ * - none
42
+ */
43
+ class PtsStationComponent extends React.Component {
44
+ static propTypes = {
45
+ station: PropTypes.object.isRequired,
46
+ currentTime: PropTypes.object.isRequired
47
+ };
48
+
49
+ // Styles of this component
50
+ styles;
51
+
52
+
53
+
54
+ constructor(props) {
55
+ super(props);
56
+ this.state = {
57
+ inProgress: true
58
+ };
59
+ // ------------------------------------------------------------------------
60
+ // PLUGIN FUNCTIONALITY
61
+ // ------------------------------------------------------------------------
62
+
63
+ const { pluginStyles,theme } = this.props;
64
+ this.styles = componentStyles(theme);
65
+
66
+ if(pluginStyles) {
67
+ this.styles = merge(componentStyles, pluginStyles);
68
+ }
69
+
70
+ this.styles = StyleSheet.create(this.styles);
71
+
72
+ // ------------------------------------------------------------------------
73
+ };
74
+
75
+ /**
76
+ * update the favorite station for given station id
77
+ *
78
+ * @param selectedItemId
79
+ * @private
80
+ */
81
+ _updateFavoriteState = (selectedItemId) => {
82
+ const favorites = this.props.settings.favoritesPtsStation;
83
+
84
+ if (favorites && favorites.includes && favorites.includes(selectedItemId)) {
85
+ const newFavoriteArray = favorites.filter(function (itemId) {
86
+ return selectedItemId !== itemId;
87
+ });
88
+ store.dispatch(onSettingPtsStationOverride('favorites', newFavoriteArray));
89
+ } else {
90
+ store.dispatch(onSettingPtsStationOverride('favorites', concat(favorites, [selectedItemId])));
91
+ }
92
+ };
93
+
94
+ /**
95
+ * Render each departure
96
+ *
97
+ * @param departures
98
+ * @returns {*}
99
+ * @private
100
+ */
101
+ _renderDepartures(departures) {
102
+ if(departures.length === 0)
103
+ return;
104
+
105
+ let output = [];
106
+ departures.forEach((departure, index) => {
107
+ if(departure) {
108
+ output.push(<PtsDepartureComponent key={index + '_' + departure.number + ' ' + departure.departureTime + ' ' + departure.direction}
109
+ departure={departure} currentTime={this.props.currentTime} />);
110
+ }
111
+ });
112
+ return output;
113
+ }
114
+
115
+
116
+ render() {
117
+ // ------------------------------------------------------------------------
118
+ // PLUGIN FUNCTIONALITY
119
+ // ------------------------------------------------------------------------
120
+ const PluginComponent = this.props.pluginComponent;
121
+ if (PluginComponent) {
122
+ return <PluginComponent />;
123
+ }
124
+ // ------------------------------------------------------------------------
125
+
126
+ const { station, t, editMode } = this.props;
127
+ const {colors} = this.props.theme;
128
+ const {favoritesPtsStation} = this.props.settings;
129
+
130
+ const isFavorite = favoritesPtsStation && favoritesPtsStation.includes && favoritesPtsStation.includes(station.id);
131
+ const accessibilityHint = isFavorite ?
132
+ t('accessibility:pts.isFavorite') :
133
+ t('accessibility:pts.isNotFavorite');
134
+
135
+ return (
136
+ <Card>
137
+ <Card.Title title={station.name}
138
+ subtitle={t('pts:distance') + ": " + (Math.round(station.distance * 100) / 100) + ' ' + t('pts:meter')}
139
+ right={(props) =>
140
+ editMode ?
141
+ <TouchableOpacity
142
+ style={this.styles.starIcon}
143
+ onPress={() => {this._updateFavoriteState(station.id); setTimeout(() => {this.props.refresh()}, 200);}}
144
+ accessibilityLabel={station.name}
145
+ accessibilityHint={editMode ? accessibilityHint : ''}
146
+ accessibilityRole={'button'}
147
+ accessibilityState={editMode ? {selected: isFavorite} : null}
148
+ >
149
+ <IconsOpenasist
150
+ icon={isFavorite ? "star-selected" : "star"}
151
+ size={25}
152
+ color={colors.icon}
153
+ />
154
+ </TouchableOpacity> :
155
+ <IconButton
156
+ {...props}
157
+ icon="crosshairs-gps"
158
+ onPress={() => {
159
+ if(this.props.routeButtonPressed) {
160
+ this.props.routeButtonPressed(station.latitude, station.longitude);
161
+ }
162
+ }}
163
+ accessibilityLabel={',' + t('accessibility:pts.centerLocation')}
164
+ />
165
+ }/>
166
+ <Card.Content>
167
+ {this._renderDepartures(station.departures)}
168
+ </Card.Content>
169
+ </Card>
170
+ );
171
+ }
172
+ }
173
+
174
+
175
+ const mapStateToProps = state => {
176
+ return {
177
+ pluginComponent: state.pluginReducer.ptsStation.component,
178
+ pluginStyles: state.pluginReducer.ptsStation.styles,
179
+ settings: state.settingReducer
180
+ };
181
+ };
182
+
183
+ export default connect(mapStateToProps, null)(withTranslation()(withTheme(PtsStationComponent)))
@@ -0,0 +1,47 @@
1
+ export default function(theme) {
2
+ return {
3
+ container: {
4
+ flex: 1,
5
+ },
6
+ containerInner: {
7
+ flex: 1,
8
+ paddingHorizontal: 20,
9
+ paddingVertical: 20
10
+ },
11
+ activity: {
12
+ marginTop: 20
13
+ },
14
+ badges: {
15
+ flexDirection: 'row',
16
+ flexWrap: 'wrap',
17
+ paddingHorizontal: 10
18
+ },
19
+ badge: {
20
+ marginRight: 5,
21
+ marginBottom: 5
22
+ },
23
+ bookHeader: {
24
+ flex: 0,
25
+ flexDirection: 'row',
26
+ marginBottom: 20
27
+ },
28
+ bookImage: {
29
+ flex: 0.4,
30
+ maxHeight: 300
31
+ },
32
+ bookTitle: {
33
+ flex: 0.6,
34
+ paddingLeft: 15
35
+ },
36
+ bookDetails: {
37
+ flex: 1,
38
+ flexDirection: 'column'
39
+ },
40
+ holdingBranch: {
41
+ flexWrap: 'wrap'
42
+ },
43
+ starIcon: {
44
+ marginRight: theme.paddings.default
45
+ }
46
+ };
47
+ }