diff --git a/components/Map/Map.tsx b/components/Map/Map.tsx new file mode 100644 index 000000000..d802bec8d --- /dev/null +++ b/components/Map/Map.tsx @@ -0,0 +1,83 @@ +import React, { useRef, useCallback } from 'react' +import { View, ViewStyle } from 'react-native' +import { + WebViewLeaflet, + WebviewLeafletMessage, + WebViewLeafletProps, + AnimationType, +} from '@uclapi/react-native-webview-leaflet' +import { generate } from 'shortid' + +// eslint-disable-next-line quotes +interface Props extends Omit { + style?: ViewStyle, + mapMarkers?: { + position: { + lat: number, + lng: number, + }, + animation?: { + delay: number, + duration: number, + iterationCount: number, + type: AnimationType, + }, + }[], +} + +const defaultPosition = { + lat: 51.52411, + lng: -0.13282, +} + +const defaultMarker = { + animation: { + delay: 0, + duration: 0.5, + iterationCount: 1, + type: AnimationType.BOUNCE, + }, + icon: `📌`, + id: generate(), + size: [24, 24], +} + +const Map: React.FC = ({ + zoom = 16, + style, + mapCenterPosition = defaultPosition, + mapMarkers, +}) => { + const onMessageReceived = useCallback((message: WebviewLeafletMessage) => console.log(`Map received: `, message), []) + + const map = useRef(null) + + return ( + + ({ + ...defaultMarker, + ...marker, + animation: { + ...defaultMarker.animation, + ...marker?.animation, + }, + }))} + /> + + ) +} + +export default Map diff --git a/components/Map/index.ts b/components/Map/index.ts new file mode 100644 index 000000000..9c0363673 --- /dev/null +++ b/components/Map/index.ts @@ -0,0 +1 @@ +export { default } from './Map' diff --git a/package-lock.json b/package-lock.json index 0a18636cd..23e10291a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9704,6 +9704,41 @@ } } }, + "@uclapi/react-native-webview-leaflet": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@uclapi/react-native-webview-leaflet/-/react-native-webview-leaflet-5.0.3.tgz", + "integrity": "sha512-gKsluO1URBhYwiqLTysx7yfu5Np4nBENrHVjORnADGiXhwtB01iA+Yora1yJ+Fb9fQOeuyMFSwN/SuAElAg9rA==", + "requires": { + "expo-asset": "^7.0.0", + "expo-asset-utils": "^1.2.0", + "expo-file-system": "^8.0.0", + "leaflet": "^1.5.1", + "lodash.isequal": "^4.5.0", + "react-dom": "^16.10.2", + "react-leaflet": "^2.6.1", + "react-native-webview": "^9.4.0" + }, + "dependencies": { + "expo-asset": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-7.0.0.tgz", + "integrity": "sha512-MwWrlpzaZqT0NU0V3Wn8oA1pMb7Al49aYAWMPEUZ2UV5NyVAbzYPuS2duIfwX55ivczjJZHpwrhd0hb/3l9ngQ==", + "requires": { + "blueimp-md5": "^2.10.0", + "path-browserify": "^1.0.0", + "url-parse": "^1.4.4" + } + }, + "expo-file-system": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-8.1.0.tgz", + "integrity": "sha512-xb4roeU8CotW8t3LkmsrliNbgFpY2KB+3sW1NnujnH39pFVwCd/kfujCYzRauj8aUy/HhSq+3xGkQTpC7pSjVw==", + "requires": { + "uuid": "^3.4.0" + } + } + } + }, "@unimodules/core": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/@unimodules/core/-/core-5.3.0.tgz", @@ -15332,6 +15367,11 @@ "url-parse": "^1.4.4" } }, + "expo-asset-utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/expo-asset-utils/-/expo-asset-utils-1.2.0.tgz", + "integrity": "sha512-06zVi5aXzyMq7SFiawxu2FUbpbVlxnE9W44cG4K5HyhLaqyRqss+o5MZMEGn8Ibd+008UiK7yCPy/bSpx2hVag==" + }, "expo-auth-session": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/expo-auth-session/-/expo-auth-session-1.4.2.tgz", @@ -16574,8 +16614,7 @@ "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-glob": { "version": "3.2.4", @@ -24869,6 +24908,11 @@ "invert-kv": "^2.0.0" } }, + "leaflet": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz", + "integrity": "sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw==" + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -25391,6 +25435,11 @@ "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, "lodash.isobject": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", @@ -30743,7 +30792,6 @@ "version": "16.11.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.11.0.tgz", "integrity": "sha512-nrRyIUE1e7j8PaXSPtyRKtz+2y9ubW/ghNgqKFHHAHaeP0fpF5uXR+sq8IMRHC+ZUxw7W9NyCDTBtwWxvkb0iA==", - "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -30782,6 +30830,27 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-leaflet": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-2.7.0.tgz", + "integrity": "sha512-pMf5eRyWU8RH9HohM2i0NZymcWHraJA1m6iMFYu94/01PAaBJpOyxORZJmN6cV9dBzkVWaLjAAHTNmxbwIpcfw==", + "requires": { + "@babel/runtime": "^7.9.2", + "fast-deep-equal": "^3.1.1", + "hoist-non-react-statics": "^3.3.2", + "warning": "^4.0.3" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + } + } + }, "react-lifecycles-compat": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", @@ -35043,7 +35112,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", - "dev": true, "requires": { "loose-envify": "^1.0.0" } diff --git a/package.json b/package.json index eb84f6d2e..879a43d77 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "@react-navigation/material-top-tabs": "^5.2.17", "@react-navigation/native": "^5.7.3", "@react-navigation/stack": "^5.9.0", + "@uclapi/react-native-webview-leaflet": "^5.0.3", "axios": "^0.20.0", "base-64": "^0.1.0", "expo": "^38.0.10", diff --git a/screens/Timetable/TimetableDetailScreen/TimetableDetailView.tsx b/screens/Timetable/TimetableDetailScreen/TimetableDetailView.tsx index 912e8147a..4195e050e 100644 --- a/screens/Timetable/TimetableDetailScreen/TimetableDetailView.tsx +++ b/screens/Timetable/TimetableDetailScreen/TimetableDetailView.tsx @@ -1,9 +1,8 @@ import React from "react" -import { StyleSheet, View } from "react-native" -import MapView, { Marker } from "react-native-maps" - +import { Dimensions, StyleSheet, View } from "react-native" import Button from "../../../components/Button" import { Page } from "../../../components/Containers" +import Map from "../../../components/Map/Map" import { BodyText, ErrorText, @@ -15,7 +14,6 @@ import { LocalisationManager, MailManager, MapsManager } from "../../../lib" import type { MailManagerComposeAsyncReturnType, } from "../../../lib/MailManager" -import MapStyle from "../../../styles/Map" import type { Region, TimetableEvent } from "../../../types/uclapi" import type { TimetableNavigationType } from "../TimetableNavigator" @@ -27,6 +25,13 @@ const styles = StyleSheet.create({ emailButton: { marginTop: 10, }, + map: { + height: 300, + marginBottom: 10, + marginLeft: -20, + marginTop: 10, + width: Dimensions.get(`screen`).width, + }, }) interface Props extends TimetableEvent { @@ -186,7 +191,17 @@ class TimetableDetailView extends React.Component {  so the map may be incorrect. )} - + {/* { }} > - + */} diff --git a/screens/Timetable/TimetableScreen/components/WeekView.tsx b/screens/Timetable/TimetableScreen/components/WeekView.tsx index 9f3e1d28d..613030f7d 100644 --- a/screens/Timetable/TimetableScreen/components/WeekView.tsx +++ b/screens/Timetable/TimetableScreen/components/WeekView.tsx @@ -159,10 +159,12 @@ class WeekView extends React.Component { module: { name: moduleName, module_id: moduleId, + lecturer, }, location: { name: locationName, }, + session_type_str: sessionTypeStr, session_type: sessionType, start_time: startTime, end_time: endTime, @@ -178,8 +180,8 @@ class WeekView extends React.Component { moduleCode={moduleId} startTime={`${dateISO} ${startTime}`} endTime={`${dateISO} ${endTime}`} - location={locationName || `TBA`} - lecturer={contact || `Unknown Lecturer`} + location={(/online/gi).test(sessionTypeStr) ? sessionTypeStr : (locationName || `TBA`)} + lecturer={contact || lecturer?.name || `Unknown Lecturer`} pastEvent={past} key={`${dateISO}-${moduleId}-${startTime}-${endTime}-${sessionType}`} navigation={navigation} diff --git a/tsconfig.json b/tsconfig.json index 6d852bb96..0012524de 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,6 +14,7 @@ "sourceMap": true, "esModuleInterop": true, "checkJs": false, + "types": [] }, "include": [ "./types/customTypes.d.ts",