@olea-bps/base 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 (268) hide show
  1. package/components/AppBar/index.js +84 -0
  2. package/components/AppBar/styles.js +27 -0
  3. package/components/BookDetail/index.js +268 -0
  4. package/components/BookDetail/styles.js +124 -0
  5. package/components/ComponentJobsFilter/index.js +188 -0
  6. package/components/ComponentJobsFilter/styles.js +12 -0
  7. package/components/ConnectivityWarning/index.js +65 -0
  8. package/components/ConnectivityWarning/styles.js +19 -0
  9. package/components/ContactDetail/index.js +232 -0
  10. package/components/ContactDetail/styles.js +32 -0
  11. package/components/CourseDetail/index.js +357 -0
  12. package/components/CourseDetail/styles.js +59 -0
  13. package/components/CourseDetailDialog/index.js +169 -0
  14. package/components/CourseDetailDialog/styles.js +116 -0
  15. package/components/CourseInfo/index.js +219 -0
  16. package/components/CourseInfo/styles.js +40 -0
  17. package/components/DevelopmentDialog/index.js +214 -0
  18. package/components/DevelopmentDialog/styles.js +10 -0
  19. package/components/EventCodeInput/index.js +149 -0
  20. package/components/EventCodeInput/styles.js +108 -0
  21. package/components/FlexMenuEntry/index.js +84 -0
  22. package/components/FlexMenuEntry/styles.js +27 -0
  23. package/components/MainMenuEntry/index.js +88 -0
  24. package/components/MainMenuEntry/styles.js +28 -0
  25. package/components/MealItem/index.js +87 -0
  26. package/components/MealItem/styles.js +84 -0
  27. package/components/MensaMenu/index.js +305 -0
  28. package/components/MensaMenu/styles.js +94 -0
  29. package/components/MensaSlider/index.js +188 -0
  30. package/components/MensaSlider/styles.js +53 -0
  31. package/components/Modal/index.js +106 -0
  32. package/components/Modal/styles.js +8 -0
  33. package/components/NewsDetail/index.js +377 -0
  34. package/components/NewsDetail/styles.js +77 -0
  35. package/components/NewsList/index.js +120 -0
  36. package/components/NewsList/styles.js +19 -0
  37. package/components/NewsListItem/index.js +89 -0
  38. package/components/NewsListItem/styles.js +32 -0
  39. package/components/OtherCourses/index.js +152 -0
  40. package/components/OtherCourses/styles.js +10 -0
  41. package/components/PtsDeparture/index.js +140 -0
  42. package/components/PtsDeparture/styles.js +7 -0
  43. package/components/PtsStation/index.js +186 -0
  44. package/components/PtsStation/styles.js +47 -0
  45. package/components/QuickLinks/index.js +127 -0
  46. package/components/QuickLinks/styles.js +45 -0
  47. package/components/RoomDetail/index.js +281 -0
  48. package/components/RoomDetail/styles.js +56 -0
  49. package/components/ScaledImage/index.js +92 -0
  50. package/components/SearchResults/index.js +362 -0
  51. package/components/SearchResults/styles.js +59 -0
  52. package/components/SettingSection/index.js +54 -0
  53. package/components/SettingSection/styles.js +15 -0
  54. package/components/SettingsDialog/index.js +52 -0
  55. package/components/SettingsDialog/styles.js +12 -0
  56. package/components/SettingsDialogRadio/index.js +66 -0
  57. package/components/SettingsDialogRadio/styles.js +7 -0
  58. package/components/SettingsDialogSelect/index.js +73 -0
  59. package/components/SettingsDialogSelect/styles.js +7 -0
  60. package/components/TimetableCodeInput/index.js +205 -0
  61. package/components/TimetableCodeInput/styles.js +28 -0
  62. package/components/TimetableDay/index.js +252 -0
  63. package/components/TimetableDay/styles.js +103 -0
  64. package/components/TimetableEvent/index.js +163 -0
  65. package/components/TimetableEvent/styles.js +108 -0
  66. package/components/TimetableList/index.js +180 -0
  67. package/components/TimetableList/styles.js +106 -0
  68. package/components/TimetableMonth/index.js +156 -0
  69. package/components/TimetableMonth/styles.js +29 -0
  70. package/components/TimetableWeek/index.js +230 -0
  71. package/components/TimetableWeek/styles.js +58 -0
  72. package/components/TopNews/index.js +282 -0
  73. package/components/TopNews/styles.js +125 -0
  74. package/components/TopNewsHtwk/index.js +279 -0
  75. package/components/TopNewsHtwk/styles.js +142 -0
  76. package/components/WebView/index.js +108 -0
  77. package/components/WebView/styles.js +11 -0
  78. package/context/context-callmanager/TucCallManager.js +74 -0
  79. package/context/context-callmanager/index.js +128 -0
  80. package/context/context-canteen/AsistServerApiProvider.js +126 -0
  81. package/context/context-canteen/CollektorVersion2ApiProvider.js +100 -0
  82. package/context/context-canteen/index.js +692 -0
  83. package/context/context-connectivity/index.js +85 -0
  84. package/context/context-event/AsistServerClient.js +82 -0
  85. package/context/context-event/index.js +205 -0
  86. package/context/context-flex-menu/AsistServerApiProvider.js +0 -0
  87. package/context/context-flex-menu/CollectorVersion2ApiProvider.js +32 -0
  88. package/context/context-flex-menu/index.js +160 -0
  89. package/context/context-info-dialog/CollektorVersion2ApiProvider.js +53 -0
  90. package/context/context-info-dialog/ProviderErrors.js +22 -0
  91. package/context/context-info-dialog/index.js +190 -0
  92. package/context/context-mails/MailService.js +147 -0
  93. package/context/context-mails/TucUnseenApiProvider.js +65 -0
  94. package/context/context-mails/index.js +131 -0
  95. package/context/context-news/CollektorVersion2ApiProvider.js +68 -0
  96. package/context/context-news/index.js +155 -0
  97. package/context/context-public-transport-ticket/CollektorVersion2ApiProvider.js +45 -0
  98. package/context/context-public-transport-ticket/ProviderErrors.js +11 -0
  99. package/context/context-public-transport-ticket/index.js +175 -0
  100. package/context/context-timetable/CollectorVersion2ApiProvider.js +102 -0
  101. package/context/context-timetable/ProviderErrors.js +22 -0
  102. package/context/context-timetable/TimetableService.js +357 -0
  103. package/context/context-timetable/index.js +215 -0
  104. package/context/context-user/index.js +586 -0
  105. package/index.js +178 -0
  106. package/libraries/base-api-provider/hooks.js +24 -0
  107. package/libraries/base-api-provider/http-api-provider.js +168 -0
  108. package/libraries/base-api-provider/index.js +20 -0
  109. package/libraries/core/api/canteens.js +88 -0
  110. package/libraries/core/api/corona.js +45 -0
  111. package/libraries/core/api/courses.js +54 -0
  112. package/libraries/core/api/device.js +98 -0
  113. package/libraries/core/api/feed.js +144 -0
  114. package/libraries/core/api/feedback.js +123 -0
  115. package/libraries/core/api/jobs.js +48 -0
  116. package/libraries/core/api/library.js +67 -0
  117. package/libraries/core/api/lostfound.js +77 -0
  118. package/libraries/core/api/occupancy.js +44 -0
  119. package/libraries/core/api/officehours.js +25 -0
  120. package/libraries/core/api/poi.js +25 -0
  121. package/libraries/core/api/pts.js +68 -0
  122. package/libraries/core/api/rooms.js +31 -0
  123. package/libraries/core/api/survey.js +121 -0
  124. package/libraries/core/api/telephone.js +32 -0
  125. package/libraries/core/api/tucrooms.js +31 -0
  126. package/libraries/core/constants/actions.js +75 -0
  127. package/libraries/core/constants/api.js +146 -0
  128. package/libraries/core/constants/enums.js +5 -0
  129. package/libraries/core/helper/date.js +9 -0
  130. package/libraries/core/helper/format.helper.js +2 -0
  131. package/libraries/core/index.js +60 -0
  132. package/libraries/core/redux/actions/notifications.js +6 -0
  133. package/libraries/core/redux/actions/setting.js +75 -0
  134. package/libraries/core/redux/actions/state.js +74 -0
  135. package/libraries/core/redux/asyncDispatch.js +27 -0
  136. package/libraries/core/redux/reducers/api.js +190 -0
  137. package/libraries/core/redux/reducers/index.js +32 -0
  138. package/libraries/core/redux/reducers/notifications.js +16 -0
  139. package/libraries/core/redux/reducers/setting.js +99 -0
  140. package/libraries/core/redux/reducers/state.js +122 -0
  141. package/libraries/core/redux/selectors.js +123 -0
  142. package/libraries/core/redux/store.js +40 -0
  143. package/libraries/core/services/data.js +96 -0
  144. package/libraries/core/services/root-navigation.js +36 -0
  145. package/libraries/core/services/search.js +175 -0
  146. package/libraries/core-plugins/enums/replaceTypes.js +53 -0
  147. package/libraries/core-plugins/index.js +21 -0
  148. package/libraries/core-plugins/redux/actions/plugin.js +13 -0
  149. package/libraries/core-plugins/redux/reducers/plugin.js +210 -0
  150. package/libraries/icons-openasist/index.js +143 -0
  151. package/libraries/notifications/index.js +268 -0
  152. package/libraries/notifications/services/subscriber.service.js +123 -0
  153. package/libraries/react-native-webview-autoheight/README.md +47 -0
  154. package/libraries/react-native-webview-autoheight/index.js +140 -0
  155. package/libraries/react-native-webview-autoheight/package.json +37 -0
  156. package/libraries/react-native-webview-autoheight/utils.js +268 -0
  157. package/libraries/redux-offline/.eslintignore +1 -0
  158. package/libraries/redux-offline/.github/ISSUE_TEMPLATE/redux-offline-core-issues-template.md +25 -0
  159. package/libraries/redux-offline/.prettierrc +6 -0
  160. package/libraries/redux-offline/LICENSE +21 -0
  161. package/libraries/redux-offline/README.md +133 -0
  162. package/libraries/redux-offline/flow-typed/npm/redux-logger_vx.x.x.js +109 -0
  163. package/libraries/redux-offline/flow-typed/npm/redux_v4.x.x.js +100 -0
  164. package/libraries/redux-offline/lib/actions.js +46 -0
  165. package/libraries/redux-offline/lib/config.js +15 -0
  166. package/libraries/redux-offline/lib/constants.js +17 -0
  167. package/libraries/redux-offline/lib/defaults/defaultCommit.js +11 -0
  168. package/libraries/redux-offline/lib/defaults/defaultRollback.js +11 -0
  169. package/libraries/redux-offline/lib/defaults/detectNetwork.js +33 -0
  170. package/libraries/redux-offline/lib/defaults/detectNetwork.native.js +211 -0
  171. package/libraries/redux-offline/lib/defaults/discard.js +18 -0
  172. package/libraries/redux-offline/lib/defaults/effect.js +87 -0
  173. package/libraries/redux-offline/lib/defaults/index.js +32 -0
  174. package/libraries/redux-offline/lib/defaults/offlineStateLens.js +24 -0
  175. package/libraries/redux-offline/lib/defaults/persist.js +9 -0
  176. package/libraries/redux-offline/lib/defaults/persist.native.js +17 -0
  177. package/libraries/redux-offline/lib/defaults/persistAutoRehydrate.js +8 -0
  178. package/libraries/redux-offline/lib/defaults/queue.js +27 -0
  179. package/libraries/redux-offline/lib/defaults/retry.js +29 -0
  180. package/libraries/redux-offline/lib/index.js +115 -0
  181. package/libraries/redux-offline/lib/middleware.js +56 -0
  182. package/libraries/redux-offline/lib/offlineActionTracker.js +43 -0
  183. package/libraries/redux-offline/lib/send.js +112 -0
  184. package/libraries/redux-offline/lib/types.js +3 -0
  185. package/libraries/redux-offline/lib/updater.js +111 -0
  186. package/libraries/redux-offline/package.json +69 -0
  187. package/libraries/redux-offline/src/__tests__/defaults/discard.js +22 -0
  188. package/libraries/redux-offline/src/__tests__/defaults/effect.js +118 -0
  189. package/libraries/redux-offline/src/__tests__/index.js +116 -0
  190. package/libraries/redux-offline/src/__tests__/middleware.js +185 -0
  191. package/libraries/redux-offline/src/__tests__/offlineActionTracker.js +54 -0
  192. package/libraries/redux-offline/src/__tests__/send.js +208 -0
  193. package/libraries/redux-offline/src/actions.js +36 -0
  194. package/libraries/redux-offline/src/config.js +9 -0
  195. package/libraries/redux-offline/src/constants.js +18 -0
  196. package/libraries/redux-offline/src/defaults/defaultCommit.js +7 -0
  197. package/libraries/redux-offline/src/defaults/defaultRollback.js +7 -0
  198. package/libraries/redux-offline/src/defaults/detectNetwork.js +16 -0
  199. package/libraries/redux-offline/src/defaults/detectNetwork.native.js +148 -0
  200. package/libraries/redux-offline/src/defaults/discard.js +19 -0
  201. package/libraries/redux-offline/src/defaults/effect.js +86 -0
  202. package/libraries/redux-offline/src/defaults/index.js +25 -0
  203. package/libraries/redux-offline/src/defaults/offlineStateLens.js +11 -0
  204. package/libraries/redux-offline/src/defaults/persist.js +4 -0
  205. package/libraries/redux-offline/src/defaults/persist.native.js +9 -0
  206. package/libraries/redux-offline/src/defaults/persistAutoRehydrate.js +4 -0
  207. package/libraries/redux-offline/src/defaults/queue.js +20 -0
  208. package/libraries/redux-offline/src/defaults/retry.js +18 -0
  209. package/libraries/redux-offline/src/index.js +138 -0
  210. package/libraries/redux-offline/src/middleware.js +52 -0
  211. package/libraries/redux-offline/src/offlineActionTracker.js +40 -0
  212. package/libraries/redux-offline/src/send.js +111 -0
  213. package/libraries/redux-offline/src/types.js +127 -0
  214. package/libraries/redux-offline/src/updater.js +141 -0
  215. package/libraries/redux-offline/typings.d.ts +150 -0
  216. package/libraries/redux-offline/yarn.lock +6460 -0
  217. package/libraries/stored-state/index.js +155 -0
  218. package/package.json +68 -0
  219. package/views/Callmanager/index.js +148 -0
  220. package/views/Callmanager/styles.js +62 -0
  221. package/views/Canteens/index.js +383 -0
  222. package/views/Canteens/styles.js +89 -0
  223. package/views/Dashboard/index.js +176 -0
  224. package/views/Dashboard/styles.js +16 -0
  225. package/views/DashboardHtwk/index.js +197 -0
  226. package/views/DashboardHtwk/styles.js +24 -0
  227. package/views/Event/index.js +373 -0
  228. package/views/Event/styles.js +63 -0
  229. package/views/FeedList/index.js +165 -0
  230. package/views/FeedList/styles.js +15 -0
  231. package/views/FeedNews/index.js +243 -0
  232. package/views/FeedNews/styles.js +32 -0
  233. package/views/Flexmenu/index.js +185 -0
  234. package/views/Flexmenu/styles.js +62 -0
  235. package/views/FlexmenuWebview/index.js +167 -0
  236. package/views/FlexmenuWebview/styles.js +16 -0
  237. package/views/Howhy/index.js +151 -0
  238. package/views/Howhy/styles.js +11 -0
  239. package/views/Jobs/index.js +217 -0
  240. package/views/Jobs/styles.js +41 -0
  241. package/views/MainMenu/index.js +283 -0
  242. package/views/MainMenu/styles.js +36 -0
  243. package/views/NewsTabbar/index.js +164 -0
  244. package/views/NewsTabbar/styles.js +27 -0
  245. package/views/Opal/index.js +136 -0
  246. package/views/Opal/styles.js +11 -0
  247. package/views/PublicTransportTicket/index.js +173 -0
  248. package/views/PublicTransportTicket/styles.js +17 -0
  249. package/views/Search/index.js +186 -0
  250. package/views/Search/styles.js +67 -0
  251. package/views/SettingsAccessibility/index.js +148 -0
  252. package/views/SettingsAccessibility/styles.js +13 -0
  253. package/views/SettingsAppInfo/index.js +86 -0
  254. package/views/SettingsAppInfo/styles.js +18 -0
  255. package/views/SettingsCanteens/index.js +249 -0
  256. package/views/SettingsCanteens/styles.js +33 -0
  257. package/views/SettingsGeneral/index.js +173 -0
  258. package/views/SettingsGeneral/styles.js +28 -0
  259. package/views/SettingsNotifications/index.js +204 -0
  260. package/views/SettingsNotifications/styles.js +38 -0
  261. package/views/SettingsUser/index.js +170 -0
  262. package/views/SettingsUser/styles.js +17 -0
  263. package/views/TimetableCalendar/index.js +387 -0
  264. package/views/TimetableCalendar/styles.js +121 -0
  265. package/views/TimetableList/index.js +402 -0
  266. package/views/TimetableList/styles.js +55 -0
  267. package/views/Webviews/index.js +158 -0
  268. package/views/Webviews/styles.js +11 -0
