How do I reload the original webview - webview

If I send a push to a specific link in my webview app how do I create an action for people to hit "home" to reload my homepage so it sends them back to the page they would go to if they just opened the app.

Say you have a button, then do something like:
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
webview.loadUrl(PUT_HOME_PAGE_URL_HERE);
}
});
Or you can use WebView in a fragment, and change the fragments.

Related

Vaadin 14.2: Intercept logout (invalidate session) with BeforeLeaveListener

in my Vaadin 14.2.0 application there is a BeforeLeaveListener to show a confirmation dialog when the input is dirty (= there are unsaved changes in the input fields) to cancel (or intentionally proceed) the navigation:
BeforeLeaveListener listener = new BeforeLeaveListener() {
#Override
public void beforeLeave(BeforeLeaveEvent event) {
if (dirtyFlag.isDirty()) {
ContinueNavigationAction postponeAction = event.postpone();
// show confirmation dialog and maybe execute a proceed
[...] () -> postponeAction.proceed();
}
}
};
UI.getCurrent().addBeforeLeaveListener(listener);
This works fine for everything but for the logout.
This is how my logout button looked like in the start (what works as long as I do not want to postpone/cancel the logout):
Anchor link = new Anchor();
link.getElement().addEventListener("click", e -> {
VaadinSession.getCurrent().getSession().invalidate();
UI.getCurrent().navigate(LoginView.class);
});
Now I want to postpone the logout until the user confirms that the unsaved changes should get discarded. (Switching both lines in the EventListener seems to be a good idea, but did not work because of the following.)
Within the navigate-call the BeforeLeaveListener is called (good), but the logout is done nevertheless, because the code after the navigate()-call is executed (of course, because it is no blocking call), the session is invalidated and the user is logged out though the confirmation dialog just popped out (but the user had no chance to confirm/deny).
I tried to move the session invalidation into the LoginView (into a BeforeEnterObserver), but the result is that the login view is reloaded in an endless loop.
Question: is there something like "navigate to LoginView and if navigation is not postponed and not cancelled, then invalidate session"?
A workaround is to navigate to an intercepting LogoutView that just invalidates the session and redirects/forwards to the LoginView:
#Route(value = "logout")
public class LogoutView implements BeforeEnterObserver {
#Override
public void beforeEnter(BeforeEnterEvent event) {
VaadinSession.getCurrent().getSession().invalidate();
event.forwardTo(LoginView.class);
}
}
But this seems to me to be just a bad workaround with some overhead (creating a view just to forward to another view)...
I know, you didnt mention Spring. But that's actually what I believe Spring Security is doing under the hood.
My Logout Button (using Spring Security) is looking like this:
new Button("Logout", click -> {
UI.getCurrent().getPage().executeJs("location.assign('logout')");
});
Once you click it, you are logged out and redirected to the login view (more details from Baeldung). I think it will be just fine if you do your LogoutView redirection detour.
The fact that you can even use the Navigator to go to your LogoutView is even better here, since this is caught by BeforeLeaveObserver (in contrast to completely new requests by assigning a new location or refreshing the page. See BeforeLeaveObserver vs. beforeunload for more details on that)
I would still like to propose another idea for your usecase. I think it will be much simpler, but requires that the logout link knows of the dirtyFlag:
Anchor link = new Anchor();
link.getElement().addEventListener("click", e -> {
if(dirtyFlag.isDirty()){
// show Dialog with
// - a confirm btn that calls doLogout() on click
// - a cancel btn that closes the Dialog
} else {
doLogout();
}
});
...
private void doLogout(){
VaadinSession.getCurrent().getSession().invalidate();
UI.getCurrent().navigate(LoginView.class);
}

Xamarin.Auth Google Presenter not closing in Android Xamarin.Forms App

