Is there a way to implement some sort of auto translation in an react native app? - react-native

I know this isn't google, but I wasn't able to find anything usefull and maybe you can give me some advice.
What I am looking for is some way to add an auto translation to strings in my react native application.
Right now I am using a workaround in which I translate some of the most common words manually - since that doesn't cover the whole language the outcome looks pretty unsatisfying :)

You could use react-native-i18n.
var I18n = require('react-native-i18n');
var Demo = React.createClass({
render: function() {
return (
<Text>{I18n.t('greeting')}</Text>
)
}
});
// Enable fallbacks if you want `en-US` and `en-GB` to fallback to `en`
I18n.fallbacks = true;
I18n.translations = {
en: {
greeting: 'Hi!'
},
fr: {
greeting: 'Bonjour!'
}
}

take user phone OS language using device info
https://www.npmjs.com/package/react-native-device-info#getdevicelocale
or using
I18n = require('react-native-i18n')
locale = I18n.currentLocale()
then Use power translator
https://www.npmjs.com/package/react-native-power-translator
//set your device language as a Target_Language on app start
TranslatorConfiguration.setConfig('Provider_Type', 'Your_API_Key','Target_Language', 'Source_Language');
//Fill with your own details
TranslatorConfiguration.setConfig(ProviderTypes.Google, 'xxxx','fr');
Use it as a component
<PowerTranslator text={'Engineering physics or engineering science refers to the study of the combined disciplines of physics'} />
add-on :
Use redux store or async storage to store all your string on first app start.
Then use translated text from store or storage.
IT will save your api bill as you have fixed strings.

sir for auto-translate. you can create one component where you can pass all strings (text) in your app, And use '#aws-sdk/client-translate' for translation, it's very fast and also works on dynamic data \
https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-translate/index.html
https://www.npmjs.com/package/#aws-sdk/client-translate

Related

Semantic Tokens in MarkupString / MarkupContent

Is it possible to use MarkdownString/MarkupContent with code or pre with span to emulate semantic tokens in Hover? If so, is it possible to access the colors from the user's theme using only the CSS on the span elements? Ideally I would like to avoid using anything VSCode specific.
I saw https://github.com/microsoft/vscode/issues/97409 but there was no solution.
If you want to manually set colors for code you can try this:
// using your fileSelector
let disposable = vscode.languages.registerHoverProvider('plaintext', {
provideHover(document, position) {
const codeBlock = `<code><span style="color:#f00;background-color:#fff;">const</span> a = 12</code>`;
const markdown = new vscode.MarkdownString();
// markdown.appendCodeblock(codeBlock, "javascript");
markdown.appendMarkdown(codeBlock);
markdown.supportHtml = true;
markdown.isTrusted = true;
return new vscode.Hover(markdown, new vscode.Range(position, position));
}
});
<pre> also works, instead of <code>, but I think <code> looks better.

Use i18n with data fetched from Wordpress RestAPI

