@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,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* You may obtain a copy of the License at
|
|
5
|
+
*
|
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
*
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import React from 'react';
|
|
16
|
+
|
|
17
|
+
import { useTheme } from "react-native-paper";
|
|
18
|
+
import createIconSet from '@expo/vector-icons/createIconSet';
|
|
19
|
+
import PropTypes from "prop-types";
|
|
20
|
+
import { SvgCssUri } from 'react-native-svg';
|
|
21
|
+
const glyphMap = {
|
|
22
|
+
"bus": "a",
|
|
23
|
+
"train": "b",
|
|
24
|
+
"close": "c",
|
|
25
|
+
"messages": "d",
|
|
26
|
+
"menu": "e",
|
|
27
|
+
"grid": "f",
|
|
28
|
+
"more-horizontal": "g",
|
|
29
|
+
"more-vertical": "h",
|
|
30
|
+
"paperplane-outline": "i",
|
|
31
|
+
"partlysunny": "j",
|
|
32
|
+
"partlysunny-outline": "k",
|
|
33
|
+
"rainy": "l",
|
|
34
|
+
"rainy-outline": "m",
|
|
35
|
+
"thunderstorm": "n",
|
|
36
|
+
"thunderstorm-outline": "o",
|
|
37
|
+
"sunny": "p",
|
|
38
|
+
"sunny-outline": "q",
|
|
39
|
+
"down": "r",
|
|
40
|
+
"download": "s",
|
|
41
|
+
"print": "t",
|
|
42
|
+
"hilfe": "u",
|
|
43
|
+
"back": "v",
|
|
44
|
+
"lock": "w",
|
|
45
|
+
"lock-open": "x",
|
|
46
|
+
"navigation": "y",
|
|
47
|
+
"forward": "z",
|
|
48
|
+
"profile": "A",
|
|
49
|
+
"opal": "B",
|
|
50
|
+
"mensa": "C",
|
|
51
|
+
"location": "D",
|
|
52
|
+
"inbox": "E",
|
|
53
|
+
"imprint": "F",
|
|
54
|
+
"pts": "G",
|
|
55
|
+
"feedback": "H",
|
|
56
|
+
"book": "I",
|
|
57
|
+
"news": "J",
|
|
58
|
+
"up": "K",
|
|
59
|
+
"tram": "L",
|
|
60
|
+
"rss": "M",
|
|
61
|
+
"map-search": "N",
|
|
62
|
+
"m-start1": "O",
|
|
63
|
+
"dashboard": "P",
|
|
64
|
+
"timetable": "Q",
|
|
65
|
+
"search": "R",
|
|
66
|
+
"settings": "S",
|
|
67
|
+
"coffee": "T",
|
|
68
|
+
"check": "V",
|
|
69
|
+
"star": "W",
|
|
70
|
+
"star-selected": "X",
|
|
71
|
+
"edit": "Y",
|
|
72
|
+
"time": "A1",
|
|
73
|
+
"open-external": "A2",
|
|
74
|
+
"share": "1",
|
|
75
|
+
"accessibility": "A3",
|
|
76
|
+
};
|
|
77
|
+
const CustomIcon = createIconSet(glyphMap, 'openasist');
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Icons of the Openasist app
|
|
82
|
+
*
|
|
83
|
+
* This component handles the load of the icon font and
|
|
84
|
+
* provides a simple way to include these icons.
|
|
85
|
+
*
|
|
86
|
+
* Parameters:
|
|
87
|
+
* - icon: Name (slug) of the icon
|
|
88
|
+
* - size: Size (as Number) of the icon
|
|
89
|
+
* - color: Color of the icon
|
|
90
|
+
*
|
|
91
|
+
* Navigation-Parameters:
|
|
92
|
+
* - none
|
|
93
|
+
*/
|
|
94
|
+
function IconsOpenasist({ icon, iconSVG: IconSVG, size, color, accessibilityLabel, ...props }) {
|
|
95
|
+
const theme = useTheme();
|
|
96
|
+
const { AppIcons } = theme;
|
|
97
|
+
|
|
98
|
+
const iconSize = size ?? 26;
|
|
99
|
+
const iconAriaLabel = props?.['aria-label'] ?? accessibilityLabel ?? null;
|
|
100
|
+
const iconAriaHidden = iconAriaLabel ? false : true;
|
|
101
|
+
|
|
102
|
+
const iconProps = {
|
|
103
|
+
color: color ?? 'black',
|
|
104
|
+
'aria-hidden': iconAriaHidden,
|
|
105
|
+
'aria-label': iconAriaLabel,
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (IconSVG) {
|
|
109
|
+
return (
|
|
110
|
+
<IconSVG
|
|
111
|
+
{...iconProps}
|
|
112
|
+
width={iconSize}
|
|
113
|
+
height={iconSize}
|
|
114
|
+
/>
|
|
115
|
+
);
|
|
116
|
+
} else if (AppIcons) {
|
|
117
|
+
return (
|
|
118
|
+
<AppIcons
|
|
119
|
+
{...iconProps}
|
|
120
|
+
name={icon}
|
|
121
|
+
size={iconSize}
|
|
122
|
+
/>
|
|
123
|
+
);
|
|
124
|
+
} else {
|
|
125
|
+
return (
|
|
126
|
+
<CustomIcon
|
|
127
|
+
{...iconProps}
|
|
128
|
+
name={icon}
|
|
129
|
+
size={iconSize}
|
|
130
|
+
/>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// propTypes für Funktionen wird in react.js 19 entfernt
|
|
136
|
+
IconsOpenasist.propTypes = {
|
|
137
|
+
icon: PropTypes.string,
|
|
138
|
+
iconSVG: PropTypes.func,
|
|
139
|
+
size: PropTypes.number,
|
|
140
|
+
color: PropTypes.string
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export default IconsOpenasist;
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
* you may not use this file except in compliance with the License.
|
|
4
|
+
* You may obtain a copy of the License at
|
|
5
|
+
*
|
|
6
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
*
|
|
8
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
* See the License for the specific language governing permissions and
|
|
12
|
+
* limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import React from 'react';
|
|
16
|
+
import messaging from '@react-native-firebase/messaging';
|
|
17
|
+
|
|
18
|
+
import notifee, { AndroidStyle, EventType } from '@notifee/react-native';
|
|
19
|
+
import { feedApi, RootNavigation, store, updateFeeds } from '../core';
|
|
20
|
+
import SubscriberService from './services/subscriber.service'
|
|
21
|
+
|
|
22
|
+
export default class OpenASiSTNotifications {
|
|
23
|
+
subscriberService = null
|
|
24
|
+
|
|
25
|
+
navConfig = null;
|
|
26
|
+
|
|
27
|
+
languages = null;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @param configuration: Object (see 'notification' in Settings.js)
|
|
32
|
+
* @param navigationConfiguration : Object (see 'navigation' in Settings.js)
|
|
33
|
+
* @param languages : Object (see 'languages' in Settings.js)
|
|
34
|
+
*/
|
|
35
|
+
constructor(configuration, navigationConfiguration, languages) {
|
|
36
|
+
this.subscriberService = new SubscriberService(configuration);
|
|
37
|
+
this.navConfig = navigationConfiguration;
|
|
38
|
+
this.languages = languages;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* App is in background, handle incoming messages
|
|
43
|
+
*
|
|
44
|
+
* Important: This function must be called as soon as possible! (Before app initialization)
|
|
45
|
+
*/
|
|
46
|
+
initBackgroundHandler() {
|
|
47
|
+
messaging().setBackgroundMessageHandler(async remoteMessage => {
|
|
48
|
+
await this.createNotification(remoteMessage);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
notifee.onBackgroundEvent(async ({ type, detail }) => {
|
|
52
|
+
await this.handlePNAction(type, detail);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* App is in foreground
|
|
58
|
+
*/
|
|
59
|
+
initForegroundHandler() {
|
|
60
|
+
this.requestPermission().then(async () => {
|
|
61
|
+
await this.subscriberService.initializeSubscriber();
|
|
62
|
+
|
|
63
|
+
// Listen for new Messages while the app is in foreground
|
|
64
|
+
messaging().onMessage(async remoteMessage => {
|
|
65
|
+
await this.createNotification(remoteMessage);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
notifee.onForegroundEvent(async ({ type, detail }) => {
|
|
69
|
+
await this.handlePNAction(type, detail);
|
|
70
|
+
})
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
unregister() {
|
|
75
|
+
// Unregister the user device from firebase
|
|
76
|
+
messaging().unregisterDeviceForRemoteMessages().then(() => {/* Unregistered */});
|
|
77
|
+
notifee.cancelAllNotifications().then(() => {/* Cancelled all notifications */});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Handle all actions of a push notification, no matter if back- or foreground
|
|
82
|
+
*
|
|
83
|
+
* @param type
|
|
84
|
+
* @param detail
|
|
85
|
+
* @returns {Promise<void>}
|
|
86
|
+
*/
|
|
87
|
+
async handlePNAction(type, detail) {
|
|
88
|
+
// notification details and action (like "mark as seen") the user has pressed
|
|
89
|
+
const { notification, pressAction } = detail;
|
|
90
|
+
switch(type) {
|
|
91
|
+
case EventType.PRESS:
|
|
92
|
+
const {newsDetail} = this.navConfig;
|
|
93
|
+
this.subscriberService.markNotificationAsSeen(notification.id);
|
|
94
|
+
await notifee.cancelNotification(notification.id);
|
|
95
|
+
RootNavigation.onNavigationReady(() => {
|
|
96
|
+
// Trigger News Refresh
|
|
97
|
+
store.dispatch( updateFeeds() );
|
|
98
|
+
RootNavigation.navigate(newsDetail.screen, newsDetail.params(notification.data.payload));
|
|
99
|
+
});
|
|
100
|
+
break;
|
|
101
|
+
case EventType.APP_BLOCKED:
|
|
102
|
+
case EventType.DISMISSED:
|
|
103
|
+
this.subscriberService.markNotificationAsSeen(notification.id);
|
|
104
|
+
await notifee.cancelNotification(notification.id);
|
|
105
|
+
break;
|
|
106
|
+
case EventType.FG_ALREADY_EXIST:
|
|
107
|
+
await notifee.cancelNotification(notification.id);
|
|
108
|
+
break;
|
|
109
|
+
/*
|
|
110
|
+
case EventType.ACTION_PRESS && pressAction.id === 'mark-as-read':
|
|
111
|
+
this.subscriberService.markNotificationAsSeen(notification.id)
|
|
112
|
+
// Remove the notification
|
|
113
|
+
await notifee.cancelNotification(notification.id);
|
|
114
|
+
break;
|
|
115
|
+
*/
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Request permission to display notifications
|
|
122
|
+
*
|
|
123
|
+
* @returns {Promise<void>}
|
|
124
|
+
*/
|
|
125
|
+
async requestPermission() {
|
|
126
|
+
const authStatus = await notifee.requestPermission({
|
|
127
|
+
criticalAlert: true
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const enabled =
|
|
131
|
+
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
|
|
132
|
+
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
|
|
133
|
+
|
|
134
|
+
await notifee.requestPermission({
|
|
135
|
+
criticalAlert: true
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
if (enabled) {
|
|
139
|
+
console.log('Authorization status:', authStatus);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Collect data and create the notification
|
|
146
|
+
* @returns {Promise<void>}
|
|
147
|
+
*/
|
|
148
|
+
async createNotification(messageDetails) {
|
|
149
|
+
const language = store.getState().settingReducer.settingsGeneral.language;
|
|
150
|
+
const {enabledFeedNotifications, enableAllNotifications, enablePushNotifications} = store.getState().settingReducer.settingsNotifications;
|
|
151
|
+
if(!enablePushNotifications) return;
|
|
152
|
+
|
|
153
|
+
const {notificationId, type, id, fallbackMessage} = messageDetails?.data;
|
|
154
|
+
const isCritical = type === 'critical';
|
|
155
|
+
|
|
156
|
+
let fallbackText = '';
|
|
157
|
+
try {
|
|
158
|
+
const fallback = JSON.parse(fallbackMessage);
|
|
159
|
+
fallbackText = fallback[language];
|
|
160
|
+
} catch( e) {
|
|
161
|
+
fallbackText = fallbackMessage;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if(type === undefined || id === undefined || id === null || id === "") {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
switch(type) {
|
|
169
|
+
case 'critical':
|
|
170
|
+
case 'feed':
|
|
171
|
+
feedApi.getNewsById(id, news => {
|
|
172
|
+
if(news === -1 || (news && !news.title)) {
|
|
173
|
+
return;
|
|
174
|
+
} else if(news !== 0 && news.title) {
|
|
175
|
+
// If not all notifications, feed notification or the explicit feed are enabled, return
|
|
176
|
+
if(!enabledFeedNotifications || enabledFeedNotifications?.length === 0 || (enabledFeedNotifications?.length > 0 && enabledFeedNotifications.indexOf(parseInt(news.originFeedId, 10)) === -1)) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
this.displayNotification({
|
|
180
|
+
id: notificationId,
|
|
181
|
+
title: news.title,
|
|
182
|
+
desc: news.shortDesc,
|
|
183
|
+
image: news.descImageUrl,
|
|
184
|
+
isCritical,
|
|
185
|
+
payload: news
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
break;
|
|
190
|
+
case 'grades':
|
|
191
|
+
// TODO -> Network request + display notification
|
|
192
|
+
break;
|
|
193
|
+
|
|
194
|
+
default:
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Show a notification
|
|
202
|
+
*
|
|
203
|
+
* @param notification
|
|
204
|
+
* @returns {Promise<void>}
|
|
205
|
+
*/
|
|
206
|
+
async displayNotification(notification) {
|
|
207
|
+
const {id, title, desc, image, isCritical, payload} = notification;
|
|
208
|
+
|
|
209
|
+
if(!id) { console.error('Id is required to display a notification'); return; }
|
|
210
|
+
if(!title) { console.error('Title is required to display a notification'); return; }
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
// Create a channel (required for Android)
|
|
214
|
+
const defaultChannelId = await notifee.createChannel({
|
|
215
|
+
id: 'common',
|
|
216
|
+
name: 'Allgemeine Benachrichtigungen',
|
|
217
|
+
sound: 'default'
|
|
218
|
+
});
|
|
219
|
+
const criticalChannelId = await notifee.createChannel({
|
|
220
|
+
id: 'critically',
|
|
221
|
+
name: 'Kritische Benachrichtigungen',
|
|
222
|
+
bypassDnd: true,
|
|
223
|
+
sound: 'default'
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// Additional Android Settings:
|
|
227
|
+
let android = {};
|
|
228
|
+
if(image) {
|
|
229
|
+
// NOTE: iOS Requires local files: https://notifee.app/react-native/reference/iosnotificationattachment
|
|
230
|
+
// So this isn't implemented right now.
|
|
231
|
+
android = {
|
|
232
|
+
style: { type: AndroidStyle.BIGPICTURE, picture: image}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
await notifee.displayNotification({
|
|
238
|
+
id,
|
|
239
|
+
title,
|
|
240
|
+
|
|
241
|
+
// By default notifee supports basic HTML tags and removes unsupported ones, but we need to replace the escaped characters
|
|
242
|
+
body: desc,
|
|
243
|
+
data: {
|
|
244
|
+
notificationId: id,
|
|
245
|
+
payload
|
|
246
|
+
},
|
|
247
|
+
android: {
|
|
248
|
+
...android,
|
|
249
|
+
channelId: isCritical ? criticalChannelId : defaultChannelId,
|
|
250
|
+
smallIcon: 'notification_icon',
|
|
251
|
+
//smallIcon: 'name-of-a-small-icon', // optional, defaults to 'ic_launcher'.
|
|
252
|
+
// pressAction is needed if you want the notification to open the app when pressed
|
|
253
|
+
pressAction: {
|
|
254
|
+
id: 'default',
|
|
255
|
+
},
|
|
256
|
+
sound:'default'
|
|
257
|
+
},
|
|
258
|
+
ios: isCritical ? {
|
|
259
|
+
critical: true,
|
|
260
|
+
//sound: 'critical.wav',
|
|
261
|
+
// iOS > 12
|
|
262
|
+
// play at 90% sound volume
|
|
263
|
+
criticalVolume: 0.9,
|
|
264
|
+
sound: 'default'
|
|
265
|
+
} : {sound: 'default'}
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import uuid from 'react-native-uuid';
|
|
2
|
+
import messaging from '@react-native-firebase/messaging';
|
|
3
|
+
import debounce from 'lodash/debounce';
|
|
4
|
+
|
|
5
|
+
import { store } from '../../core';
|
|
6
|
+
import { POSTOptions } from '../../core/constants/api';
|
|
7
|
+
import { onNotificationsSubscriberUpdate } from '../../core/redux/actions/notifications';
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export default class SubscriberService {
|
|
11
|
+
notificationServerUrl = '';
|
|
12
|
+
universityCode = '';
|
|
13
|
+
subscriberId = null
|
|
14
|
+
|
|
15
|
+
constructor(configuration) {
|
|
16
|
+
if(!configuration.notificationServerUrl) {
|
|
17
|
+
throw Error('Missing Notification Server Url');
|
|
18
|
+
}
|
|
19
|
+
if(!configuration.universityCode) {
|
|
20
|
+
throw Error('Missing University Code');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
this.notificationServerUrl = configuration.notificationServerUrl;
|
|
24
|
+
this.notificationStgServerUrl = configuration.notificationStgServerUrl;
|
|
25
|
+
this.universityCode = configuration.universityCode;
|
|
26
|
+
this.upsertSubscriber = debounce(this.upsertSubscriber, 2000);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Register a new Subscriber or update the existing one
|
|
32
|
+
*/
|
|
33
|
+
async initializeSubscriber() {
|
|
34
|
+
this.subscriberId = this.getSubscriberId();
|
|
35
|
+
if(!messaging().isDeviceRegisteredForRemoteMessages) {
|
|
36
|
+
await messaging().registerDeviceForRemoteMessages();
|
|
37
|
+
}
|
|
38
|
+
const token = await this.getFCMToken();
|
|
39
|
+
|
|
40
|
+
await this.upsertSubscriber(token);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Return the subscriber id stored in the redux store or create a new ID.
|
|
46
|
+
*
|
|
47
|
+
* @returns string subscriberId
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
getSubscriberId() {
|
|
51
|
+
let subscriberId = store.getState().notificationsReducer.subscriberId;
|
|
52
|
+
|
|
53
|
+
if(subscriberId) {
|
|
54
|
+
return subscriberId;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
subscriberId = uuid.v4();
|
|
58
|
+
store.dispatch(onNotificationsSubscriberUpdate(subscriberId));
|
|
59
|
+
return subscriberId;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get Device Token for Firebase Cloud Messaging
|
|
65
|
+
*
|
|
66
|
+
* @returns {Promise<void>}
|
|
67
|
+
*/
|
|
68
|
+
async getFCMToken() {
|
|
69
|
+
return await messaging().getToken();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Register / Update a subscriber (=user) with the current device token
|
|
75
|
+
*
|
|
76
|
+
* @returns {Promise<void>}
|
|
77
|
+
*/
|
|
78
|
+
async upsertSubscriber(token, skipRefresh = false) {
|
|
79
|
+
const useStaging = store.getState().settingReducer.settingsDevelop.useStaging;
|
|
80
|
+
const url = useStaging ? this.notificationStgServerUrl : this.notificationServerUrl
|
|
81
|
+
|
|
82
|
+
fetch(
|
|
83
|
+
`${url}/subscriber?subscriberId=${this.subscriberId}&universityCode=${this.universityCode}&token=${token}&useDev=${useStaging}`,
|
|
84
|
+
{...POSTOptions})
|
|
85
|
+
.then((response) => response.json())
|
|
86
|
+
.then(() => {
|
|
87
|
+
// subscriber updated
|
|
88
|
+
})
|
|
89
|
+
.catch((error) => {
|
|
90
|
+
console.warn('Error Code: 1100 : ', error);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Listen for Token updates
|
|
94
|
+
if(!skipRefresh) {
|
|
95
|
+
messaging().onTokenRefresh(newToken => {
|
|
96
|
+
this.upsertSubscriber(newToken, true);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Mark a single notification as send
|
|
104
|
+
*
|
|
105
|
+
* @param notificationId
|
|
106
|
+
*/
|
|
107
|
+
markNotificationAsSeen(notificationId) {
|
|
108
|
+
const useStaging = store.getState().settingReducer.settingsDevelop.useStaging;
|
|
109
|
+
const url = useStaging ? this.notificationStgServerUrl : this.notificationServerUrl
|
|
110
|
+
|
|
111
|
+
fetch(
|
|
112
|
+
`${url}/markAsSeen?subscriberId=${this.subscriberId}&universityCode=${this.universityCode}¬ificationId=${notificationId}&useDev=${useStaging}`,
|
|
113
|
+
{...POSTOptions})
|
|
114
|
+
.then((response) => response.json())
|
|
115
|
+
.then(() => {
|
|
116
|
+
// Notification marked as seen
|
|
117
|
+
})
|
|
118
|
+
.catch((error) => {
|
|
119
|
+
console.warn('Error Code: 1101 : ', error);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# React Native WebView Autoheight
|
|
2
|
+
React Native WebView which sets it's height automatically with minimal efforts.
|
|
3
|
+
|
|
4
|
+
You can also add custom CSS style or javascript to your webview using below example.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
> npm install --save react-native-webview-autoheight
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
import MyWebView from 'react-native-webview-autoheight';
|
|
19
|
+
const customStyle = "<style>* {max-width: 100%;} body {font-family: sans-serif;} h1 {color: red;}</style>";
|
|
20
|
+
const htmlContent = "<h1>This is title</h1><p>Throw your entire HTML here</p>";
|
|
21
|
+
|
|
22
|
+
<MyWebView
|
|
23
|
+
source={{html: customStyle + htmlContent}}
|
|
24
|
+
startInLoadingState={true}
|
|
25
|
+
/>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
<MyWebView
|
|
30
|
+
source={{uri: 'http://example.com/helloworld.html'}}
|
|
31
|
+
startInLoadingState={true}
|
|
32
|
+
/>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Props
|
|
37
|
+
* Same as https://facebook.github.io/react-native/docs/webview.html#props
|
|
38
|
+
* `autoHeight` (default: true)
|
|
39
|
+
* `width` (default: Screen width)
|
|
40
|
+
* `defaultHeight` (default height unless autoHeight)
|
|
41
|
+
|
|
42
|
+
## How it works
|
|
43
|
+
It is a very simple wrapper around the built-in React Native Webview, which updates the height of the webview based on a state change using `onNavigationStateChange`.
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
### Feel free to add issues or feature requests
|
|
47
|
+
|