I am using Xamarin.Form to write a Android app. I have successfully implemented the OAuth and I can sign in and get the user information using OAuth2Authenticator.
When the user clicks signup/Login I show the OAuthLoginPresenter as follows:
var oAuthLoginPresenter = new Xamarin.Auth.Presenters.OAuthLoginPresenter();
oAuthLoginPresenter.Login(App.OAuth2Authenticator);
This works great and the user sees the login page.
When the user clicks Allow the completed Event on the OAuth2Authenticator instance fires as expected and the user is once again back looking at the app.
However this is where my problem is - I get a notification:
If CustomTabs Login Screen does not close automatically close
CustomTabs by Navigating back to the app.
Thing is though I am back at the app. If I look at all my open apps I can see the login screen is still running in the back ground so that presenter has not closed.
In my intercept Activity which gets the redirect looks like this:
[Activity(Label = "GoogleAuthInterceptor")]
[IntentFilter
(
actions: new[] { Intent.ActionView },
Categories = new[]
{
Intent.CategoryDefault,
Intent.CategoryBrowsable
},
DataSchemes = new[]
{
// First part of the redirect url (Package name)
"com.myapp.platform"
},
DataPaths = new[]
{
// Second part of the redirect url (Path)
"/oauth2redirect"
}
)]
public class GoogleAuthInterceptor: Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
Android.Net.Uri uri_android = Intent.Data;
// Convert Android Url to C#/netxf/BCL System.Uri
Uri uri_netfx = new Uri(uri_android.ToString());
// Send the URI to the Authenticator for continuation
App.OAuth2Authenticator?.OnPageLoading(uri_netfx);
Finish();
}
}
Am I missing a step in here to close that presenter? Any other ideas please?
UPDATE:
I have now found that using Chrome as the default browser works fine and presenter is closed. But if I use a Samsung browser as my default browser - it does not close.
So I need a way to close it manually.
Just set property to null when initializing Xamarin.Auth in your main activity:
//don't show warning message when closing account selection page
CustomTabsConfiguration.CustomTabsClosingMessage = null;

Vaadin 7 and browser url update

