@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,190 @@
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 { useSecureStoredReducer, useSecureStoredState } from '../../libraries/stored-state';
20
+ import { useLanguage, useStagingServer } from '../../libraries/core';
21
+
22
+ import CollektorVersion2ApiProvider from './CollektorVersion2ApiProvider';
23
+
24
+ /**
25
+ * @typedef Info
26
+ * @property {string} id
27
+ * @property {string} title
28
+ * @property {string} message
29
+ * @property {date} expiry
30
+ */
31
+
32
+ /**
33
+ * @typedef InfoContext
34
+ * @property {Info[]} pendingInfos
35
+ * @property {(infoId: string) => Promise<void> } setInfoDisplayed
36
+ */
37
+
38
+ const InfoDialogInfosStoreKey = 'infodisplay.infos';
39
+ const InfoDialogDisplayedInfosStoreKey = 'infodisplay.displayedInfos';
40
+
41
+ function displayedInfosReducer(state, addingInfo) {
42
+ return [
43
+ ...(state ?? []),
44
+ addingInfo,
45
+ ]
46
+ }
47
+
48
+ const InfoContext = createContext();
49
+
50
+ /**
51
+ * Provider for info dialog context
52
+ */
53
+ export default function InfoContextProvider({ children }) {
54
+ const componentName = InfoContextProvider.name;
55
+ const theme = useTheme();
56
+ const isStagingServerActive = useStagingServer();
57
+ const language = useLanguage();
58
+
59
+ // Einstellungen für das InfoDialog-Moduls
60
+ const infoDialogSettings = theme?.appSettings?.modules?.infodialog;
61
+ // Einstellungen für die API-Provider
62
+ const infoDialogApiSettings = infoDialogSettings?.api;
63
+ // Soll der Staging-Provider verwendet werden?
64
+ const infoDialogApiProviderSettings = isStagingServerActive
65
+ // Wenn ja, werden die Staging Provider-Einstellungen geladen
66
+ ? infoDialogApiSettings?.staging
67
+ // Wenn nein, werden die productiven Provider-Einstellungen geladen
68
+ : infoDialogApiSettings?.production;
69
+ // Basis URL der API
70
+ const infoDialogApiBaseUrl = infoDialogApiProviderSettings?.url;
71
+
72
+ const apiProvider = useMemo(
73
+ () =>
74
+ CollektorVersion2ApiProvider.from(
75
+ infoDialogApiBaseUrl,
76
+ language
77
+ ),
78
+ [infoDialogApiBaseUrl, language]
79
+ )
80
+
81
+ const [infos, setInfos] = useSecureStoredState(InfoDialogInfosStoreKey, []);
82
+ const [displayedInfos, addDisplayedInfos] = useSecureStoredReducer(InfoDialogDisplayedInfosStoreKey, displayedInfosReducer, []);
83
+
84
+ const pendingInfos = useMemo(
85
+ () => {
86
+ return infos?.filter?.(info => !displayedInfos.includes(info?.id));
87
+ },
88
+ [infos, displayedInfos]
89
+ )
90
+
91
+ console.debug(componentName, ':', 'infos', ':', infos);
92
+ console.debug(componentName, ':', 'pending infos', ':', pendingInfos);
93
+
94
+ //// Estellen des API-Providers bzw. erneuern wenn sich Einstellungen sich ändern.
95
+ //const apiProvider = useMemo(
96
+ // () => {
97
+ // switch (timetableApiProvider?.toLowerCase()) {
98
+ // case AsistServerProviderName:
99
+ // console.debug(componentName, ': use asist server api');
100
+ // return new AsistServerApiProvider.from(timetableApiBaseUrl, timetableApiUniversity, 'de');
101
+ // break;
102
+ // case CollectorVersion2ProviderName:
103
+ // console.debug(componentName, ': use collector v2 api');
104
+ // return new CollektorVersion2ApiProvider.from(timetableApiBaseUrl);
105
+ // break;
106
+ // default:
107
+ // console.log(`${componentName}: Can't build api provider: ${timetableApiProvider}`)
108
+ // return null;
109
+ // }
110
+ // },
111
+ // [timetableApiProvider, timetableApiBaseUrl, timetableApiUniversity]
112
+ //);
113
+
114
+ /**
115
+ * Makiert eine Info als angezeigt.
116
+ * @param {string} infoID ID der Info, welche als angezeigt makiert werden soll
117
+ */
118
+ const setInfoDisplayed = useCallback(
119
+ async (infoID) => {
120
+ addDisplayedInfos(infoID);
121
+ },
122
+ [addDisplayedInfos]
123
+ );
124
+
125
+ const refreshInfos = useCallback(
126
+ () => {
127
+ apiProvider.getInfos()
128
+ .then(
129
+ infos => {
130
+ setInfos(infos);
131
+ console.debug(componentName, ':', 'Get infos', ':', infos);
132
+ }
133
+ );
134
+ },
135
+ [apiProvider, setInfos, componentName]
136
+ )
137
+
138
+ // Aktualiseren Infos beim Starten der App
139
+ useEffect(
140
+ () => {
141
+ refreshInfos();
142
+ },
143
+ [refreshInfos]
144
+ );
145
+
146
+ return (
147
+ <InfoContext.Provider
148
+ value={{
149
+ pendingInfos,
150
+ setInfoDisplayed,
151
+ refreshInfos,
152
+ }}
153
+ >
154
+ {children}
155
+ </InfoContext.Provider>
156
+ );
157
+ }
158
+
159
+ /**
160
+ * Liefert den InfoContext zurück.
161
+ * @return {InfoContext} Kontext des Info-Modules
162
+ * @example
163
+ * const infoContext = useInfoContext();
164
+ */
165
+ export function useInfoContext() {
166
+ return useContext(InfoContext);
167
+ }
168
+
169
+ /**
170
+ * Liefert alle noch austehenden Infos zurück.
171
+ * Austehende Infos sind noch nicht als angezeigt markiert.
172
+ *
173
+ * @returns {[Info[], (displayedInfoId: string) => Promise<void>, () => void]}
174
+ * @example
175
+ * const [pendingInfos, setInfoDisplayed, refreshInfos] = usePendingInfos();
176
+ *
177
+ * setInfoDisplayed('1d3514da-37b1-49df-9bc1-7432a777c498');
178
+ *
179
+ * useEffect(
180
+ * () => {
181
+ * refreshInfos()
182
+ * },
183
+ * [refreshInfos]
184
+ * );
185
+ */
186
+ export function usePendingInfos() {
187
+ const { pendingInfos, setInfoDisplayed, refreshInfos } = useInfoContext();
188
+
189
+ return [pendingInfos, setInfoDisplayed, refreshInfos];
190
+ }
@@ -0,0 +1,147 @@
1
+ import { useSyncExternalStore } from 'react';
2
+
3
+ import AsyncStorage from '@react-native-async-storage/async-storage';
4
+
5
+ import TucUnseenApiProvider from './TucUnseenApiProvider';
6
+
7
+ //class SubscribeableValue {
8
+ // #value;
9
+ //
10
+ // #subscribers = new Set();
11
+ //
12
+ // get value() {
13
+ // return this.#value
14
+ // }
15
+ //
16
+ // set value(value) {
17
+ // this.#value = value;
18
+ //
19
+ // this.#subscribers.forEach(subscriber => subscriber(this.#value));
20
+ // }
21
+ //
22
+ // constructor(value) {
23
+ // this.#value = value;
24
+ // }
25
+ //
26
+ // subscribe(subscriber) {
27
+ // return () => this.unsubscribe(subscriber);
28
+ // }
29
+ //
30
+ // unsubscribe(subscriber) {
31
+ // return this.#subscribers.delete(subscriber);
32
+ // }
33
+ //}
34
+
35
+ /**
36
+ * @typedef ProviderSetting
37
+ * @property {string} provider Name des Providers
38
+ * @property {string} [url] Basis-URL des Provider für Web-Requests
39
+ */
40
+
41
+ const UnreadEmailCountStoreKey = 'mails.unreadEmailCount';
42
+
43
+ export default class MailService {
44
+ #provider;
45
+ #unreadEmailCount = undefined;
46
+ #unreadEmailCountSubscribers = new Set();
47
+
48
+ /**
49
+ *
50
+ * @param {*} provider Provider, der die Komunikation mit den Backend übernimmt
51
+ */
52
+ constructor(provider) {
53
+ this.#provider = provider;
54
+
55
+ AsyncStorage.getItem(UnreadEmailCountStoreKey)
56
+ .then(
57
+ unreadEmailCount => {
58
+ if (this.#unreadEmailCount === undefined) {
59
+ this.#unreadEmailCount = unreadEmailCount;
60
+ this.#unreadEmailCountSubscribers.forEach(subscriber => subscriber());
61
+ }
62
+ }
63
+ );
64
+
65
+ this.refreshUnreadEmailCount();
66
+ }
67
+
68
+ refreshUnreadEmailCount() {
69
+ return this.#provider
70
+ .getUnreadEmailCount()
71
+ .then(
72
+ unreadEmailCount => {
73
+ AsyncStorage.setItem(UnreadEmailCountStoreKey, unreadEmailCount);
74
+ this.#unreadEmailCount = unreadEmailCount;
75
+ this.#unreadEmailCountSubscribers.forEach(subscriber => subscriber(unreadEmailCount));
76
+ }
77
+ );
78
+ }
79
+
80
+ refreshUnreadEmailCountCallback = () => this.refreshUnreadEmailCount();
81
+
82
+ unreadEmailCountSubscribe(subscriber) {
83
+ this.#unreadEmailCountSubscribers.add(subscriber);
84
+
85
+ return () => this.unreadEmailCountUnsubscribe(subscriber);
86
+ }
87
+
88
+ unreadEmailCountSubscribeCallback = subscriber => this.unreadEmailCountSubscribe(subscriber);
89
+
90
+ unreadEmailCountUnsubscribe(subscriber) {
91
+ return this.#unreadEmailCountSubscribers.delete(subscriber);
92
+ }
93
+
94
+ unreadEmailCount() {
95
+ return this.#unreadEmailCount;
96
+ }
97
+
98
+ unreadEmailCountCallback = () => this.unreadEmailCount();
99
+
100
+ /**
101
+ *
102
+ * @param {ProviderSetting} providerSettingsObject
103
+ * @param {string} language
104
+ * @param {string} accessToken
105
+ * @returns
106
+ */
107
+ static fromProviderSettingsObject(providerSettingsObject, language, accessToken) {
108
+ const provider = MailService.#createProvider(providerSettingsObject, language, accessToken);
109
+
110
+ return new MailService(provider);
111
+ }
112
+
113
+ /**
114
+ * @param {ProviderSetting} providerSettingsObject
115
+ */
116
+ static #createProvider(providerSettingsObject, language, accessToken) {
117
+ const { provider } = providerSettingsObject;
118
+
119
+ switch (provider) {
120
+ case TucUnseenApiProvider.name:
121
+ return TucUnseenApiProvider.fromSettingsObject(providerSettingsObject, language, accessToken);
122
+ default:
123
+ return null;
124
+ }
125
+ }
126
+ }
127
+
128
+ function nullUnreadEmailCountSubscribeCallback(subscriber) {
129
+ return () => { };
130
+ }
131
+
132
+ function nullUnreadEmailCountCallback() {
133
+ return undefined;
134
+ }
135
+
136
+ /**
137
+ *
138
+ * @param {MailService} mailService
139
+ */
140
+ export function useUnreadEmailCount(mailService) {
141
+ const unreadEmailCount = useSyncExternalStore(
142
+ mailService?.unreadEmailCountSubscribeCallback ?? nullUnreadEmailCountSubscribeCallback,
143
+ mailService?.unreadEmailCountCallback ?? nullUnreadEmailCountCallback,
144
+ );
145
+
146
+ return [unreadEmailCount, mailService?.refreshUnreadEmailCountCallback];
147
+ }
@@ -0,0 +1,65 @@
1
+ import HttpApiProvider, { JsonContentType } from '../../libraries/base-api-provider';
2
+
3
+ /**
4
+ * Infos-API-Client für Kollektor
5
+ */
6
+ export default class TucUnseenApiProvider extends HttpApiProvider {
7
+
8
+ /**
9
+ * @type {string} Name des Providers
10
+ */
11
+ static name = 'tuc-unseen';
12
+
13
+ /**
14
+ * Erstellt und gibt die abzufragende URL für ein ÖPNV-Ticket zurück.
15
+ *
16
+ * @returns {URL} URL für die Abfrage eines ÖPNV-Tickets.
17
+ */
18
+ getUnreadEmailCountUrl() {
19
+ const getUnreadEmailCountUrl = this.extendBaseUrl(['unseen']);
20
+
21
+ return getUnreadEmailCountUrl
22
+ }
23
+
24
+ /**
25
+ * Gibt die Anzahl der ungelesenen Mails.
26
+ *
27
+ * @returns {number} Anzahl der ungelesenen Mails.
28
+ */
29
+ getUnreadEmailCount() {
30
+ const getUnreadEmailCountUrl = this.getUnreadEmailCountUrl();
31
+
32
+ return this.get(getUnreadEmailCountUrl)
33
+ .then(response => response.json())
34
+ .then(jsonResponse => jsonResponse?.data?.unseen);
35
+ }
36
+
37
+ /**
38
+ * Erstellt eine CollektorVersion2ApiProvider-Instanz, welche Englisch und Deutsch initialisiert wird.
39
+ * Die priorisierte Hauptsprache kann als Paramter übergeben werden.
40
+ *
41
+ * @param {string} baseUrl URL des Kollektors
42
+ * @param {string} [mainLanguage='de'] Hauptsprache, welche priorisiert wird.
43
+ * @returns {TucUnseenApiProvider} Erstellte CollektorVersion2ApiProvider-Instanz
44
+ */
45
+ static from(baseUrl, mainLanguage = 'de', accessToken) {
46
+ const acceptingLanguages = TucUnseenApiProvider.languagesFromMainLanguages(mainLanguage);
47
+ const acceptingContentTypes = HttpApiProvider.contentTypesFromContentType(JsonContentType);
48
+
49
+ return new TucUnseenApiProvider(baseUrl, acceptingLanguages, acceptingContentTypes, accessToken);
50
+ }
51
+
52
+ /**
53
+ * Erstellt eine CollektorVersion2ApiProvider-Instanz, welche Englisch und Deutsch initialisiert wird.
54
+ * Die priorisierte Hauptsprache kann als Paramter übergeben werden.
55
+ *
56
+ * @param {object} settingsObject Objekt mit Providereinstellungen
57
+ * @param {string} [mainLanguage='de'] Hauptsprache, welche priorisiert wird.
58
+ * @returns {TucUnseenApiProvider} Erstellte CollektorVersion2ApiProvider-Instanz
59
+ */
60
+ static fromSettingsObject(settingsObject, mainLanguage = 'de', accessToken) {
61
+ const { url } = settingsObject;
62
+
63
+ return TucUnseenApiProvider.from(url, mainLanguage, accessToken);
64
+ }
65
+ }
@@ -0,0 +1,131 @@
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, use, useMemo, useEffect } from 'react';
16
+ import { AppState } from 'react-native';
17
+
18
+ import { useTheme } from 'react-native-paper';
19
+
20
+ import { useLanguage, useStagingServer } from '../../libraries/core';
21
+ import { useAccessToken } from '../context-user';
22
+
23
+ import MailService, { useUnreadEmailCount as syncUnreadEmailCount } from './MailService';
24
+
25
+ /**
26
+ * @typedef MailsContext
27
+ * @property {number} unreadEmailCount
28
+ * @property {() => Promise<void>} refreshUnreadEmailCount
29
+ */
30
+
31
+ const MailsContext = createContext();
32
+
33
+ /**
34
+ * Provider for mails context
35
+ */
36
+ function MailsContextProvider({ children }) {
37
+ const theme = useTheme();
38
+ const isStagingServerActive = useStagingServer();
39
+ const language = useLanguage();
40
+ const accessToken = useAccessToken();
41
+
42
+ // Einstellungen für das ÖPNV-Ticket-Moduls
43
+ const mailsSettings = theme?.appSettings?.modules?.mails;
44
+ // Einstellungen für die API-Provider
45
+ const mailsApiSettings = mailsSettings?.api;
46
+ // Soll der Staging-Provider verwendet werden?
47
+ const mailsApiProviderSettings = isStagingServerActive
48
+ // Wenn ja, werden die Staging Provider-Einstellungen geladen
49
+ ? mailsApiSettings?.staging
50
+ // Wenn nein, werden die productiven Provider-Einstellungen geladen
51
+ : mailsApiSettings?.production;
52
+
53
+ const mailService = useMemo(
54
+ () =>
55
+ accessToken
56
+ ? MailService.fromProviderSettingsObject(
57
+ mailsApiProviderSettings,
58
+ language,
59
+ accessToken,
60
+ )
61
+ : null,
62
+ [mailsApiProviderSettings, language, accessToken]
63
+ )
64
+
65
+ const [unreadEmailCount, refreshUnreadEmailCount] = syncUnreadEmailCount(mailService);
66
+
67
+ useEffect(
68
+ () => {
69
+ const subscription = AppState.addEventListener(
70
+ 'change',
71
+ nextAppState => {
72
+ if (nextAppState === 'active') {
73
+ refreshUnreadEmailCount?.();
74
+ }
75
+ }
76
+ );
77
+
78
+ return () => {
79
+ subscription.remove();
80
+ };
81
+ },
82
+ [refreshUnreadEmailCount]
83
+ );
84
+
85
+ return (
86
+ <MailsContext
87
+ value={{
88
+ unreadEmailCount,
89
+ refreshUnreadEmailCount,
90
+ }}
91
+ >
92
+ {children}
93
+ </MailsContext>
94
+ );
95
+ }
96
+
97
+ /**
98
+ * Liefert den MailsContext zurück.
99
+ * @return {MailsContext} Kontext des Mails-Modules
100
+ * @example
101
+ * const mailsContext = useMailsContext();
102
+ */
103
+ function useMailsContext() {
104
+ return use(MailsContext);
105
+ }
106
+
107
+ /**
108
+ * Hook, der die Anzahl ungelesender Mails und eine Aktuallierungsfunktion zur Verfüfung stellt.
109
+ *
110
+ * @returns {[unreadEmailCount: number|undefined, refreshUnreadEmailCount: () => Promise<void>|undefined]}
111
+ * @example
112
+ * const [unreadEmailCount, refreshUnreadEmailCount] = useUrefreshUnreadEmailCount();
113
+ *
114
+ * useEffect(
115
+ * () => {
116
+ * refreshUnreadEmailCount?.()
117
+ * },
118
+ * [refreshUnreadEmailCount]
119
+ * );
120
+ */
121
+ function useUnreadEmailCount() {
122
+ const mailsContext = useMailsContext();
123
+
124
+ return [mailsContext?.unreadEmailCount, mailsContext?.refreshUnreadEmailCount];
125
+ }
126
+
127
+ export {
128
+ useMailsContext as default,
129
+ MailsContextProvider,
130
+ useUnreadEmailCount,
131
+ }
@@ -0,0 +1,68 @@
1
+ import HttpApiProvider from '../../libraries/base-api-provider';
2
+
3
+ /**
4
+ * API-Client for Collector
5
+ */
6
+ export default class CollektorVersion2ApiProvider extends HttpApiProvider {
7
+
8
+ /**
9
+ * @param {string} baseUrl URL which is used as the basis for the query URLs.
10
+ * @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.
11
+ */
12
+ constructor(baseUrl, acceptingLanguages) {
13
+ // ContentTypes wird auf JSON festgesetzt, da der ASiST-Server nur JSON spricht.
14
+ super(baseUrl, acceptingLanguages, ['application/json']);
15
+ }
16
+
17
+ /**
18
+ * Returns the request URL to get all news channels from the collector.
19
+ * @returns {URL}
20
+ */
21
+ getNewsChannelsUrl() {
22
+ return this.extendBaseUrl(['feed']);
23
+ }
24
+
25
+ /**
26
+ * Returns a list of all news channels.
27
+ * @returns {Array} Array of all news channels.
28
+ */
29
+ getNewsChannels() {
30
+ const getNewsChannelsUrl = this.getNewsChannelsUrl();
31
+
32
+ return this.get(getNewsChannelsUrl)
33
+ .then(response => response.json());
34
+ }
35
+
36
+ /**
37
+ * Returns the request URL to get the news of a news channel from the collector.
38
+ * @param {String} newsChannelId Id of news channel.
39
+ * @returns {URL} URL of the news from the given news channel.
40
+ */
41
+ getNewsUrl(newsChannelId) {
42
+ return this.extendBaseUrl(['feed', newsChannelId]);
43
+ }
44
+
45
+ /**
46
+ * Returns a list of all news from the queried news channel.
47
+ * @param {String} newsChannelId Id of news channel.
48
+ * @returns {Array} Array of all news of the news channel.
49
+ */
50
+ getNews(newsChannelId) {
51
+ const getNewsUrl = this.getNewsUrl(newsChannelId);
52
+
53
+ return this.get(getNewsUrl)
54
+ .then(response => response.json());
55
+ }
56
+
57
+ /**
58
+ * Creates a CollektorVersion2ApiProvider instance initialised to a list of standard languages, where the mainLanguage parameter specifies the mainLanguage.
59
+ * @param {string} baseUrl URL which is used as the basis for the query URLs.
60
+ * @param {string} mainLanguage Main language which is prioritised.
61
+ * @returns {CollektorVersion2ApiProvider} Created CollectorVersion2ApiProvider instance.
62
+ */
63
+ static from(baseUrl, mainLanguage = 'de') {
64
+ const acceptingLanguages = CollektorVersion2ApiProvider.languagesFromMainLanguages(mainLanguage);
65
+
66
+ return new CollektorVersion2ApiProvider(baseUrl, acceptingLanguages);
67
+ }
68
+ }