diff --git a/API.js b/API.js index 832a5af..29ba4ad 100644 --- a/API.js +++ b/API.js @@ -304,6 +304,10 @@ const API = { return getCall("/user/" + CurrentProfile); }, updateMyProfile(profile, data) { + if (CurrentProfile) { + delete userNameCache[CurrentProfile]; + delete failedProfileCache[CurrentProfile]; + } return postCall("/user/myProfile", {profile, data}); }, searchProfiles(query){ diff --git a/Views/ProfileSettings.js b/Views/ProfileSettings.js index d525343..c4bba05 100644 --- a/Views/ProfileSettings.js +++ b/Views/ProfileSettings.js @@ -1,6 +1,6 @@ import React from "react"; -import { View, ImageBackground, ScrollView, Picker } from "react-native"; -import { Text, TextInput, Button, Divider, Checkbox, RadioButton } from "react-native-paper"; +import { View, ImageBackground, ScrollView, Platform } from "react-native"; +import { Text, TextInput, Button, Divider, Checkbox, Menu } from "react-native-paper"; import i18n from "../i18nMessages.js"; import Moment from 'moment'; import 'moment/min/locales'; @@ -25,6 +25,26 @@ let ProfileSettings = () => { const [updateKey, setUpdateKey] = React.useState(0); const [description, setDescription] = React.useState(viewerProfile.description || ""); const [uploading, setUploading] = React.useState(false); + const [languageMenuVisible, setLanguageMenuVisible] = React.useState(false); + const previewProfile = { + ...(GlobalState.me || {}), + profile: { + ...(GlobalState.me?.profile || {}), + firstName: name, + lastName: lastName, + description: description, + language: language, + photo: photoUrl, + }, + }; + + const languageOptions = [ + { value: "es", label: "Español" }, + { value: "en", label: "English" }, + { value: "da", label: "Danish" }, + { value: "fr", label: "French" }, + ]; + const currentLanguageLabel = languageOptions.find((opt) => opt.value === language)?.label || "English"; const pickImage = async () => { if (uploading) return; @@ -44,8 +64,8 @@ let ProfileSettings = () => { setphotoUrl(newPhotoURL); if (!GlobalState.me.profile) GlobalState.me.profile = {}; GlobalState.me.profile.photo = newPhotoURL; - updateProfile() - setUpdateKey(updateKey + 1); + await updateProfile({ photo: newPhotoURL }); + setUpdateKey((k) => k + 1); } setPhoto(null); setUploading(false); @@ -91,27 +111,51 @@ let ProfileSettings = () => { return uploadedFile; }; - let updateProfile = async () => { - let currentProfile = await API.getUserProfile(viewer?._id); - const currentData = currentProfile?.data || {}; - currentProfile = currentProfile?.profile || {}; + let updateProfile = async (overrides = {}) => { + let currentProfile = {}; + let currentData = {}; try { - //let currentProfile = JSON.parse(JSON.stringify(viewer.profile)); - currentProfile.firstName = name; - currentProfile.lastName = lastName; - currentProfile.description = description; - currentProfile.language = language; - currentProfile.photo = photoUrl; + currentData = JSON.parse(JSON.stringify(viewer?.data || {})); + } catch (_) { + currentData = {}; + } + try { + currentProfile = { + firstName: name, + lastName: lastName, + description, + language, + photo: overrides.photo ?? photoUrl, + }; console.log("updating", currentProfile); } catch (error) { alert("Error updating profile, contact administrator."); return; } let r = await API.updateMyProfile(currentProfile, currentData).catch((e) => { + console.error("Profile update request failed", e); alert("Error updating profile, contact administrator."); + return null; }); + if (!r || r.status !== "ok") { + console.error("Profile update unexpected response", r); + return alert("Error updating profile, contact administrator."); + } + const refreshedProfile = await API.getUserProfile(viewer?._id, true).catch(() => null); + if (refreshedProfile && refreshedProfile._id) { + GlobalState.me = { + ...GlobalState.me, + ...refreshedProfile, + }; + } else { + if (!GlobalState.me.profile) GlobalState.me.profile = {}; + GlobalState.me.profile = { + ...GlobalState.me.profile, + ...currentProfile, + }; + } console.log(r); - setUpdateKey(updateKey + 1); + setUpdateKey((k) => k + 1); } return ( @@ -122,7 +166,12 @@ let ProfileSettings = () => { imageStyle={{ resizeMode: "contain", opacity: 0.05 }} style={{ paddingBottom: 50 }} > - Profile Settings + + + + Profile Setting + + { value={description} onChangeText={text => setDescription(text)} /> - Language: - - - - - - - + Language: + + setLanguageMenuVisible(false)} + anchor={ + + } + > + {languageOptions.map((option) => ( + { + setLanguage(option.value); + setLanguageMenuVisible(false); + }} + /> + ))} + - - - - Preview: - - - + + {/* {i18n.t("message.optional")}: @@ -201,6 +268,7 @@ let ProfileSettings = () => { //onChangeText={text => setLastName(text)} /> + */} ) diff --git a/components/ProfileHeader.js b/components/ProfileHeader.js index 623a4a0..6b22b90 100644 --- a/components/ProfileHeader.js +++ b/components/ProfileHeader.js @@ -1,21 +1,39 @@ import React, { useState, useEffect } from 'react'; -import { View, Share } from 'react-native'; +import { View, Share, TouchableOpacity } from 'react-native'; import { Avatar, Button, Card, Title, Paragraph } from 'react-native-paper'; import UserName from './UserName'; import FollowButton from './basics/FollowButton'; +import { useNavigation } from '@react-navigation/native'; +import { useSnapshot } from 'valtio'; +import GlobalState from '../contexts/GlobalState.js'; const DefaultPhoto = "https://social.emmint.com/uploads/e6f9be6d665dc43417701bf16a90122c.png"; const ProfileHeader = ({ profileObj }) => { + const navigation = useNavigation(); + const viewer = useSnapshot(GlobalState).me || {}; const safeProfileObj = profileObj || {}; const safeProfile = safeProfileObj.profile || {}; let photoUrl = safeProfile.photo ? 'https://social.emmint.com/' + safeProfile.photo + '?width=1000&height=1000' : DefaultPhoto; + const canEditProfileImage = !!( + safeProfileObj?._id && + !safeProfileObj?.isGroup && + String(safeProfileObj._id) === String(viewer?._id || '') + ); + + const handlePressPhoto = () => { + if (!canEditProfileImage) return; + navigation.navigate("ProfileSettings"); + }; + return ( <> - + + + <UserName profileid={safeProfileObj._id} />