My Vaadin 7 application doesn't react on browser url changing. For example I entering from keyboard a new url parameters and pressing Enter key and after that nothing is changing.
Application only reacts on F5 or page refresh button.
How to also make Vaadin 7 application to respond to Enter key after url update ?
UPDATED
I'm using Vaadin com.vaadin.navigator.Navigator object.
For example I have an url: http://example.com/#!products/30970
When I change the url in browser address bar (for example to http://example.com/#!products/34894) and press enter key I would like to change information at my page in order to show info about product with id 34894 instead of product with a previous id 30970.
Vaadin Navigator and UriFragmentChangedListener
Right now I'm using Vaadin Navigator in order to define views:
Navigator navigator = new Navigator(this, viewDisplay);
navigator.addView("products", ProductView.class);
First time in web browser I'm successfully able to access this view with product id parameter for example by the following url:
http://example.com/#!products/30970
ProductView is constructed first time and in its public void enter(ViewChangeListener.ViewChangeEvent event) method I'm able to get uri parameters.
But after that when I change product id in web browser address bar in this url to another one(for example to 30971 in order to display information for another product):
http://example.com/#!products/30971
and press Enter key the view is not refreshed and doesn't react on these changes..
As suggested in the comments I have added UriFragmentChangedListener listener and now at least able to handle URL fragment changes(after Enter key presing).
Now, my logic have to react on these changes and I'm looking for a correct way how it should be implemented in Vaadin 7.
So, If I understood correctly - in additional to Navigator logic I also have to use this listener and inside of this listener logic I have to get a reference on appropriate view(navigator.getCurrentView() ?) object and invoke some method on this object in order to change internal view state without full view rebuild ? If I'm correct - is there some standard mechanism in Vaadin in order to simplify this job ?
i can not think of another way than pass the UriFragmentChangeEvent manually to your View. I guess the Vaadin API can not do it automatic.
public class MyUI extends UI{
#Override
protected void init(final VaadinRequest request) {
/*
* UriFragmentChangedListener
* when URL+Parameter manuell eingegeben werden
*/
getPage().addUriFragmentChangedListener(new UriFragmentChangedListener() {
#Override
public void uriFragmentChanged(UriFragmentChangedEvent event) {
View currentView = getNavigator().getCurrentView();
if(currentView != null){
if(currentView instanceof UriFragmentChangedListener){
((UriFragmentChangedListener)currentView).uriFragmentChanged(event); //custom method
}
}
}
});
}
}
To make this work add UriFragmentChangedListener to your ProductView:
public class ProductView extends CustomComponent implements View, UriFragmentChangedListener {
}
take a look at the Parameters in the ViewChangeEvent of your ProductView
By using this url structure "http://example.com/#!products/30970", you can read the product id as following:
#Override
public void enter(ViewChangeEvent event) {
String productId = event.getParameters();
}

redirect and download pdf on click of radio button

Need a suggestion from people more intelligent than me. I have a modal which has 2 things, essentially, 3 radio buttons (Email, PDF, None)and a Yes and NO submit button.
On press of radio button I flag hidden variables appropriately to know if the user pressed email or pdf in my controller. Than user presses Yes for saving (happy path), and it will call a controller.
This controller will save the changes and redirect to a different page. Now I wanna add to this controller and make it download a pdf. I am doing this by calling my DownloadPDF action.
public ActionResult Main(string id)
//code for doing all the save and other stuff
{
if (viewModel.Email)
{
SendTestingEmail(viewModel.ConsumerEncryptedID);
}
else if(viewModel.PDF)
{
DownloadWelcomePDF()
}
return RedirectToAction("ConsumerIndex", "Consumer")
}
public ActionResult DownloadWelcomePDF(string id)
{
var htmlWelcomeEmail = db.getHtmlBody(id.DecryptID());
var converter = new ConvertToPDF();
var file = converter.ConvertHTMLStringToPDF(htmlWelcomeEmail.EmailBody);
var fileStreamResult = new FileStreamResult(file, "application/pdf") { FileDownloadName = string.Format("Welcome{0}{1}_{2}.pdf", htmlWelcomeEmail.ConsumerFirstName, htmlWelcomeEmail.ConsumerLastName, DateTime.Now.ToString("yyyyMMdd")) };
return fileStreamResult;
}
Now since this will also return pdf content I cannot do both these 2 things (redirecting to a different page and downloading ) at the same time.
Is there any suggestion, I have been searching internet for a long time.
It is essentially download and redirect but download needs to happen only on certain condition (press of radio) and the page should always redirect nonetheless.
You can break this into two steps.
First on submit you do a check in javascript to see if the user wants to download the PDF. If he wants, then call the download action and then call the main method from JS.
Or you can render the customerIndex page first and pass a flag (something like downloadPDFForId). Based on this flag in the JS in CustomerIndex you can download the file.
The first approach would be a cleaner one.

initially load a page with the BrowserField and then have links clicked in that open up in the BB browser instead of the BrowserField?

I want to initially load a page (stored html page) with the BrowserField and then have links clicked in that open up in the BB browser instead of the BrowserField?
My current code is as following,
BrowserFieldConfig.setProperty(BrowserFieldConfig.CONTROLLER, new BrowserFieldController()
{
public InputConnection handleResourceRequest(BrowserFieldRequest request) throws Exception {
return (InputConnection)Connector.open(request.getURL());
}
public void handleNavigationRequest(BrowserFieldRequest request) throws Exception
{
BrowserSession b = Browser.getDefaultSession();
b.displayPage(request.getURL());
}
});
And I want to load the html page stored in resources in browserfield and then open the links from the page in BB Browser which I'm doing using
browserfield.requestContent("local:///test.html");
But application tries to open the html file in browser, which is not desirable.
Please suggest me a workaround,
Thanks,
Aniket
This should be quite easy to achieve.
Firstly you will need to use the BrowserField object instead.
Extend the browser field's javascript engine, by using BrowserField.extendScriptEngine(String name, Scriptable scriptable)
Within the Scriptable you will open the native browser.
In the html, make the buttons execute the extended javascript function you created.
The handleNavigationRequest(BrowserFieldRequest request) method is called each time the browserfield requests content.
Add a count inside the method.
Increment the count by 1 each time the method is called.
If the count is greater then 0, it means the Browserfield has already loaded the first time. Subsequent calls to the method should then open a browser session instead of requesting content inside the Browserfield.
public void handleNavigationRequest(BrowserFieldRequest request) throws Exception
{
if(click<1){
// request for content inside Browserfield
}
else {
BrowserSession b = Browser.getDefaultSession();
b.displayPage(request.getURL());
}
click++;
}

Resources