diff --git a/src/components/VolunteerOpportunity.js b/src/components/VolunteerOpportunity.js
index 8162180..ccd0930 100644
--- a/src/components/VolunteerOpportunity.js
+++ b/src/components/VolunteerOpportunity.js
@@ -21,6 +21,7 @@ import SimpleLineIcons from "@expo/vector-icons/SimpleLineIcons";
import { Image } from "expo-image";
import { Platform, StyleSheet, Text, View } from "react-native";
import { TouchableOpacity } from "react-native-gesture-handler";
+import Markdown from "react-native-markdown-display";
export default function VolunteerOpportunity({
navigation,
@@ -80,16 +81,23 @@ export default function VolunteerOpportunity({
{date}
{/* Location info with icon */}
-
+
- {" "}
- {location}
-
+
+ {location}
+
+
{/* Right-side indicator chevron */}
diff --git a/src/screens/VolunteerFormScreen.js b/src/screens/VolunteerFormScreen.js
index 39423c6..7ac0bdc 100644
--- a/src/screens/VolunteerFormScreen.js
+++ b/src/screens/VolunteerFormScreen.js
@@ -17,6 +17,7 @@ import {
Text,
View,
} from "react-native";
+import Markdown from "react-native-markdown-display";
import WebView from "react-native-webview";
import Fuse from "fuse.js";
import ErrorBoundary from "react-native-error-boundary";
@@ -24,12 +25,11 @@ import ErrorBoundary from "react-native-error-boundary";
import NextButton from "../components/NextButton";
import PersistScrollView from "../components/PersistScrollView";
-import { alertError, sendErrorEmail, openInMaps } from "../utils";
+import { openURL, sendErrorEmail } from "../utils";
import DanceClub from "../utils/forms/DanceClub";
import LibraryMusicHour from "../utils/forms/LibraryMusicHour";
import MusicByTheTracks from "../utils/forms/MusicByTheTracks";
import RequestConcert from "../utils/forms/RequestConcert";
-import colors from "../constants/colors";
import formIDs from "../constants/formIDs";
// Factory: choose form class by event title using fuzzy matching
@@ -160,14 +160,21 @@ export default function VolunteerFormScreen({ navigation, route }) {
)}
{location == null ? null : (
- openInMaps(location)}>
-
+ {
+ openURL(url);
+ return false;
+ }}
+ style={{
+ body: {
+ fontSize: 18,
+ },
+ }}
>
{location}
-
-
+
+
)}
{/* Render each question component from form */}
@@ -262,8 +269,4 @@ const styles = StyleSheet.create({
justifyContent: "flex-end",
marginBottom: 50,
},
- locationText: {
- textDecorationLine: "underline",
- color: colors.primary,
- },
});
diff --git a/src/screens/VolunteerOpportunityScreen.js b/src/screens/VolunteerOpportunityScreen.js
index a43ca75..912ffc2 100644
--- a/src/screens/VolunteerOpportunityScreen.js
+++ b/src/screens/VolunteerOpportunityScreen.js
@@ -14,14 +14,7 @@ import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons";
import SimpleLineIcons from "@expo/vector-icons/SimpleLineIcons";
import { ImageBackground } from "expo-image";
import { LinearGradient } from "expo-linear-gradient";
-import {
- Linking,
- Pressable,
- SafeAreaView,
- StyleSheet,
- Text,
- View,
-} from "react-native";
+import { Pressable, SafeAreaView, StyleSheet, Text, View } from "react-native";
import Heading from "../components/Heading";
import NextButton from "../components/NextButton";
@@ -29,7 +22,7 @@ import PersistScrollView from "../components/PersistScrollView";
import PostersButton from "../components/PostersButton";
import Tag from "../components/Tag";
import colors from "../constants/colors";
-import { openInMaps } from "../utils";
+import { openURL } from "../utils";
export default function VolunteerOpportunityScreen({ route, navigation }) {
// Destructure parameters passed via navigation
@@ -95,14 +88,19 @@ export default function VolunteerOpportunityScreen({ route, navigation }) {
size={20}
color={colors.black}
/>
- openInMaps(location)}>
-
- {location}
-
-
+ {
+ openURL(url);
+ return false;
+ }}
+ style={{
+ body: {
+ fontSize: 18,
+ },
+ }}
+ >
+ {location}
+
{/* Optional description section */}
@@ -111,7 +109,7 @@ export default function VolunteerOpportunityScreen({ route, navigation }) {
About
{
- Linking.openURL(url);
+ openURL(url);
return false;
}}
style={{
@@ -269,8 +267,4 @@ const styles = StyleSheet.create({
detailsText: {
fontSize: 18,
},
- locationText: {
- textDecorationLine: "underline",
- color: colors.primary,
- },
});
diff --git a/src/utils/index.js b/src/utils/index.js
index 7e84f61..0ba7008 100644
--- a/src/utils/index.js
+++ b/src/utils/index.js
@@ -2,14 +2,13 @@
* index.js
* Shared utility functions:
* - alertError: standardized error alert + EmailJS error report
- * - openURL / maybeOpenURL: external link handling with app store fallback
+ * - openURL: external link handling with app store fallback
* - request: retry wrapper with exponential backoff for network calls
* - strToDate / formatDate: Google Sheets date parsing and formatting
* - Question: form question helper class
* - emptyQuestionState: hook for question state
* - isAtLeast, isNotEmpty, isExactly: basic validation predicates
* - isValidEmail, isValidPhoneNumber: validator.js-backed field validators
- * - openInMaps: launch maps app for a location
*/
import Constants from "expo-constants";
@@ -79,30 +78,6 @@ export function openURL(url) {
});
}
-/**
- * Try to open URL, fallback to app store if scheme fails.
- * @param {string} url
- * @param {string} appName
- * @param {string} appStoreID
- * @param {string} playStoreID
- */
-export function maybeOpenURL(url, appName, appStoreID, playStoreID) {
- Linking.openURL(url).catch((error) => {
- if (error.code == "EUNSPECIFIED") {
- if (Platform.OS == "ios") {
- openURL(`https://apps.apple.com/us/app/${appName}/id${appStoreID}`);
- } else {
- openURL(`https://play.google.com/store/apps/details?id=${playStoreID}`);
- }
- } else {
- Alert.alert(
- `Unable to open URL`,
- `Your device does not support opening ${url} from this app. Please copy and paste the URL into your browser.`,
- );
- }
- });
-}
-
/**
* Utility delay function for retry backoff.
*/
@@ -215,25 +190,3 @@ export const isAtLeast = (value, len) =>
export const isNotEmpty = (value) => isAtLeast(value, 1);
export const isExactly = (value, len) =>
!isAtLeast(value, len + 1) && isAtLeast(value, len);
-
-/**
- * Launch maps application or fallback to web URL for a location.
- * @param {string} location
- */
-export function openInMaps(location) {
- const encodedLocation = encodeURIComponent(location);
- const url = Platform.select({
- ios: `maps://maps.apple.com/?q=${encodedLocation}`,
- android: `https://www.google.com/maps/search/?api=1&query=${encodedLocation}`,
- });
- Linking.canOpenURL(url).then((supported) => {
- if (supported) {
- Linking.openURL(url);
- } else {
- // Fallback to Google Maps web URL
- Linking.openURL(
- `https://www.google.com/maps/search/?api=1&query=${encodedLocation}`,
- );
- }
- });
-}