@@ -0,0 +1,165 @@
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 {
17
+ ActivityIndicator,
18
+ FlatList,
19
+ SafeAreaView,
20
+ StyleSheet,
21
+ Text,
22
+ TouchableOpacity,
23
+ View
24
+ } from 'react-native';
25
+ import {connect} from 'react-redux'
26
+ import {withTheme} from "react-native-paper";
27
+ import {withTranslation} from "react-i18next";
28
+
29
+ import merge from 'lodash/merge';
30
+
31
+ import {onUpdateRefreshing} from '../../libraries/core';
32
+
33
+
34
+ import componentStyles from "./styles";
35
+ import AppbarComponent from '../../components/AppBar';
36
+ import IconsOpenasist from '../../libraries/icons-openasist';
37
+
38
+ /**
39
+ * Feed List View
40
+ *
41
+ * Shows a list of news feeds
42
+ *
43
+ * Parameters:
44
+ * - none
45
+ *
46
+ * Navigation-Parameters:
47
+ * - none
48
+ */
49
+ class FeedListView extends React.Component {
50
+ static navigationOptions = {
51
+ header: null
52
+ };
53
+
54
+ // Styles of this component
55
+ styles;
56
+
57
+ constructor(props) {
58
+ super(props);
59
+
60
+ // ------------------------------------------------------------------------
61
+ // PLUGIN FUNCTIONALITY
62
+ // ------------------------------------------------------------------------
63
+
64
+ const {pluginStyles,theme} = this.props;
65
+ this.styles = componentStyles(theme);
66
+
67
+ if (pluginStyles) {
68
+ this.styles = merge(this.styles, pluginStyles);
69
+ }
70
+
71
+ this.styles = StyleSheet.create(this.styles);
72
+
73
+ // ------------------------------------------------------------------------
74
+ }
75
+
76
+ /**
77
+ * Render a feed
78
+ *
79
+ * @returns {Array}
80
+ *
81
+ * @private
82
+ */
83
+ _renderFeed = ({item}) => {
84
+ const {themeStyles, colors} = this.props.theme;
85
+
86
+ return (
87
+ <TouchableOpacity style={themeStyles.card} onPress={() => {this.props.navigation.navigate('FeedNews', {feedId: item.feedid, feedTitle: item.title})}}>
88
+ <View style={[themeStyles.cardContent, this.styles.cardContent]}>
89
+ <Text style={[themeStyles.cardTitle, this.styles.cardTitle]}>{item.title}</Text>
90
+ <Text style={[themeStyles.cardSubTitle, this.styles.cardSubTitle]}>{item.desc}</Text>
91
+ </View>
92
+ <View style={themeStyles.cardRightIcon}>
93
+ <IconsOpenasist icon={"forward"} size={25} color={colors.messages.icon} />
94
+ </View>
95
+ </TouchableOpacity>
96
+ );
97
+ };
98
+
99
+
100
+ /**
101
+ * Key Extractor for unique item key
102
+ *
103
+ * @param item
104
+ * @param index
105
+ * @returns {*}
106
+ * @private
107
+ */
108
+ _keyExtractor = (item, index) => {
109
+ return 'feed_' + ((item.feedid) ? item.feedid : ((item.title) ? item.title : index));
110
+ };
111
+
112
+
113
+ render() {
114
+ // ------------------------------------------------------------------------
115
+ // PLUGIN FUNCTIONALITY
116
+ // ------------------------------------------------------------------------
117
+ const PluginComponent = this.props.pluginComponent;
118
+ if (PluginComponent) {
119
+ return <PluginComponent/>;
120
+ }
121
+ // ------------------------------------------------------------------------
122
+
123
+ const {feeds, theme: {colors, paddings, themeStyles}, t} = this.props;
124
+
125
+ return (
126
+ <SafeAreaView style={[this.styles.container, themeStyles.appSafeAreaContainer]}>
127
+ <AppbarComponent {...this.props} title={t('news:feeds')}/>
128
+ <View style={themeStyles.container}>
129
+ {!feeds ?
130
+ <ActivityIndicator style={this.styles.activity} size="large" color={colors.loadingIndicator} /> :
131
+ <FlatList
132
+ data={feeds.sort((a,b) => {
133
+ if(a.feedid < b.feedid){
134
+ return -1;
135
+ } else if (a.feedid > b.feedid) {
136
+ return 1;
137
+ }
138
+ return 0;
139
+ })}
140
+ extraData={this.state}
141
+ keyExtractor={this._keyExtractor}
142
+ renderItem={this._renderFeed}
143
+ initialNumToRender={6}
144
+ getItemLayout={(data, index) => (
145
+ {length: 50, offset: 50 * index, index}
146
+ )}
147
+ contentContainerStyle={{paddingBottom: paddings.default}}
148
+ style={this.styles.innerContainer}
149
+ />}
150
+ </View>
151
+ </SafeAreaView>
152
+ );
153
+ }
154
+ }
155
+
156
+ const mapStateToProps = state => {
157
+ return {
158
+ pluginComponent: state.pluginReducer.feedList.component,
159
+ pluginStyles: state.pluginReducer.feedList.styles,
160
+ feeds: state.apiReducer.feeds
161
+ };
162
+ };
163
+
164
+
165
+ export default connect(mapStateToProps, {onUpdateRefreshing})(withTranslation()(withTheme(FeedListView)))
@@ -0,0 +1,15 @@
1
+ export default function(theme) {
2
+ return {
3
+ container: {
4
+ flex: 1
5
+ },
6
+ innerContainer: {
7
+ flex: 1
8
+ },
9
+ cardContent: {
10
+ paddingLeft: theme.paddings.large,
11
+ paddingTop: theme.paddings.small,
12
+ paddingBottom: theme.paddings.small
13
+ }
14
+ }
15
+ };
@@ -0,0 +1,243 @@
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 {
17
+ ActivityIndicator,
18
+ Text,
19
+ SafeAreaView,
20
+ StyleSheet,
21
+ View,
22
+ FlatList,
23
+ TouchableOpacity, Image, Linking
24
+ } from 'react-native';
25
+ import {connect} from 'react-redux'
26
+ import {withTheme} from "react-native-paper";
27
+ import {withTranslation} from "react-i18next";
28
+
29
+ import merge from 'lodash/merge';
30
+ import moment from "moment";
31
+
32
+ import {feedApi, onUpdateRefreshing} from '../../libraries/core';
33
+ import AppbarComponent from '../../components/AppBar';
34
+ import IconsOpenasist from '../../libraries/icons-openasist';
35
+
36
+ import componentStyles from "./styles";
37
+ import { handleHtmlEntities } from '../../libraries/core/helper/format.helper';
38
+
39
+
40
+ /**
41
+ * Feed News View
42
+ *
43
+ * Shows a list of news of the provided feed
44
+ *
45
+ * Parameters:
46
+ * - none
47
+ *
48
+ * Navigation-Parameters:
49
+ * - feedId: Id of the feed to load the news from
50
+ * - feedTitle: Name/Title of the feed for view header
51
+ */
52
+ class FeedNewsView extends React.Component {
53
+ static navigationOptions = {
54
+ header: null
55
+ };
56
+
57
+ // Styles of this component
58
+ styles;
59
+
60
+ feedNews = null;
61
+
62
+ constructor(props) {
63
+ super(props);
64
+
65
+ this.state = {
66
+ inProgress: true,
67
+ hasNoNewsAvailable: false,
68
+ hasError: false
69
+ };
70
+
71
+ // ------------------------------------------------------------------------
72
+ // PLUGIN FUNCTIONALITY
73
+ // ------------------------------------------------------------------------
74
+
75
+ const {pluginStyles,theme} = this.props;
76
+ this.styles = componentStyles(theme);
77
+
78
+ if (pluginStyles) {
79
+ this.styles = merge(this.styles, pluginStyles);
80
+ }
81
+
82
+ this.styles = StyleSheet.create(this.styles);
83
+
84
+ // ------------------------------------------------------------------------
85
+ }
86
+
87
+ /**
88
+ * User pressed a card to read this news
89
+ *
90
+ * @param news
91
+ *
92
+ * @private
93
+ */
94
+ _onCardPress(news) {
95
+ this.props.navigation.navigate('NewsDetail', {news: news});
96
+ }
97
+
98
+
99
+ /**
100
+ * Render a single news item with title, description and image
101
+ *
102
+ * @param item
103
+ * @returns {*}
104
+ * @private
105
+ */
106
+ _renderNewsItem = ({item}) => {
107
+ const { theme: { themeStyles, colors}, t } = this.props;
108
+
109
+ var description = item.shortDesc
110
+ .replace(/<(?:.|\n)*?>/gm, '')
111
+ .replace('Weiterlesen ›', '');
112
+
113
+ let date = moment(item.pubdate);
114
+
115
+ let pubDate = item.pubdate;
116
+ if(date) {
117
+ pubDate = date.format('DD.MM.YYYY - HH:mm');
118
+ }
119
+
120
+ return (
121
+ <TouchableOpacity style={themeStyles.cardWithImage} onPress={() => this._onCardPress(item)}>
122
+ <View style={themeStyles.cartHeaderSplit}>
123
+ {item.imageUrl && <Image source={{uri: item.imageUrl }} style={themeStyles.cartHeaderSplitImage} resizeMode="contain"/>}
124
+ <View style={item.imageUrl ? themeStyles.cartHeaderSplitDetails : themeStyles.cartHeaderDetails}>
125
+ <Text style={[themeStyles.cardTitle, this.styles.newsTitle]}>{item.title}</Text>
126
+ <View style={[themeStyles.flexRow, {alignItems: 'center', alignContent: 'center'}]}>
127
+ <IconsOpenasist icon={'time'} size={20} color={colors.accent}/>
128
+ <Text style={[themeStyles.cardSubTitle, this.styles.newsDate]}>{pubDate}</Text>
129
+ </View>
130
+ </View>
131
+ </View>
132
+ <View style={themeStyles.flexRow}>
133
+ <View style={[themeStyles.cardContent, this.styles.newsContent]}>
134
+ <Text style={themeStyles.cardText}>{handleHtmlEntities(description)}</Text>
135
+ </View>
136
+ <View style={[themeStyles.cardRightIcon, this.styles.newsIcon]}>
137
+ <IconsOpenasist icon={"forward"} size={25} color={colors.messages.icon} />
138
+ </View>
139
+ </View>
140
+ {item.link ? (
141
+ <TouchableOpacity style={themeStyles.cardLinkExternal} onPress={() => {Linking.openURL(item.link)}}>
142
+ <Text style={themeStyles.cardLinkTextExternal}>{t('common:openInBrowser')}</Text>
143
+ <IconsOpenasist icon={"open-external"} size={18} color={colors.subtitle} />
144
+ </TouchableOpacity>
145
+ ) : null}
146
+ </TouchableOpacity>
147
+ );
148
+ };
149
+
150
+ /**
151
+ * Key Extractor for unique item key
152
+ *
153
+ * @param item
154
+ * @param index
155
+ * @returns {*}
156
+ * @private
157
+ */
158
+ _keyExtractor = (item, index) => {
159
+ return ((item.guid) ? item.guid : ((item.title) ? item.title : index));
160
+ };
161
+
162
+ render() {
163
+
164
+ // ------------------------------------------------------------------------
165
+ // PLUGIN FUNCTIONALITY
166
+ // ------------------------------------------------------------------------
167
+ const PluginComponent = this.props.pluginComponent;
168
+ if (PluginComponent) {
169
+ return <PluginComponent />;
170
+ }
171
+ // ------------------------------------------------------------------------
172
+
173
+
174
+ const {route, t} = this.props;
175
+ const {colors, paddings, themeStyles} = this.props.theme;
176
+ const {inProgress, hasNoNewsAvailable, hasError} = this.state;
177
+
178
+ const feedId = route.params && route.params.feedId || null;
179
+ const feedTitle = route.params && route.params.feedTitle || 'News';
180
+
181
+ if(!this.feedNews && feedId) {
182
+ feedApi.getFeedById(feedId, (feed) => {
183
+ if(typeof feed === 'number') {
184
+ this.feedNews = [];
185
+ this.setState({
186
+ inProgress: false,
187
+ hasNoNewsAvailable: feed === 0,
188
+ hasError: feed === -1
189
+ });
190
+ } else {
191
+ this.feedNews = feed;
192
+ this.setState({
193
+ inProgress: false,
194
+ hasNoNewsAvailable: false,
195
+ hasError: false
196
+ });
197
+ }
198
+ });
199
+ }
200
+
201
+ return (
202
+ <SafeAreaView style={[this.styles.container, themeStyles.appSafeAreaContainer]}>
203
+ <AppbarComponent {...this.props} title={feedTitle}/>
204
+ <View style={themeStyles.container}>
205
+ { !inProgress && hasNoNewsAvailable &&
206
+ <View style={themeStyles.noticeTextContainer}>
207
+ <Text style={themeStyles.noticeText}>{t('news:noResult')}</Text>
208
+ </View>
209
+ }
210
+ { !inProgress && hasError &&
211
+ <View style={themeStyles.noticeTextContainer}>
212
+ <Text style={themeStyles.noticeText}>{t('news:couldNotLoadNews')}</Text>
213
+ </View>
214
+ }
215
+ { inProgress && <ActivityIndicator style={this.styles.activity} size="large" color={colors.loadingIndicator} /> }
216
+ { !inProgress && <FlatList
217
+ data={this.feedNews}
218
+ extraData={this.state}
219
+ keyExtractor={this._keyExtractor}
220
+ renderItem={this._renderNewsItem}
221
+ initialNumToRender={6}
222
+ getItemLayout={(data, index) => (
223
+ {length: 50, offset: 50 * index, index}
224
+ )}
225
+ contentContainerStyle={{paddingBottom: paddings.default}}
226
+ style={this.styles.innerContainer}
227
+ /> }
228
+
229
+ </View>
230
+ </SafeAreaView>
231
+ );
232
+ }
233
+ }
234
+
235
+ const mapStateToProps = state => {
236
+ return {
237
+ pluginComponent: state.pluginReducer.feedNews.component,
238
+ pluginStyles: state.pluginReducer.feedNews.styles,
239
+ };
240
+ };
241
+
242
+
243
+ export default connect(mapStateToProps, {onUpdateRefreshing})(withTranslation()(withTheme(FeedNewsView)))
@@ -0,0 +1,32 @@
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
+ newsTitle: {
13
+ ...theme.fonts.medium,
14
+ fontSize: theme.fontSizes.xl,
15
+ lineHeight: theme.lineHeights.xxl,
16
+ marginBottom: theme.paddings.default
17
+ },
18
+ newsDate: {
19
+ ...theme.fonts.bold,
20
+ marginTop: 3,
21
+ paddingLeft: theme.paddings.small
22
+ },
23
+ newsContent: {
24
+ paddingTop: theme.paddings.default,
25
+ paddingLeft: theme.paddings.default,
26
+ paddingRight: theme.paddings.default
27
+ },
28
+ newsIcon: {
29
+ paddingRight: theme.paddings.xsmall
30
+ }
31
+ }
32
+ };
@@ -0,0 +1,185 @@
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
+ StyleSheet,
18
+ SafeAreaView,
19
+ View,
20
+ Text,
21
+ FlatList,
22
+ Linking
23
+ } from 'react-native';
24
+
25
+ import { connect } from 'react-redux';
26
+ import { useTheme } from 'react-native-paper';
27
+ import { useTranslation } from 'react-i18next';
28
+ import { useNavigation } from '@react-navigation/native';
29
+
30
+ import AppbarComponent from '../../components/AppBar';
31
+ import IconsOpenasist from '../../libraries/icons-openasist';
32
+ import FlexMenuEntry from '../../components/FlexMenuEntry';
33
+
34
+ import componentStyles from './styles';
35
+
36
+ /**
37
+ * Diese View zeigt eine Ebene von Menüeintragen des Flex-Menüs an.
38
+ *
39
+ * Es sollte mindestens ein Menütyp(props.menuType) über die Eigenschaften oder ein Hauptmenüeintrag(props.route.mainMenuEntry) übergeben werden.
40
+ * Wird ein Menütyp übergeben, wird der Hauptmenüeintrag des Menütypes gesucht und die Kindermenüeintrage angezeigt.
41
+ * Wird ein Hauptmenüeintrag bzw. Elternmenüeintrag übergeben, werden dessen Kindereinträge angezeigt.
42
+ * Der Hauptmenüeintrag wird über das Navigationsframework übergeben, weshalb dieser in der 'route'-Eigenschaft zu finden ist.
43
+ * Somit werden meherer Menüebenen unterstützt.
44
+ *
45
+ * Die View heißt aus historischen Gründen CoronaView und sollte zeitnah sinvoll umbennant werden
46
+ *
47
+ * @param {object} props
48
+ * @param {string} [props.menuType] Menütyp, dessen erste Menüebene angezeigt werden soll
49
+ * @param {object} props.route Eigenschaften, welche durch das Navigationsframework übergeben werden: {@link https://reactnavigation.org/docs/params}
50
+ * @param {string} [props.route.mainMenuEntry] ID des Hauptmenüeintrag, dessen Kinder anzuzeigen sind
51
+ */
52
+ function FlexMenuView(props) {
53
+ const componentName = FlexMenuView.name;
54
+ const {
55
+ route,
56
+ } = props;
57
+
58
+ const menuType = props?.menuType ?? route?.params?.menuType;
59
+ const menuEntries = props.menuEntries ?? [];
60
+ const view = props?.view ?? route.params.view;
61
+
62
+ const theme = useTheme();
63
+ const { themeStyles, paddings, colors, appSettings } = theme;
64
+ const { t, i18n } = useTranslation();
65
+ const navigation = useNavigation();
66
+
67
+ const languages = appSettings?.languages;
68
+ // Eingestellte Sprache aus der Übersetzung holen
69
+ const selectedLanguage = i18n.language;
70
+ // Hinterlegte Sprachen durchgehen und nach dem erweiterten Sprachcode holen
71
+ const menuEntriesLanguage = languages
72
+ // Finde die derzeitige eingestellte Sprache
73
+ .find(language => language?.code === selectedLanguage)
74
+ // Erweiterten Sprachcode von der gefundenen Sprache auslesen
75
+ ?.extCode;
76
+
77
+ let mainMenuEntry;
78
+ let childMenuEntries;
79
+
80
+ const styles = useMemo(
81
+ () => StyleSheet.create(componentStyles(theme)),
82
+ [theme]
83
+ );
84
+
85
+ // Bestimmen des Hauptmenüeintrages dieser View
86
+ // Zuerst wird der Hauptmenüeintrag es den Navigationsparametern entnommen
87
+ mainMenuEntry = route?.params?.mainMenuEntry ?? null;
88
+ // Ist der Hauptmenüeintrag nicht in den Navigationsparametern enthalten gewesen, aber dennoch ist ein Menütyp vergeben, wird der Hauptmenüeintrag aus allen Menueinträgen bestimmt
89
+ if (mainMenuEntry === null && menuType !== null) {
90
+ // Der Hauptmenüeintrag ist ein Eintrag ohne einen Elterneintrag, mit dem übergenen Menütyp und der eingestellten Sprache
91
+ mainMenuEntry = menuEntries
92
+ // Es werden alle Menüeintrage behalten, die dem Menütyp entsprechen
93
+ .filter(menuEntry => menuEntry.type === menuType)
94
+ // Es werden alle Menüeintrage behalten, die der eingestellten Sprache entsprechen
95
+ .filter(menuEntry => (menuEntry.language ?? null) === menuEntriesLanguage)
96
+ // Aus den nicht ausgefilterten Menüeinträgen wird eine Eintrag genommen, der kein Elterneintrag besitzt
97
+ .find(menuEntry => (menuEntry.parentMenuEntry ?? null) === null);
98
+ }
99
+
100
+ // Ids der Untermenüpunkte aus den Ressource-links herausholen
101
+ const childMenuEntryIds = mainMenuEntry
102
+ ?.subMenuEntries
103
+ ?.map(
104
+ subMenuLinkId =>
105
+ // Der Link des Untermenüpunktes wird in seine Segmente aufgesplitted und das letzte Segment mit Inhalt als ID verwendet
106
+ subMenuLinkId
107
+ // Aufsplitten der URL in seine Segmente
108
+ .split('/')
109
+ // Entfernen aller 'leeren' Segmenente
110
+ .filter(urlSegment => urlSegment !== '')
111
+ // Nehmen des letzten Elements
112
+ .pop()
113
+ )
114
+ ?? [];
115
+
116
+ childMenuEntries = childMenuEntryIds
117
+ .map(childMenuEntryId => menuEntries.find(menuEntry => menuEntry.id === childMenuEntryId))
118
+ .filter(menuEntry => (menuEntry ?? null) !== null);
119
+
120
+ return (
121
+ <SafeAreaView style={[styles.container, themeStyles.appSafeAreaContainer]}>
122
+ <AppbarComponent {...props} title={mainMenuEntry?.title} />
123
+ <View style={themeStyles.container}>
124
+ <FlatList
125
+ data={
126
+ Array.isArray(childMenuEntries)
127
+ ? childMenuEntries
128
+ : []
129
+ }
130
+ renderItem={
131
+ ({ item: menuEntry }) => {
132
+ let menuEntryOnPress;
133
+ switch (menuEntry.openIn) {
134
+ case 'webview':
135
+ menuEntryOnPress = () => { navigation.push('FlexMenuWebView', { url: menuEntry.url, item: menuEntry }) };
136
+ break;
137
+ case 'webbrowser':
138
+ case 'browser':
139
+ menuEntryOnPress = () => {
140
+ Linking.canOpenURL(menuEntry.url)
141
+ .then(supported => {
142
+ if (supported) {
143
+ Linking.openURL(menuEntry.url);
144
+ } else {
145
+ console.debug(componentName, ':', 'Can not open', menuEntry?.url);
146
+ }
147
+ });
148
+ }
149
+ break;
150
+ case null:
151
+ menuEntryOnPress = () => { navigation.push(view, { mainMenuEntry: menuEntry, view: view }) };
152
+ break;
153
+ }
154
+
155
+ return (
156
+ <FlexMenuEntry
157
+ title={menuEntry?.title}
158
+ description={menuEntry?.description}
159
+ iconImage={menuEntry?.image}
160
+ onPress={menuEntryOnPress}
161
+ />
162
+ );
163
+ }
164
+ }
165
+ keyExtractor={item => item.id}
166
+ contentContainerStyle={{ paddingBottom: paddings.default }}
167
+ ListEmptyComponent={
168
+ <View style={[styles.containerInner, styles.containerErrorMsg]}>
169
+ <IconsOpenasist icon={'info'} size={48} color={colors.primary} />
170
+ <Text style={styles.title}>{t('corona:menuEntriesNotAvailable')}</Text>
171
+ </View>
172
+ }
173
+ />
174
+ </View>
175
+ </SafeAreaView>
176
+ );
177
+ }
178
+
179
+ const mapStateToProps = state => {
180
+ return {
181
+ menuEntries: state.apiReducer.menuEntries,
182
+ };
183
+ };
184
+
185
+ export default connect(mapStateToProps)(FlexMenuView)