I'm stuck since a while on this problem now and I'm struggling to find answers or peoples that have experienced the same problem.
Also, I'm not a native English speaker and I'm new to programming, so sorry if it's not clear / if my approch is dumb as f
I decided to turn the Wordpress of my company to headless (on Nuxt). Everything was pretty fine until I tried to internationalized the app. The best solution (I think) to manage this task is to use nuxt-i18n, a tool to properly translate the app (strings, paths etc). But this solution seems to not be very compatible with data fetched from the Rest API.
For now I'm trying to passing the data from single page like that :
<script>
import SwitchL from '~/components/LanguageInput.vue'
export default {
components: {
SwitchL,
},
data() {
return {
fetchRestFr: null,
fetchRestEn: null,
i18nData: null,
}
},
i18n: {
messages: {
// help
}
},
methods: {
fetchSomeData() {
// Get page data in French
let fetchRestFr = this.$axios.$get(`https://www.company-site.com/wp-json/wp/v2/pages?include=42&lang=fr`);
// Get page data in English
let fetchRestEn = this.$axios.$get(`https://www.company-site.com/wp-json/wp/v2/pages?include=42&lang=en`);
// Assign data to null variables
this.fetchRestFr = fetchRestFr[0]
this.fetchRestEn = fetchRestEn[0]
// Build the i18n object
this.dataToI18n();
},
dataToI18n() {
if (this.fetchRestFr && this.fetchRestEn) {
let fr = this.fetchRestFr
let en = this.fetchRestEn
let data = {
messages: {
fr,
en
}
}
this.i18nData = data
}
},
},
created() {
this.fetchSomeData();
},
}
</script>
An other approch was to use the tag outside the template section like so :
<i18n>
// Inject the data generated from a function
{
"en": {
"data": "here"
},
"fr": {
"data": "ici"
}
}
</i18n>
But I don't find any solution to dynamically inject JSON here.
Last solution is to make things to preper way, by creating JSON file for i18n to referencing, but I think It will be pretty hard for me to do this, and to manage this on long term.
If you have advice, thoughts on this I will be very grateful !
You do usually use some JSON files directly. They will be stored into /locales/fr.json with something like this
{
"here": "ici"
}
Then, you'll access it into your template with
<template>
<p>{{ $t('here') }}</p>
</template>
And it will handle the fr/en switch by the several ways available (manual switch, checking browser's locale, URL's path, cookie etc).
You can check nuxt-i18n's documentation for this and get a proper simple setup quickly here: https://i18n.nuxtjs.org/
Usually, you won't need to use the i18n tag anymore but if you still need to, you can do as explained here: https://i18n.nuxtjs.org/per-component-translations

Understanding React-Admin translation

I am working with react-admin and trying to traduce it to my native language with this short guide usage:
https://github.com/marmelab/react-admin/tree/master/packages/ra-language-french
I keep getting non-referenced keys on the supposed translated keys.
To get my traduction working, I tried to delete node-modules file, tested in other browsers, cleared cache etc. but I still had the non-referenced keys: ra.______
When I changed this line (as below), it solved my problem:
const messages = { 'fr': frenchMessages, };
TO
const messages = { 'en': frenchMessages, };
And that's the only thing that i needed to change for the polyglot to work (French traduction).
Can someone explain to me what's going on, i don't know why it works in that case ?
Example in picture which shows the case explained above:
Not working case
Working case
Thanks for your time.
The <Admin locale='fr' ... property is deprecated! New version:
import { resolveBrowserLocale } from 'react-admin'
...
const i18nProvider = polyglotI18nProvider(locale => messages[locale], resolveBrowserLocale()) // or 'fr'

React Native + Redux: Where to put functions for 3rd party libraries?

I'm creating an ecommerce app that uses a geolocation library (https://github.com/transistorsoft/react-native-background-geolocation).
I have an orderState:
const ordersInitState = {
lineItems: [],
status: ORDER_STATUSES.AWAITING_CHECKOUT,
};
const ordersReducer = (prevState=ordersInitState, action) => {
switch(action.type) {
...
case actions.ORDERS.REMOVE_ITEM:
const lineItems = [...prevState.lineItems];
const indexToRemove = action.payload;
lineItems.splice(indexToRemove, 1);
const status = lineItems.length > 0 ? prevState.status : ORDER_STATUSES.AWAITING_CHECKOUT;
return {
...prevState,
status,
lineItems,
};
default:
return prevState;
}
}
export default ordersReducer;
As you can see, the client is allowed to remove items from their cart. If they end up removing everything, their order status will reset. If they do end up emptying their cart (lineItems.length === 0) I want to also run a simple line from the geolocation library:
BackgroundGeolocation.removeGeofence("blah");
Where would I put this? It feels wrong to do it in the reducer because it has nothing to do with state. It also isn't specific to one particular component, so putting it in one of my components doesn't make sense.
I'm still a bit new to redux so I'm not sure where to put non-state related methods.
The often used name for what you are looking for is called "side effects" middleware. In the abstract, you want to cause an effect in an external system (in this case, the geolocation library), when the application state changes.
There are many libraries for this use case. Some of the more popular ones are redux-saga and redux-loop. They are both good tools and help give structure to managing complicated side effects, but both come with a significant conceptual overhead, and should only be used when really needed.
If you want a quick and simple solution, you can create a plain JavaScript module that subscribes to your store changes and executes the side effects for you:
import store from '../your/redux/store;
let previousCount = 0;
store.subscribe(() => {
const count = store.getState().orders.lineItems.length;
if (count === 0 && previousCount > 0) {
// someone just emptied the cart, so execute side-effect
BackgroundGeolocation.removeGeofence("blah");
}
previousCount = count;
});
And then if you find yourself needing this type of solution repeatedly, you can reach for one of the libraries mentioned above.

