diff --git a/API.js b/API.js
index 262bf4d..0a63c59 100644
--- a/API.js
+++ b/API.js
@@ -1,6 +1,6 @@
import i18n from "./i18nMessages.js";
-//const baseUrl = "https://emiapi.reynafamily.com";
-const baseUrl = "http://localhost:3000";
+const baseUrl = "https://emiapi.reynafamily.com";
+//const baseUrl = "http://localhost:3000";
const requestErrorCooldownMs = 30000;
const profileFailureCooldownMs = 60000;
const recentRequestErrors = {};
@@ -270,6 +270,9 @@ const API = {
updatePost(post){
return postCall("/post/" + post._id, {content: post.content});
},
+ translatePost(postid, targetLang) {
+ return postCall("/post/translate", { postid, targetLang });
+ },
newPost(content, toProfile, isNews) {
//Content is expected to be a string.
let params = { content };
diff --git a/components/Post.js b/components/Post.js
index 59bae02..6a379a4 100644
--- a/components/Post.js
+++ b/components/Post.js
@@ -26,6 +26,7 @@ let Post = (props) => {
const [deleted, setDeleted] = useState(false);
let [likes, changeLikes] = useState(Object.keys(post.reactions).length);
let [bookmarked, changeBookmarked] = useState(post.bookmarks && post.bookmarks.includes(viewer._id));
+ const [translating, setTranslating] = useState(false);
const isOwner = String(post.profileid || '') === String(viewer?._id || '');
const swipeX = useRef(new Animated.Value(0)).current;
const mediaGestureActiveRef = useRef(false);
@@ -34,6 +35,30 @@ let Post = (props) => {
: undefined;
let cleanContent = stripInlineTags(stripBibleTokens(post.content));
const navigation = useNavigation();
+
+ const textWithoutUrls = cleanContent.replace(/(https?:\/\/[^\s]+)/g, '').trim();
+ const hasTextContent = textWithoutUrls && textWithoutUrls.length > 0 && cleanContent.length < 1000;
+ const currentLang = i18n.locale.substring(0, 2).toLowerCase();
+ const hasTranslation = post.translations && post.translations[currentLang];
+ const [showTranslation, setShowTranslation] = useState(!!hasTranslation);
+
+ const requestTranslation = async () => {
+ setTranslating(true);
+ try {
+ await API.translatePost(post._id, i18n.locale);
+ setTimeout(async () => {
+ const updatedPost = await API.getPost(post._id);
+ if (updatedPost && updatedPost.translations && updatedPost.translations[i18n.locale.substring(0, 2).toLowerCase()]) {
+ changePost(updatedPost);
+ setShowTranslation(true);
+ }
+ setTranslating(false);
+ }, 3000);
+ } catch (e) {
+ setTranslating(false);
+ }
+ };
+
//cleanContent = convertLinks(cleanContent);
const newComentAdded = (commentData) => {
let newPostObj = { ...post };
@@ -168,9 +193,37 @@ let Post = (props) => {
{ pattern: /(https?:\/\/[^\s]+)/, style: styles.link, onPress: handleLinkPress, onLongPress: handleLinkLongPress },
]}
>
- {cleanContent}
+ {showTranslation && hasTranslation ? stripInlineTags(stripBibleTokens(post.translations[currentLang])) : cleanContent}
+ {hasTextContent && (
+
+ {hasTranslation && showTranslation ? (
+
+
+ {i18n.t("message.aiTranslated") || "AI Translated"}
+
+ setShowTranslation(false)}>
+
+ {i18n.t("message.seeOriginal") || "See Original"}
+
+
+
+ ) : (
+ {
+ if (hasTranslation) {
+ setShowTranslation(true);
+ } else {
+ requestTranslation();
+ }
+ }}>
+
+ {translating ? (i18n.t("message.translating") || "Translating...") : (i18n.t("message.seeTranslation") || "See Translation")}
+
+
+ )}
+
+ )}
diff --git a/i18nMessages.js b/i18nMessages.js
index 0cd9126..74a3d36 100644
--- a/i18nMessages.js
+++ b/i18nMessages.js
@@ -148,6 +148,9 @@ const messages = {
updateProfile: "Update Profile",
previous: "Previous",
next: "Next",
+ translating: "Translating...",
+ seeTranslation: "See Translation",
+ seeOriginal: "See Original",
},
},
es: {
@@ -291,6 +294,9 @@ const messages = {
updateProfile: "Actualizar perfil",
previous: "Anterior",
next: "Siguiente",
+ translating: "Traduciendo...",
+ seeTranslation: "Ver traducción",
+ seeOriginal: "Ver original",
}
},
fr: {
@@ -434,6 +440,9 @@ const messages = {
updateProfile: "Mettre à jour le profil",
previous: "Précédent",
next: "Suivant",
+ translating: "Traduction en cours...",
+ seeTranslation: "Voir la traduction",
+ seeOriginal: "Voir l'original",
}
},
da: {
@@ -577,6 +586,9 @@ const messages = {
updateProfile: "Opdater profil",
previous: "Forrige",
next: "Næste",
+ translating: "Oversætter...",
+ seeTranslation: "Se oversættelse",
+ seeOriginal: "Se original",
}
}
}
diff --git a/utils/bibleReferences.js b/utils/bibleReferences.js
index 8984a23..5894e93 100644
--- a/utils/bibleReferences.js
+++ b/utils/bibleReferences.js
@@ -155,7 +155,7 @@ export const fetchBibleChapter = async (chapterReference = "", locale = "", cust
queryParamsString += p + "=" + queryParams[p] + "&";
});
- const localBaseUrl = global.baseUrl ?? "http://localhost:3000";
+ const localBaseUrl = global.baseUrl ?? "https://emiapi.reynafamily.com";
// To bypass getCall's strict JSON structure mapping (since our backend just passes the API response directly),
// we can use standard fetch with the same cookie inclusion strategy.
const fetchRes = await fetch(localBaseUrl + url + queryParamsString, {