@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,155 @@
1
+ import { useContext, createContext, useMemo, useState, useCallback, useEffect } from 'react';
2
+
3
+ import { useTheme } from 'react-native-paper';
4
+
5
+ import { useLanguage, useStagingServer } from '../../libraries/core';
6
+
7
+ import CollektorVersion2ApiProvider from './CollektorVersion2ApiProvider';
8
+
9
+ /**
10
+ * @typedef News
11
+ * @property {string} title
12
+ * @property {string} link
13
+ * @property {string} author
14
+ * @property {string} guid
15
+ * @property {string} pubdate
16
+ * @property {string} desc
17
+ * @property {string} descImageUrl
18
+ * @property {string} contentImageDesc
19
+ * @property {string} contentImageUrl
20
+ * @property {string} shortDesc
21
+ * @property {string} imageUrl
22
+ */
23
+
24
+ /**
25
+ * @typedef Newschannel
26
+ * @property {Number} feedid
27
+ * @property {string} title
28
+ * @property {string} url
29
+ * @property {string} description
30
+ * @property {string} language
31
+ * @property {News[]} news
32
+ */
33
+
34
+ export const NewsContext = createContext();
35
+
36
+ const CollectorVersion2ProviderName = 'hs-collector-v2';
37
+
38
+ /**
39
+ * Provider for news context
40
+ */
41
+ function NewsContextProvider({ children }) {
42
+ const theme = useTheme();
43
+ const language = useLanguage();
44
+ const isStagingServerActive = useStagingServer();
45
+
46
+ const componentName = NewsContextProvider.name;
47
+ const availableLanguages = theme?.appSettings.languages;
48
+
49
+ const [newsChannels, setNewsChannels] = useState();
50
+
51
+ // Einstellungen für das Stundenplan-Modul
52
+ const newsSettings = theme?.appSettings?.modules?.news;
53
+
54
+ //
55
+ const newsChannelsSettings = newsSettings?.channels;
56
+ const filterNewsChannelsByLanguages = !(newsChannelsSettings?.allLanguages ?? false);
57
+
58
+ // Einstellungen für API-Provider
59
+ const newsApiSettings = newsSettings?.api
60
+ // Soll der Staging-Provider verwendet werden?
61
+ const newsApiProviderSettings = isStagingServerActive
62
+ // Wenn ja, werden die Staging Provider-Einstellungen geladen
63
+ ? newsApiSettings?.staging
64
+ // Wenn nein, werden die productiven Provider-Einstellungen geladen
65
+ : newsApiSettings?.production;
66
+ const newsApiProvider = newsApiProviderSettings?.provider;
67
+ const newsApiBaseUrl = newsApiProviderSettings?.url;
68
+
69
+ // Erstellen des API-Providers bzw. erneuern wenn sich Einstellungen ändern.
70
+ const apiProvider = useMemo(
71
+ () => {
72
+ switch (newsApiProvider?.toLowerCase()) {
73
+ case CollectorVersion2ProviderName:
74
+ console.debug(componentName, ': use collector v2 api');
75
+ return new CollektorVersion2ApiProvider.from(newsApiBaseUrl, language);
76
+ default:
77
+ console.log(`${componentName}: Can't build api provider: ${newsApiProvider}`)
78
+ return null;
79
+ }
80
+ },
81
+ [newsApiProvider, newsApiBaseUrl, language]
82
+ );
83
+
84
+ const refreshNewsChannels = useCallback(
85
+ () => {
86
+ // Nachrichtenkanäle nutzen drei stelligen Sprachcode
87
+ // Es wird der 2-stellige Sprachcode in den 3-stelligen konvertiert.
88
+ const newsChannelsFilterLanguageCode = availableLanguages
89
+ .find(avaiableLanguage => avaiableLanguage.code === language)
90
+ .extCode;
91
+
92
+ let newsChannelsPromise = apiProvider
93
+ ?.getNewsChannels();
94
+
95
+ if (filterNewsChannelsByLanguages) {
96
+ // Solange die Kollektoren nicht die Sprache über die API-Filtern, müssen wir im Clienten filtern.
97
+ // Es werden nur Nachrichtenkanäle übernommen, die der aktuellen Sprache entsprechen.
98
+ newsChannelsPromise = newsChannelsPromise
99
+ ?.then(
100
+ newsChannels =>
101
+ newsChannels.filter(
102
+ // Die Spracheinstellung wird mit der Sprache des Newschannels auf Gleichheit verglichen, dabei wird die Groß- bzw. Kleinschreibung ignoriert.
103
+ newsChannel => newsChannelsFilterLanguageCode?.localeCompare?.(newsChannel?.language, undefined, { sensitivity: 'accent' }) == 0
104
+ )
105
+ )
106
+ }
107
+
108
+ return newsChannelsPromise
109
+ ?.then(setNewsChannels);
110
+ },
111
+ [apiProvider, availableLanguages, language, filterNewsChannelsByLanguages]
112
+ )
113
+
114
+ useEffect(
115
+ () => {
116
+ refreshNewsChannels();
117
+ },
118
+ [refreshNewsChannels]
119
+ )
120
+
121
+ return (
122
+ <NewsContext.Provider
123
+ value={{
124
+ apiProvider: apiProvider,
125
+ newsChannels,
126
+ refreshNewsChannels,
127
+ }}
128
+ >
129
+ {children}
130
+ </NewsContext.Provider>
131
+ );
132
+ }
133
+
134
+ function useNewsContext() {
135
+ return useContext(NewsContext);
136
+ }
137
+
138
+ function useApiProvider() {
139
+ const newsContext = useNewsContext();
140
+
141
+ return newsContext?.apiProvider;
142
+ }
143
+
144
+ function useNewsChannels() {
145
+ const newsContext = useNewsContext();
146
+
147
+ return [newsContext?.newsChannels, newsContext?.refreshNewsChannels];
148
+ }
149
+ export {
150
+ NewsContext as default,
151
+ NewsContextProvider,
152
+ useNewsContext,
153
+ useApiProvider,
154
+ useNewsChannels,
155
+ }
@@ -0,0 +1,45 @@
1
+ import HttpApiProvider, { JsonContentType } from '../../libraries/base-api-provider';
2
+
3
+ /**
4
+ * Infos-API-Client für Kollektor
5
+ */
6
+ export default class CollektorVersion2ApiProvider extends HttpApiProvider {
7
+
8
+ /**
9
+ * Erstellt und gibt die abzufragende URL für ein ÖPNV-Ticket zurück.
10
+ *
11
+ * @returns {URL} URL für die Abfrage eines ÖPNV-Tickets.
12
+ */
13
+ getTicketUrl() {
14
+ const getTicketUrl = this.extendBaseUrl(['ticket']);
15
+
16
+ return getTicketUrl
17
+ }
18
+
19
+ /**
20
+ * Gibt ein ÖPNV-Ticket zurück.
21
+ *
22
+ * @returns {object} Ein ÖPNV-Ticket.
23
+ */
24
+ getTicket() {
25
+ const getTicketUrl = this.getTicketUrl();
26
+
27
+ return this.get(getTicketUrl)
28
+ .then(response => response.json());
29
+ }
30
+
31
+ /**
32
+ * Erstellt eine CollektorVersion2ApiProvider-Instanz, welche Englisch und Deutsch initialisiert wird.
33
+ * Die priorisierte Hauptsprache kann als Paramter übergeben werden.
34
+ *
35
+ * @param {string} baseUrl URL des Kollektors
36
+ * @param {string} [mainLanguage='de'] Hauptsprache, welche priorisiert wird.
37
+ * @returns {CollektorVersion2ApiProvider} Erstellte CollektorVersion2ApiProvider-Instanz
38
+ */
39
+ static from(baseUrl, mainLanguage = 'de', accessToken) {
40
+ const acceptingLanguages = CollektorVersion2ApiProvider.languagesFromMainLanguages(mainLanguage);
41
+ const acceptingContentTypes = HttpApiProvider.contentTypesFromContentType(JsonContentType);
42
+
43
+ return new CollektorVersion2ApiProvider(baseUrl, acceptingLanguages, acceptingContentTypes, accessToken);
44
+ }
45
+ }
@@ -0,0 +1,11 @@
1
+
2
+ /**
3
+ * Diese Exception wird ausgelöst, wenn zu dem Nutzer kein ÖPNV-Ticket abgeholt werden kann.
4
+ */
5
+ export class TicketNotFoundError extends Error {
6
+
7
+ constructor() {
8
+ super('User has no ticket');
9
+ this.name = this.constructor.name;
10
+ }
11
+ }
@@ -0,0 +1,175 @@
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 { createContext, useEffect, useContext, useMemo, useCallback } from 'react'
16
+
17
+ import { useTheme } from 'react-native-paper';
18
+
19
+ import { useSecureStoredState } from '../../libraries/stored-state';
20
+ import { useLanguage, useStagingServer } from '../../libraries/core';
21
+ import { useAccessToken } from '../context-user';
22
+
23
+ import CollektorVersion2ApiProvider from './CollektorVersion2ApiProvider';
24
+
25
+ /**
26
+ * @typedef Ticket
27
+ * @property {string} barcode
28
+ * @property {string} owner
29
+ * @property {date} valid_from
30
+ * @property {date} valid_to
31
+ */
32
+
33
+ /**
34
+ * @typedef PublicTransportTicketContext
35
+ * @property {string} ticketBarcode
36
+ * @property {string} ticketOwner
37
+ * @property {string} ticketValidFrom
38
+ * @property {string} ticketValidTo
39
+ * @property {() => Promise<void>} refreshTicket
40
+ */
41
+
42
+ const ticketBarcodeStoreKey = 'publictransportticket.ticketBarcode';
43
+ const ticketOwnerStoreKey = 'publictransportticket.ticketOwner';
44
+ const ticketValidFromStoreKey = 'publictransportticket.ticketValidFrom';
45
+ const ticketValidToStoreKey = 'publictransportticket.ticketValidTo';
46
+
47
+ const PublicTransportTicketContext = createContext();
48
+
49
+ /**
50
+ * Provider for public transport ticket context
51
+ */
52
+ function PublicTransportTicketContextProvider({ children }) {
53
+ const componentName = PublicTransportTicketContextProvider.name;
54
+ const theme = useTheme();
55
+ const isStagingServerActive = useStagingServer();
56
+ const language = useLanguage();
57
+ const accessToken = useAccessToken();
58
+
59
+ // Einstellungen für das ÖPNV-Ticket-Moduls
60
+ const publicTransportTicketSettings = theme?.appSettings?.modules?.publicTransportTicket;
61
+ // Einstellungen für die API-Provider
62
+ const publicTransportTicketApiSettings = publicTransportTicketSettings?.api;
63
+ // Soll der Staging-Provider verwendet werden?
64
+ const publicTransportTicketApiProviderSettings = isStagingServerActive
65
+ // Wenn ja, werden die Staging Provider-Einstellungen geladen
66
+ ? publicTransportTicketApiSettings?.staging
67
+ // Wenn nein, werden die productiven Provider-Einstellungen geladen
68
+ : publicTransportTicketApiSettings?.production;
69
+ // Basis URL der API
70
+ const publicTransportTicketApiBaseUrl = publicTransportTicketApiProviderSettings?.url;
71
+
72
+ const apiProvider = useMemo(
73
+ () =>
74
+ CollektorVersion2ApiProvider.from(
75
+ publicTransportTicketApiBaseUrl,
76
+ language,
77
+ accessToken,
78
+ ),
79
+ [publicTransportTicketApiBaseUrl, language, accessToken]
80
+ )
81
+
82
+ const [ticketBarcode, setTicketBarcode] = useSecureStoredState(ticketBarcodeStoreKey, null);
83
+ const [ticketOwner, setTicketOwner] = useSecureStoredState(ticketOwnerStoreKey, null);
84
+ const [ticketValidFrom, setTicketValidFrom] = useSecureStoredState(ticketValidFromStoreKey, null);
85
+ const [ticketValidTo, setTicketValidTo] = useSecureStoredState(ticketValidToStoreKey, null);
86
+
87
+ const refreshTicket = useCallback(
88
+ apiProvider && accessToken
89
+ ? () => apiProvider.getTicket()
90
+ .then(
91
+ ticket => {
92
+ setTicketBarcode(ticket?.barcode ?? null);
93
+ setTicketOwner(ticket?.owner ?? null);
94
+ setTicketValidFrom(ticket?.validFrom ?? null);
95
+ setTicketValidTo(ticket?.validTo ?? null);
96
+ console.debug(componentName, ':', 'Get ticket barcode', ':', ticket.barcode);
97
+ }
98
+ )
99
+ : undefined
100
+ ,
101
+ [apiProvider, accessToken, componentName]
102
+ )
103
+
104
+ useEffect(
105
+ () => {
106
+ refreshTicket?.();
107
+ },
108
+ [refreshTicket]
109
+ );
110
+
111
+ return (
112
+ <PublicTransportTicketContext.Provider
113
+ value={{
114
+ ticketBarcode,
115
+ ticketOwner,
116
+ ticketValidFrom,
117
+ ticketValidTo,
118
+ refreshTicket,
119
+ }}
120
+ >
121
+ {children}
122
+ </PublicTransportTicketContext.Provider>
123
+ );
124
+ }
125
+
126
+ /**
127
+ * Liefert den PublicTransportTicketContext zurück.
128
+ * @return {PublicTransportTicketContext} Kontext des Ticket-Modules
129
+ * @example
130
+ * const infoContext = usePublicTransportTicketContext();
131
+ */
132
+ function usePublicTransportTicketContext() {
133
+ return useContext(PublicTransportTicketContext);
134
+ }
135
+
136
+ /**
137
+ * Liefert alle noch austehenden Infos zurück.
138
+ * Austehende Infos sind noch nicht als angezeigt markiert.
139
+ *
140
+ * @returns {[barcode: string|undefined, owner: string|undefined, validForm: string|undefined, validTo: string|undefined, refreshTicket: () => Promise<void>|undefined]}
141
+ * @example
142
+ * const [
143
+ * ticketBarcode,
144
+ * ticketOwner,
145
+ * ticketValidFrom,
146
+ * ticketValidTo,
147
+ * refreshTicket,
148
+ * refreshTicket
149
+ * ] = usePublicTransportTicket();
150
+ *
151
+ * useEffect(
152
+ * () => {
153
+ * refreshInfos?.()
154
+ * },
155
+ * [refreshInfos]
156
+ * );
157
+ */
158
+ function usePublicTransportTicket() {
159
+ const publicTransportTicketContext = usePublicTransportTicketContext();
160
+
161
+ return [
162
+ publicTransportTicketContext?.ticketBarcode,
163
+ publicTransportTicketContext?.ticketOwner,
164
+ publicTransportTicketContext?.ticketValidFrom,
165
+ publicTransportTicketContext?.ticketValidTo,
166
+ publicTransportTicketContext?.refreshTicket
167
+ ];
168
+ }
169
+
170
+ export {
171
+ usePublicTransportTicketContext as default,
172
+ PublicTransportTicketContextProvider,
173
+ usePublicTransportTicketContext,
174
+ usePublicTransportTicket,
175
+ }
@@ -0,0 +1,102 @@
1
+ import HttpApiProvider from '../../libraries/base-api-provider';
2
+ import { TimetableNotFoundError } from './ProviderErrors';
3
+
4
+ /**
5
+ * API-Client for Kollektor
6
+ */
7
+ export default class CollectorVersion2ApiProvider extends HttpApiProvider {
8
+
9
+ /**
10
+ * Name des Providers
11
+ * @type {string}
12
+ */
13
+ static name = 'hs-collector-v2';
14
+
15
+ /**
16
+ * @param {string} baseUrl - URL which is used as the basis for the query URLs.
17
+ * @param {string[]} acceptingLanguages - List of languages that are queried by the ASiST server. The priority is based on the order of the languages in the array.
18
+ */
19
+ constructor(baseUrl, acceptingLanguages) {
20
+ // ContentTypes wird auf JSON festgesetzt, da der ASiST-Server nur JSON spricht.
21
+ super(baseUrl, acceptingLanguages, ['application/json']);
22
+ }
23
+
24
+ /**
25
+ * Returns the request URL to get all courses of a personal timetable code from the collektor.
26
+ *
27
+ * If the start date and end date are passed, query filter parameters are added to the URL.
28
+ * These parameters restrict the events that are sent.
29
+ * Only events that take place between the start date and end date are sent back.
30
+ *
31
+ * @param {string} personalTimetableCode Personal timetable code to get.
32
+ * @param {string} [startDate] Start date in ISO 8601 format.
33
+ * @param {string} [endDate] End date in ISO 8601 format.
34
+ * @returns {URL} URL to get courses of timetable code with optional query parameter.
35
+ */
36
+ getByCodeUrl(personalTimetableCode, startDate, endDate) {
37
+ const getByCodeUrl = this.extendBaseUrl(['courses', 'shortcode', personalTimetableCode]);
38
+
39
+ if (startDate) {
40
+ getByCodeUrl.searchParams.set('start', startDate)
41
+ }
42
+
43
+ if (endDate) {
44
+ getByCodeUrl.searchParams.set('end', endDate)
45
+ }
46
+
47
+ return getByCodeUrl
48
+ }
49
+
50
+ /**
51
+ * Returns a list of all courses from the queried personal timetable code.
52
+ *
53
+ * The list can be restricted by the startDate and endDate, which means that only lectures that take place between the start date and end date are requested.
54
+ *
55
+ * If the collector could not find a timetable for the timetable code, a {@link TimetableNotFoundError} exception is triggered.
56
+ *
57
+ * @param {String} personalTimetableCode Personal code of the timetable.
58
+ * @param {string} [startDate] Start date in ISO 8601 format.
59
+ * @param {string} [endDate] End date in ISO 8601 format.
60
+ * @returns {Array} Array of all courses of the timetable.
61
+ */
62
+ getByCode(personalTimetableCode, startDate, endDate) {
63
+ const getByCodeUrl = this.getByCodeUrl(personalTimetableCode, startDate, endDate);
64
+
65
+ return this.get(getByCodeUrl)
66
+ .then(
67
+ response => {
68
+ if (response.status === 404) {
69
+ throw new TimetableNotFoundError(personalTimetableCode);
70
+ } else {
71
+ return response.json();
72
+ }
73
+ }
74
+ );
75
+ }
76
+
77
+ /**
78
+ * Creates a CollektorVersion2ApiProvider instance initialised to a list of standard languages, where the mainLanguage parameter specifies the mainLanguage.
79
+ * @param {string} baseUrl - URL which is used as the basis for the query URLs.
80
+ * @param {string} mainLanguage - Main language which is prioritised.
81
+ * @returns {CollectorVersion2ApiProvider} Created CollectorVersion2ApiProvider instance.
82
+ */
83
+ static from(baseUrl, mainLanguage = 'de') {
84
+ const acceptingLanguages = CollectorVersion2ApiProvider.languagesFromMainLanguages(mainLanguage);
85
+
86
+ return new CollectorVersion2ApiProvider(baseUrl, acceptingLanguages);
87
+ }
88
+
89
+ /**
90
+ * Erstellt eine CollektorVersion2ApiProvider-Instanz, welche Englisch und Deutsch initialisiert wird.
91
+ * Die priorisierte Hauptsprache kann als Paramter übergeben werden.
92
+ *
93
+ * @param {object} settingsObject Objekt mit Providereinstellungen
94
+ * @param {string} [mainLanguage='de'] Hauptsprache, welche priorisiert wird.
95
+ * @returns {CollectorVersion2ApiProvider} Erstellte CollektorVersion2ApiProvider-Instanz
96
+ */
97
+ static fromSettingsObject(settingsObject, mainLanguage = 'de') {
98
+ const { url } = settingsObject;
99
+
100
+ return CollectorVersion2ApiProvider.from(url, mainLanguage);
101
+ }
102
+ }
@@ -0,0 +1,22 @@
1
+
2
+ /**
3
+ * Diese Exception wird ausgelöst, wenn zu dem Studenplancode kein Stundenplan abgeholt werden kann.
4
+ */
5
+ export class TimetableNotFoundError extends Error {
6
+
7
+ /**
8
+ * Stundenplancode welcher keinem Stundenplan angehörig ist.
9
+ * @type {string}
10
+ */
11
+ timetableCode
12
+
13
+ /**
14
+ *
15
+ * @param {string} timetableCode Stundenplancode, welcher zu einem Fehler führte, weil dieser mit keinem Stundenplan verknüpft ist
16
+ */
17
+ constructor(timetableCode) {
18
+ super(`Timetable code ${timetableCode} is not linked to a timetable`);
19
+ this.timetableCode = timetableCode;
20
+ this.name = this.constructor.name;
21
+ }
22
+ }