share modal

This commit is contained in:
2025-10-20 12:08:09 +02:00
parent f49a0346a0
commit 8e281e8f78
4 changed files with 257 additions and 78 deletions
+3 -4
View File
@@ -58,7 +58,6 @@
},
"package": "com.omedis.musicland",
"permissions": [
"android.permission.RECORD_AUDIO",
"android.permission.CAMERA",
"android.permission.MODIFY_AUDIO_SETTINGS",
"android.permission.POST_NOTIFICATIONS"
@@ -74,7 +73,7 @@
{
"photosPermission": "Nous avons besoin d'accéder à votre galerie pour vous permettre d'ajouter des photos à vos tâches.",
"cameraPermission": "Nous avons besoin d'accéder à votre appareil photo pour vous permettre de prendre des photos de vos tâches.",
"microphonePermission": "Nous avons besoin d'accéder à votre microphone pour vous permettre d'enregistrer des messages vocaux pour vos tâches."
"microphonePermission": false
}
],
[
@@ -102,8 +101,8 @@
"expo-camera",
{
"cameraPermission": "Allow $(PRODUCT_NAME) to access your camera",
"microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone",
"recordAudioAndroid": true
"microphonePermission": false,
"recordAudioAndroid": false
}
],
"expo-audio",
+6 -12
View File
@@ -1,23 +1,17 @@
import React, {
useCallback,
useEffect,
useRef,
useState,
useGlobal,
} from "reactn";
import { Image, Pressable, Text, View } from "react-native";
import * as ImagePicker from "expo-image-picker";
import moment from "moment";
import { useActionSheet } from "@expo/react-native-action-sheet";
import * as DocumentPicker from "expo-document-picker";
import * as ImagePicker from "expo-image-picker";
import moment from "moment";
import { Image, Pressable, Text, View } from "react-native";
import Compressor from "react-native-compressor";
import useMinuit from "react-native-minuit/src/hooks/useMinuit";
import React, { useCallback, useEffect, useRef, useState } from "reactn";
import { arrayUnion } from "../config/firebase";
import Style, { gutterConstant, mainBorderRadius } from "../styles/Style";
import { Fonts, Palette } from "../styles";
import { icons } from "../assets";
import { Fonts, Palette } from "../styles";
import Style, { gutterConstant, mainBorderRadius } from "../styles/Style";
import { uploadFileToFirebase } from "../helpers/uploadToFirebase";
import useLayoutType from "../hooks/useLayoutType";
+195 -9
View File
@@ -222,8 +222,7 @@ const ShareModal = ({ payload }) => {
];
}, [encodedShareText, encodedUrl, payload?.options, shareTitle]);
return (
<AppActionSheet id="Share">
const mobileContent = (
<View style={styles.container}>
<BlurView
style={[styles.card, styles.blurCard]}
@@ -231,13 +230,6 @@ const ShareModal = ({ payload }) => {
intensity={40}
{...blurProps}
>
{/* <Pressable
onPress={closeSheet}
style={styles.closeButton}
hitSlop={8}
>
<Feather name="x" size={18} color={Palette.white} />
</Pressable> */}
<Text style={styles.heading}>{heading}</Text>
<View style={styles.linkRow}>
<Text numberOfLines={1} style={styles.linkText}>
@@ -294,6 +286,87 @@ const ShareModal = ({ payload }) => {
</View>
</BlurView>
</View>
);
const webContent = (
<View style={styles.webContainer}>
<View style={styles.webHeader}>
<Text style={styles.webHeading}>{heading}</Text>
<Pressable
onPress={closeSheet}
hitSlop={12}
style={styles.webCloseButton}
>
<Feather name="x" size={16} color={Palette.white} />
</Pressable>
</View>
<Text style={styles.webSubheading}>{shareMessage}</Text>
<View style={styles.webContent}>
<View style={styles.webLinkCard}>
<Text style={styles.webLinkLabel}>{linkLabel}</Text>
<View style={styles.webLinkActions}>
<Pressable
onPress={handleCopy}
style={[
styles.webActionButton,
styles.webPrimaryButton,
copied && styles.webActionButtonActive,
]}
>
<Feather
name={copied ? "check" : "copy"}
size={16}
color={Palette.white}
/>
<Text style={styles.webActionLabel}>
{copied ? "Lien copié" : "Copier le lien"}
</Text>
</Pressable>
<Pressable
onPress={onSystemShare}
style={[styles.webActionButton, styles.webSecondaryButton]}
>
<Feather name="share-2" size={16} color={Palette.white} />
<Text style={styles.webActionLabel}>Partager</Text>
</Pressable>
</View>
</View>
<View style={styles.webOptionsCard}>
<Text style={styles.webSectionHeading}>{sectionTitle}</Text>
<View style={styles.webOptionsGrid}>
{shareOptions.map((option, index) => {
const Icon = option?.Icon ?? Feather;
return (
<Pressable
key={option?.key || index}
onPress={() => handleShareOption(option)}
style={styles.webOptionRow}
>
<View style={styles.webOptionIcon}>
<Icon size={18} color={Palette.white} />
</View>
<Text style={styles.webOptionLabel}>{option?.label}</Text>
<Feather
name="chevron-right"
size={16}
color="rgba(255, 255, 255, 0.6)"
/>
</Pressable>
);
})}
</View>
</View>
</View>
</View>
);
return (
<AppActionSheet id="Share" webModal={isWeb} onClose={closeSheet}>
{isWeb ? webContent : mobileContent}
</AppActionSheet>
);
};
@@ -405,6 +478,119 @@ const styles = StyleSheet.create({
color: Palette.white,
fontFamily: FONT_FAMILY.InterMedium,
},
webContainer: {
gap: 24,
},
webHeader: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
gap: 12,
},
webHeading: {
flex: 1,
fontSize: 24,
color: Palette.white,
fontFamily: FONT_FAMILY.HelveticaNeueMedium,
},
webCloseButton: {
width: 32,
height: 32,
borderRadius: 16,
backgroundColor: "rgba(255, 255, 255, 0.08)",
alignItems: "center",
justifyContent: "center",
},
webSubheading: {
fontSize: 14,
color: "rgba(255, 255, 255, 0.65)",
fontFamily: FONT_FAMILY.InterMedium,
},
webContent: {
gap: 20,
},
webLinkCard: {
backgroundColor: "rgba(255, 255, 255, 0.06)",
borderRadius: 20,
paddingHorizontal: 20,
paddingVertical: 18,
gap: 16,
},
webLinkLabel: {
color: Palette.white,
fontSize: 15,
fontFamily: FONT_FAMILY.InterMedium,
overflow: "hidden",
},
webLinkActions: {
flexDirection: "row",
alignItems: "center",
gap: 12,
flexWrap: "wrap",
},
webActionButton: {
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
gap: 10,
paddingHorizontal: 18,
paddingVertical: 12,
borderRadius: 16,
},
webPrimaryButton: {
backgroundColor: Palette.primary,
},
webSecondaryButton: {
backgroundColor: "rgba(255, 255, 255, 0.08)",
},
webActionButtonActive: {
backgroundColor: Palette.darkRadioactivGreen,
},
webActionLabel: {
fontSize: 14,
color: Palette.white,
fontFamily: FONT_FAMILY.InterMedium,
},
webOptionsCard: {
backgroundColor: "rgba(255, 255, 255, 0.06)",
borderRadius: 20,
paddingHorizontal: 20,
paddingVertical: 22,
gap: 16,
},
webSectionHeading: {
fontSize: 18,
color: Palette.white,
fontFamily: FONT_FAMILY.HelveticaNeueMedium,
},
webOptionsGrid: {
gap: 12,
},
webOptionRow: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
gap: 12,
backgroundColor: "rgba(255, 255, 255, 0.04)",
borderRadius: 16,
paddingHorizontal: 18,
paddingVertical: 14,
},
webOptionIcon: {
width: 36,
height: 36,
borderRadius: 18,
alignItems: "center",
justifyContent: "center",
backgroundColor: "rgba(255, 255, 255, 0.08)",
marginRight: 4,
},
webOptionLabel: {
flex: 1,
fontSize: 15,
color: Palette.white,
fontFamily: FONT_FAMILY.InterMedium,
},
});
export default ShareModal;
+1 -1
View File
@@ -382,7 +382,7 @@ const RecordPlayback = ({ route }) => {
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: "user" },
audio: true,
audio: false,
});
if (cancelled) {
stream.getTracks().forEach((track) => track.stop());