Organizing JS code with Alloy and CommonJS in Titanium projects

I'm learning with Titanium to make iPhone/Android apps. I'm using Alloy MVC framework. I never used javascript before, apart from simple scripts in HTML to access the DOM or something like that, so I never needed to structure the code before.
Now, with Titanium, I must use a lot of JS code and I was looking for ways to structure my code. Basically I found 3 ways to do it: prototype, namespace and functions inside functions.
Simple example for each:
Prototype:
NavigationController = function() {
this.windowStack = [];
};
NavigationController.prototype.open = function(windowToOpen) {
//add the window to the stack of windows managed by the controller
this.windowStack.push(windowToOpen);
//grab a copy of the current nav controller for use in the callback
var that = this;
windowToOpen.addEventListener('close', function() {
if (that.windowStack.length > 1)
{
that.windowStack.pop();
}
});
if(Ti.Platform.osname === 'android') {
windowToOpen.open();
} else {
this.navGroup.open(windowToOpen);
}
};
NavigationController.prototype.back = function(w) {
//store a copy of all the current windows on the stack
if(Ti.Platform.osname === 'android') {
w.close();
} else {
this.navGroup.close(w);
}
};
module.exports = NavigationController;
Using it as:
var NavigationController = require('navigator');
var navController = new NavigationController();
Namespace (or I think is something like that, coz the use of me = {}):
exports.createNavigatorGroup = function() {
var me = {};
if (OS_IOS) {
var navGroup = Titanium.UI.iPhone.createNavigationGroup();
var winNav = Titanium.UI.createWindow();
winNav.add(navGroup);
me.open = function(win) {
if (!navGroup.window) {
// First time call, add the window to the navigator and open the navigator window
navGroup.window = win;
winNav.open();
} else {
// All other calls, open the window through the navigator
navGroup.open(win);
}
};
me.setRightButton = function(win, button) {
win.setRightNavButton(button);
};
me.close = function(win) {
if (navGroup.window) {
// Close the window on this nav
navGroup.close(win);
}
};
};
return me;
};
Using it as:
var ui = require('navigation');
var nav = ui.createNavigatorGroup();
Functions inside functions:
function foobar(){
this.foo = function(){
console.log('Hello foo');
}
this.bar = function(){
console.log('Hello bar');
}
}
// expose foobar to other modules
exports.foobar = foobar;
Using it as:
var foobar = require('foobar').foobar
var test = new foobar();
test.bar(); // 'Hello bar'
And now my question is: which is the better to maintain code clean and clear? It seems that prototype is clear an easy to read/mantain. Namespace confuses me a bit but only needs to execute the initial function to be "available" (no use of new while declaring it, I suppose because it returns the object?namespace? "me"). Finally, functions inside functions is similar to the last, so I don't know exactly the difference, but is useful to export only the main function and have all the inside functions available for use it later.
Maybe the last two possibilities are the same, and I'm messing concepts.
Remember that I'm searching for a good way to structure the code and have functions available to other modules and also inside the own module.
I appreciate any clarification.
In the examples that they release, Appcelerator appears to follow the non-prototype approach. You can see it in the examples they have released: https://github.com/appcelerator/Field-Service-App.
I've seen a lot of different approaches to structuring applications in Titanium before Alloy. Since Alloy, I've found following the development team's examples helpful to me.
With that being said, it seems to me that all of this is still under interpretation and open to change and community development. Before Alloy there were some great community suggestions on structuring an app and I believe that it is still open with Alloy. Often when I find someone's example code I see something they did with it that appears to organize it a bit better than I thought of. It seems to make it a bit easier.
I think you should structure your application in a way that makes sense to you. You may stumble on to a better and easier way of developing applications with Alloy, because you are looking at it critically.
I haven't found a lot of extensive Alloy examples, but Field-Service-App makes sense to me. They have a nice separation of the elements in the application beyond MVC. Check it out.