@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.
- package/components/AppBar/index.js +84 -0
- package/components/AppBar/styles.js +27 -0
- package/components/BookDetail/index.js +268 -0
- package/components/BookDetail/styles.js +124 -0
- package/components/ComponentJobsFilter/index.js +188 -0
- package/components/ComponentJobsFilter/styles.js +12 -0
- package/components/ConnectivityWarning/index.js +65 -0
- package/components/ConnectivityWarning/styles.js +19 -0
- package/components/ContactDetail/index.js +232 -0
- package/components/ContactDetail/styles.js +32 -0
- package/components/CourseDetail/index.js +357 -0
- package/components/CourseDetail/styles.js +59 -0
- package/components/CourseDetailDialog/index.js +169 -0
- package/components/CourseDetailDialog/styles.js +116 -0
- package/components/CourseInfo/index.js +219 -0
- package/components/CourseInfo/styles.js +40 -0
- package/components/DevelopmentDialog/index.js +214 -0
- package/components/DevelopmentDialog/styles.js +10 -0
- package/components/EventCodeInput/index.js +149 -0
- package/components/EventCodeInput/styles.js +108 -0
- package/components/FlexMenuEntry/index.js +84 -0
- package/components/FlexMenuEntry/styles.js +27 -0
- package/components/MainMenuEntry/index.js +88 -0
- package/components/MainMenuEntry/styles.js +28 -0
- package/components/MealItem/index.js +87 -0
- package/components/MealItem/styles.js +84 -0
- package/components/MensaMenu/index.js +305 -0
- package/components/MensaMenu/styles.js +94 -0
- package/components/MensaSlider/index.js +188 -0
- package/components/MensaSlider/styles.js +53 -0
- package/components/Modal/index.js +106 -0
- package/components/Modal/styles.js +8 -0
- package/components/NewsDetail/index.js +377 -0
- package/components/NewsDetail/styles.js +77 -0
- package/components/NewsList/index.js +120 -0
- package/components/NewsList/styles.js +19 -0
- package/components/NewsListItem/index.js +89 -0
- package/components/NewsListItem/styles.js +32 -0
- package/components/OtherCourses/index.js +152 -0
- package/components/OtherCourses/styles.js +10 -0
- package/components/PtsDeparture/index.js +140 -0
- package/components/PtsDeparture/styles.js +7 -0
- package/components/PtsStation/index.js +186 -0
- package/components/PtsStation/styles.js +47 -0
- package/components/QuickLinks/index.js +127 -0
- package/components/QuickLinks/styles.js +45 -0
- package/components/RoomDetail/index.js +281 -0
- package/components/RoomDetail/styles.js +56 -0
- package/components/ScaledImage/index.js +92 -0
- package/components/SearchResults/index.js +362 -0
- package/components/SearchResults/styles.js +59 -0
- package/components/SettingSection/index.js +54 -0
- package/components/SettingSection/styles.js +15 -0
- package/components/SettingsDialog/index.js +52 -0
- package/components/SettingsDialog/styles.js +12 -0
- package/components/SettingsDialogRadio/index.js +66 -0
- package/components/SettingsDialogRadio/styles.js +7 -0
- package/components/SettingsDialogSelect/index.js +73 -0
- package/components/SettingsDialogSelect/styles.js +7 -0
- package/components/TimetableCodeInput/index.js +205 -0
- package/components/TimetableCodeInput/styles.js +28 -0
- package/components/TimetableDay/index.js +252 -0
- package/components/TimetableDay/styles.js +103 -0
- package/components/TimetableEvent/index.js +163 -0
- package/components/TimetableEvent/styles.js +108 -0
- package/components/TimetableList/index.js +180 -0
- package/components/TimetableList/styles.js +106 -0
- package/components/TimetableMonth/index.js +156 -0
- package/components/TimetableMonth/styles.js +29 -0
- package/components/TimetableWeek/index.js +230 -0
- package/components/TimetableWeek/styles.js +58 -0
- package/components/TopNews/index.js +282 -0
- package/components/TopNews/styles.js +125 -0
- package/components/TopNewsHtwk/index.js +279 -0
- package/components/TopNewsHtwk/styles.js +142 -0
- package/components/WebView/index.js +108 -0
- package/components/WebView/styles.js +11 -0
- package/context/context-callmanager/TucCallManager.js +74 -0
- package/context/context-callmanager/index.js +128 -0
- package/context/context-canteen/AsistServerApiProvider.js +126 -0
- package/context/context-canteen/CollektorVersion2ApiProvider.js +100 -0
- package/context/context-canteen/index.js +692 -0
- package/context/context-connectivity/index.js +85 -0
- package/context/context-event/AsistServerClient.js +82 -0
- package/context/context-event/index.js +205 -0
- package/context/context-flex-menu/AsistServerApiProvider.js +0 -0
- package/context/context-flex-menu/CollectorVersion2ApiProvider.js +32 -0
- package/context/context-flex-menu/index.js +160 -0
- package/context/context-info-dialog/CollektorVersion2ApiProvider.js +53 -0
- package/context/context-info-dialog/ProviderErrors.js +22 -0
- package/context/context-info-dialog/index.js +190 -0
- package/context/context-mails/MailService.js +147 -0
- package/context/context-mails/TucUnseenApiProvider.js +65 -0
- package/context/context-mails/index.js +131 -0
- package/context/context-news/CollektorVersion2ApiProvider.js +68 -0
- package/context/context-news/index.js +155 -0
- package/context/context-public-transport-ticket/CollektorVersion2ApiProvider.js +45 -0
- package/context/context-public-transport-ticket/ProviderErrors.js +11 -0
- package/context/context-public-transport-ticket/index.js +175 -0
- package/context/context-timetable/CollectorVersion2ApiProvider.js +102 -0
- package/context/context-timetable/ProviderErrors.js +22 -0
- package/context/context-timetable/TimetableService.js +357 -0
- package/context/context-timetable/index.js +215 -0
- package/context/context-user/index.js +586 -0
- package/index.js +178 -0
- package/libraries/base-api-provider/hooks.js +24 -0
- package/libraries/base-api-provider/http-api-provider.js +168 -0
- package/libraries/base-api-provider/index.js +20 -0
- package/libraries/core/api/canteens.js +88 -0
- package/libraries/core/api/corona.js +45 -0
- package/libraries/core/api/courses.js +54 -0
- package/libraries/core/api/device.js +98 -0
- package/libraries/core/api/feed.js +144 -0
- package/libraries/core/api/feedback.js +123 -0
- package/libraries/core/api/jobs.js +48 -0
- package/libraries/core/api/library.js +67 -0
- package/libraries/core/api/lostfound.js +77 -0
- package/libraries/core/api/occupancy.js +44 -0
- package/libraries/core/api/officehours.js +25 -0
- package/libraries/core/api/poi.js +25 -0
- package/libraries/core/api/pts.js +68 -0
- package/libraries/core/api/rooms.js +31 -0
- package/libraries/core/api/survey.js +121 -0
- package/libraries/core/api/telephone.js +32 -0
- package/libraries/core/api/tucrooms.js +31 -0
- package/libraries/core/constants/actions.js +75 -0
- package/libraries/core/constants/api.js +146 -0
- package/libraries/core/constants/enums.js +5 -0
- package/libraries/core/helper/date.js +9 -0
- package/libraries/core/helper/format.helper.js +2 -0
- package/libraries/core/index.js +60 -0
- package/libraries/core/redux/actions/notifications.js +6 -0
- package/libraries/core/redux/actions/setting.js +75 -0
- package/libraries/core/redux/actions/state.js +74 -0
- package/libraries/core/redux/asyncDispatch.js +27 -0
- package/libraries/core/redux/reducers/api.js +190 -0
- package/libraries/core/redux/reducers/index.js +32 -0
- package/libraries/core/redux/reducers/notifications.js +16 -0
- package/libraries/core/redux/reducers/setting.js +99 -0
- package/libraries/core/redux/reducers/state.js +122 -0
- package/libraries/core/redux/selectors.js +123 -0
- package/libraries/core/redux/store.js +40 -0
- package/libraries/core/services/data.js +96 -0
- package/libraries/core/services/root-navigation.js +36 -0
- package/libraries/core/services/search.js +175 -0
- package/libraries/core-plugins/enums/replaceTypes.js +53 -0
- package/libraries/core-plugins/index.js +21 -0
- package/libraries/core-plugins/redux/actions/plugin.js +13 -0
- package/libraries/core-plugins/redux/reducers/plugin.js +210 -0
- package/libraries/icons-openasist/index.js +143 -0
- package/libraries/notifications/index.js +268 -0
- package/libraries/notifications/services/subscriber.service.js +123 -0
- package/libraries/react-native-webview-autoheight/README.md +47 -0
- package/libraries/react-native-webview-autoheight/index.js +140 -0
- package/libraries/react-native-webview-autoheight/package.json +37 -0
- package/libraries/react-native-webview-autoheight/utils.js +268 -0
- package/libraries/redux-offline/.eslintignore +1 -0
- package/libraries/redux-offline/.github/ISSUE_TEMPLATE/redux-offline-core-issues-template.md +25 -0
- package/libraries/redux-offline/.prettierrc +6 -0
- package/libraries/redux-offline/LICENSE +21 -0
- package/libraries/redux-offline/README.md +133 -0
- package/libraries/redux-offline/flow-typed/npm/redux-logger_vx.x.x.js +109 -0
- package/libraries/redux-offline/flow-typed/npm/redux_v4.x.x.js +100 -0
- package/libraries/redux-offline/lib/actions.js +46 -0
- package/libraries/redux-offline/lib/config.js +15 -0
- package/libraries/redux-offline/lib/constants.js +17 -0
- package/libraries/redux-offline/lib/defaults/defaultCommit.js +11 -0
- package/libraries/redux-offline/lib/defaults/defaultRollback.js +11 -0
- package/libraries/redux-offline/lib/defaults/detectNetwork.js +33 -0
- package/libraries/redux-offline/lib/defaults/detectNetwork.native.js +211 -0
- package/libraries/redux-offline/lib/defaults/discard.js +18 -0
- package/libraries/redux-offline/lib/defaults/effect.js +87 -0
- package/libraries/redux-offline/lib/defaults/index.js +32 -0
- package/libraries/redux-offline/lib/defaults/offlineStateLens.js +24 -0
- package/libraries/redux-offline/lib/defaults/persist.js +9 -0
- package/libraries/redux-offline/lib/defaults/persist.native.js +17 -0
- package/libraries/redux-offline/lib/defaults/persistAutoRehydrate.js +8 -0
- package/libraries/redux-offline/lib/defaults/queue.js +27 -0
- package/libraries/redux-offline/lib/defaults/retry.js +29 -0
- package/libraries/redux-offline/lib/index.js +115 -0
- package/libraries/redux-offline/lib/middleware.js +56 -0
- package/libraries/redux-offline/lib/offlineActionTracker.js +43 -0
- package/libraries/redux-offline/lib/send.js +112 -0
- package/libraries/redux-offline/lib/types.js +3 -0
- package/libraries/redux-offline/lib/updater.js +111 -0
- package/libraries/redux-offline/package.json +69 -0
- package/libraries/redux-offline/src/__tests__/defaults/discard.js +22 -0
- package/libraries/redux-offline/src/__tests__/defaults/effect.js +118 -0
- package/libraries/redux-offline/src/__tests__/index.js +116 -0
- package/libraries/redux-offline/src/__tests__/middleware.js +185 -0
- package/libraries/redux-offline/src/__tests__/offlineActionTracker.js +54 -0
- package/libraries/redux-offline/src/__tests__/send.js +208 -0
- package/libraries/redux-offline/src/actions.js +36 -0
- package/libraries/redux-offline/src/config.js +9 -0
- package/libraries/redux-offline/src/constants.js +18 -0
- package/libraries/redux-offline/src/defaults/defaultCommit.js +7 -0
- package/libraries/redux-offline/src/defaults/defaultRollback.js +7 -0
- package/libraries/redux-offline/src/defaults/detectNetwork.js +16 -0
- package/libraries/redux-offline/src/defaults/detectNetwork.native.js +148 -0
- package/libraries/redux-offline/src/defaults/discard.js +19 -0
- package/libraries/redux-offline/src/defaults/effect.js +86 -0
- package/libraries/redux-offline/src/defaults/index.js +25 -0
- package/libraries/redux-offline/src/defaults/offlineStateLens.js +11 -0
- package/libraries/redux-offline/src/defaults/persist.js +4 -0
- package/libraries/redux-offline/src/defaults/persist.native.js +9 -0
- package/libraries/redux-offline/src/defaults/persistAutoRehydrate.js +4 -0
- package/libraries/redux-offline/src/defaults/queue.js +20 -0
- package/libraries/redux-offline/src/defaults/retry.js +18 -0
- package/libraries/redux-offline/src/index.js +138 -0
- package/libraries/redux-offline/src/middleware.js +52 -0
- package/libraries/redux-offline/src/offlineActionTracker.js +40 -0
- package/libraries/redux-offline/src/send.js +111 -0
- package/libraries/redux-offline/src/types.js +127 -0
- package/libraries/redux-offline/src/updater.js +141 -0
- package/libraries/redux-offline/typings.d.ts +150 -0
- package/libraries/redux-offline/yarn.lock +6460 -0
- package/libraries/stored-state/index.js +155 -0
- package/package.json +68 -0
- package/views/Callmanager/index.js +148 -0
- package/views/Callmanager/styles.js +62 -0
- package/views/Canteens/index.js +383 -0
- package/views/Canteens/styles.js +89 -0
- package/views/Dashboard/index.js +176 -0
- package/views/Dashboard/styles.js +16 -0
- package/views/DashboardHtwk/index.js +197 -0
- package/views/DashboardHtwk/styles.js +24 -0
- package/views/Event/index.js +373 -0
- package/views/Event/styles.js +63 -0
- package/views/FeedList/index.js +165 -0
- package/views/FeedList/styles.js +15 -0
- package/views/FeedNews/index.js +243 -0
- package/views/FeedNews/styles.js +32 -0
- package/views/Flexmenu/index.js +185 -0
- package/views/Flexmenu/styles.js +62 -0
- package/views/FlexmenuWebview/index.js +167 -0
- package/views/FlexmenuWebview/styles.js +16 -0
- package/views/Howhy/index.js +151 -0
- package/views/Howhy/styles.js +11 -0
- package/views/Jobs/index.js +217 -0
- package/views/Jobs/styles.js +41 -0
- package/views/MainMenu/index.js +283 -0
- package/views/MainMenu/styles.js +36 -0
- package/views/NewsTabbar/index.js +164 -0
- package/views/NewsTabbar/styles.js +27 -0
- package/views/Opal/index.js +136 -0
- package/views/Opal/styles.js +11 -0
- package/views/PublicTransportTicket/index.js +173 -0
- package/views/PublicTransportTicket/styles.js +17 -0
- package/views/Search/index.js +186 -0
- package/views/Search/styles.js +67 -0
- package/views/SettingsAccessibility/index.js +148 -0
- package/views/SettingsAccessibility/styles.js +13 -0
- package/views/SettingsAppInfo/index.js +86 -0
- package/views/SettingsAppInfo/styles.js +18 -0
- package/views/SettingsCanteens/index.js +249 -0
- package/views/SettingsCanteens/styles.js +33 -0
- package/views/SettingsGeneral/index.js +173 -0
- package/views/SettingsGeneral/styles.js +28 -0
- package/views/SettingsNotifications/index.js +204 -0
- package/views/SettingsNotifications/styles.js +38 -0
- package/views/SettingsUser/index.js +170 -0
- package/views/SettingsUser/styles.js +17 -0
- package/views/TimetableCalendar/index.js +387 -0
- package/views/TimetableCalendar/styles.js +121 -0
- package/views/TimetableList/index.js +402 -0
- package/views/TimetableList/styles.js +55 -0
- package/views/Webviews/index.js +158 -0
- 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
|
+
}
|