Changing application direction on the fly without restarting the whole application - android

I'm developing a react native application in two languages, English and Persian(Farsi).
I'm using I18nManager for setting the application layout direction, but I manage translations by myself and I don't use I18nManager for translation. so please note that my application translation is not related to the system locale. and the application locale is completely independent from the system locale.
I pass application language as a prop to all children components in the hierarchy and manage their changes in App.js component (as the root component of system). (in App.js there is a state called applicationLanguage)
I have a function below that I am calling after setState for changing the applicationLanguage:
setApplicationDirection = (language: Language) => {
I18nManager.allowRTL(language === Language.Farsi);
I18nManager.forceRTL(language === Language.Farsi);
};
usage of setApplicationDirection:
onChangeLanguage = (language: Language) => {
this.setState({
applicationLanguage: language
});
this.setApplicationDirection(language);
};
after onChangeLanguage my translations has been changed without application restart. but application direction does not changed.
I know I can use react-native-restart and manually restart the application to take effect, but I would really prefer if changes would occur without restarting the application to provide a better UX. In my application the user can change the language in every screen and if I restart the application, he has to route to that screen again.

Related

Using detox to look at UI in different orientations (Android)

So I am using detox to take screenshots of my app. I'm using a connected Android device. The device.takeScreenshot function works. Now what is the best way to see what my app looks like on different orientations? Is the only way to just change the tablet orientation and run the test again? Or is there a smarter way to do it?
I'm not entirely sure what you're asking here, but in order to change orientation you can use device.setOrientation().
Is the only way to just change the tablet orientation and run the test again?
To me, this sounds like two separate use cases (portrait vs. vertical). Would be easier to maintain.
Lastly, as far as screenshot testing is concerned, you might find the practices described in Detox's screenshots guide useful:
...
the concept is mainly useful for verifying the proper visual structure and layout of elements appearing on the device's screen, in the form of a snapshot-test. Namely, by following these conceptual steps:
Taking a screenshot, once, and manually verifying it, visually.
Storing it as an e2e-test asset (i.e. the snapshot).
Using it as the point-of-reference for comparison against screenshots taken in consequent tests, from that point on.
const fs = require('fs');
describe('Members area', () => {
const snapshottedImagePath = './e2e/assets/snapshotted-image.png';
it('should greet the member with an announcement', async () => {
const imagePath = (take screenshot from the device); // Discussed >below
expectBitmapsToBeEqual(imagePath, snapshottedImagePath);
});
});
function expectBitmapsToBeEqual(imagePath, expectedImagePath) {
const bitmapBuffer = fs.readFileSync(imagePath);
const expectedBitmapBuffer = fs.readFileSync(expectedImagePath);
if (!bitmapBuffer.equals(expectedBitmapBuffer)) {
throw new Error(`Expected image at ${imagePath} to be equal to image >at ${expectedImagePath}, but it was different!`);
}
}
Important: The recommended, more practical way of doing this, is by utilizing more advanced 3rd-party image snapshotting & comparison tools such as applitools.

R shiny mobile app: prevent PullToRefresh

Context: I am developing a mobile Shiny app using the shinyMobile package, which is a wrapper for the famous framework7 HTML template.
In my app, the user has to make a selection of attributes on a first tab using multiple dropdown lists, and then, on the other tabs, some output is produced. Each tab requires the user to scroll up and down to access all the content and in this process, very often the 'pull to refresh' feature is triggered.
This is really annoying, because the entire attribute selection and output are lost, and the user has to start over from scratch.
What I tried: based on this SO thread which pointed me to this Google developer page, I tried setting the CSS overscroll-behavior property to contain with: body {overscroll-behavior-y: contain;}. PROBLEM: It does not work for me! (tested on Chrome Android)
Minimal reproducible example:
default app, deployed here
library(shiny);library(shinyMobile)
shiny::shinyApp(
ui = f7Page(
f7Card(
h5('try to pull to refresh. normally it should work.')
)
),
server = function(input, output) {}
)
Supposedly fixed app, deployed here
library(shiny);library(shinyMobile)
shiny::shinyApp(
ui = f7Page(
tags$style(type='text/css', '.body{overscroll-behavior-y: contain;}'),
f7Card(
h5('try to pull to refresh. Normally it should not work.')
)
),
server = function(input, output) {}
)
Hope you guys can reproduce my issue and identify what is amiss!!!
You might want to change your css part to: html,body{overscroll-behavior-y: contain;}, see https://stackoverflow.com/a/42509310/3502164.
Then it works for me on my mobile (android chrome).
Reproducible example:
library(shiny)
library(shinyMobile)
app <- shiny::shinyApp(
ui = f7Page(
tags$style(type='text/css', 'html,body{overscroll-behavior-y: contain;}'),
f7Card(
h5('try to pull to refresh. Normally it should not work.')
)
),
server = function(input, output) {}
)
# use host config to access app from mobiles in the same network
shiny::runApp(appDir = app, host = '0.0.0.0')

Changing the point at which the one touching the screen by a superior point, using react

I'm newbie using react and I'm trying now to get when a phone user touch screen, my web app interpretes that like the user has touched in another screen point. For example, a bit above.
I'm trying this:
onTouchStart = {(event) => {
event.touches [0] .pageY = event.touches [0] .pageY + 250;
}
});
But I'm getting this:
** Uncaught TypeError: Can not assign to read only property 'pageY' of object '# ' **
How can I fix it? Can I get same results with another way? If you can give me a hand I really will to thank you.
Thank you in advance.
Are you talking about browser and ReactJS(not React Native)? If yes, interception of user actions are prohibited inheretely by browsers, to prevent security breaches and user abuse. You can only read properties of user-originated events(and use them further in your app), but not alter them.

Set Locale from App - Back Button Issue

I am working on Language setting on my app. I was able to change the locale from my Main Activity through the use of
Resources resources = getResources();
Configuration configuration = resources.getConfiguration();
DisplayMetrics displayMetrics = resources.getDisplayMetrics();
configuration.setLocale(new Locale("ar"));
resources.updateConfiguration(configuration,displayMetrics);
recreate();
Everything worked fine but I noticed that the back button did not change its direction to RTL:
This is my expected behaviour when I set the language to a RTL language:
Is this possible?
Changing the navigation bar's direction means that the app will change the Locale of the device. Such a thing is similar to setting the device language in the language setting of the device since a Locale defines the language and direction (rtl or ltr) of the views to support the language. Since you're only changing the Locale of your Context in the app, it will not affect the Context of the other apps on the device and the system apps/components (launcher, navigation bar, status bar, etc...). Hence the navigation bar will not change and stay unaffected by the change in your app.
Furthermore, to alter the device Locale or any other configuration (font, font size, display metrics, rotation, etc..), the app would need the SET_CONFIGURATION permission to do so. Although it is not stated in the docs, the SET_CONFIGURATION permission can only be given automatically to system apps like the language and display settings. I haven't seen if it can be requested from the user by a third party app but I believe that it cannot be as most of the times in the development of my apps, the permission was being granted using adb shell pm grant command in the command line. Usually I would do that during my tests since my apps also support other languages and would want to make sure that the app performs well in such cases, hence I'd grant it the permission in the command line and let it to change the locale of the device from within the tests.
Try to call this method when you set arabic language:
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private void forceRTLIfSupported()
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
//HERE CHECK CONDITION FOR YOUR LANGUAGE if it is AR then
//change if it is english then don't
getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL);
}
}
The direction of the navigation bar (and other parts of the OS, like the Settings), is not related to an app. A user can have a LTR OS with a RTL app. thus changing your app's locale and direction does not affect the underlying OS and the user has to change it manually.

What is the expected startup experience for a Progressive Web Application?

Testing a Progressive Web Application.
When I start the app in airplane mode, I get an unexpected startup/splash experience (Android/Chrome).
Launch from Home Screen Experience
I see a white screen, followed by a brief flash of the "offline dinosaur" before the app successfully starts and all is well. The startup time is longer than I expected, especially after testing with Chrome Devtools on a laptop, where startup is near instant.
Since it is a little tricky to debug where this time is being spent (especially in the “service-worker-not-running” case), it would be helpful to have some baseline knowledge:
Launch from Browser Experience
Just a brief flash of the "offline dinosaur" before the app successfully starts. Starts much faster.
Questions
What is the expected startup time and experience on Android/Chrome?
Is the experience described above just the current state of things (11/2015)?
Is there any way to specify the startup (splash) experience for Chrome? (I'm aware of background color and 144x144 icon in app manifest for splash, but for Opera only)
First time PWA for me, so any information on this would be helpful.
My platform:
Samsung GS 5,
Android 5.0,
Chrome 46.0.2490.76
The reason for the existence of the splash screen is because on mobile it can take over a second to start the render process so we paint something (the background colour and icons) util you have a first paint generated by your app.
If you are seeing a white screen on startup it might be because you added to the homescreen prior to Chrome landing (46) the splash screen feature. Some things to lookout for:
Ensure your manifest has a short_name and name
Ensure your start_url is in the same scope as a SW that is registered on the page
Have good icons in the manifest ideally > 192px
Set background_color in the manifest to the color of your background on the page (ideally.) This will ensure that the splash screen is the expected colour of your site.
You shouldn't see the offline dinosaur at all, even when you are in aeroplane mode. Airhorner should represent the ideal experience: Blue splash screen with an icon that morphs into the display of the app.
re: Icons - I recommend actually 192px icon or higher.
Regarding the offline-dino flash:
I was using sw-toolbox and performing asynchronous work to setup route handlers at worker startup. This caused an offline dino flash when the application was offline and starting up.
To avoid that, set a sw-toolbox default handler that waits for the asynchronous route handler setup to complete.
var toolbox = require('sw-toolbox');
var setupPromise = someAsyncHandlerSetup()
.then(function () {
// make default handler temporary, allows other fetch handlers (like sw-precache, for example)
toolbox.router.default = null;
});
// until the async handler setup is done, provide a default handler
// to avoid an offline-dino flash when starting up while offline.
toolbox.router.default = function defaultHandler (request) {
return setupPromise.then(function () {
var handler = toolbox.router.match(request);
if (handler) {
return handler(request);
}
throw new Error('default handler could not handle ' + request.url);
});
};

Categories

Resources