EddyVerbruggen / Toast-PhoneGap-Plugin

:beers: A Toast popup plugin for your fancy Cordova app
MIT License
510 stars 276 forks source link

Touch callback never triggers #88

Open HikeNH opened 8 years ago

HikeNH commented 8 years ago

Expected behaviour

the trigger event listed below should trigger.

Actual behaviour

The success is always called upon initializing the toast, and result returns a value of "ok". result.event is never populated. The trigger event works if I set it to occur when the result value is "ok", so whatever I'm doing wrong is specific to the code below. Any help or suggestions?

I'm seeing this behaviour on

Remove this hint: these checkboxes can be checked like this: [x]

Acts.prototype.ShowToast = function (st_message,st_duration,st_location,st_offset,st_opacity,st_backcolor,st_textcolor,st_textsize,st_cornerradius,st_hpadding,st_vpadding) {if(st_location === 0){st_location = "top";} else if(st_location === 1){st_location = "center";} else{st_location = "bottom";} window["plugins"]["toast"]["showWithOptions"]({ "message": st_message, "duration": st_duration, "position": st_location, "addPixelsY": st_offset, "data": {"foo":"bar"}, "styling": { "opacity": st_opacity, // 0.0 %28transparent) to 1.0 (opaque). Default 0.8 "backgroundColor": st_backcolor, // make sure you use #RRGGBB. Default #333333 "textColor": st_textcolor, // Ditto. Default #FFFFFF "textSize": st_textsize, // Default is approx. 13. "cornerRadius": st_cornerradius, // minimum is 0 (square). iOS default 20, Android default 100 "horizontalPadding": st_hpadding, // iOS default 16, Android default 50 "verticalPadding": st_vpadding // iOS default 12, Android default 30

}
},
// implement the success callback
function(result) {
    ToastMessage = result["event"];
        if (result && result["event"]) {

    if(result["event"] == 'hide')
            {
                ToastRuntime.trigger(cr.plugins_.locke_cordova_toast.prototype.cnds.OnToast, ToastInst);
            }
            else if(result["event"] == 'touch')
            {
            ToastRuntime.trigger(cr.plugins_.locke_cordova_toast.prototype.cnds.OnToastTouch, ToastInst);
          }
  }

},function(result1){
  ToastMessage = result1;
    ToastRuntime.trigger(cr.plugins_.locke_cordova_toast.prototype.cnds.OnToastFail, ToastInst);
}

); };

frcol commented 8 years ago

Same problem here.

lantonello commented 8 years ago

Me too

EddyVerbruggen commented 8 years ago

Please add some useful info. Android device/ version at the very least

lantonello commented 8 years ago

Sorry Eddy,

For me, the touch callback triggers only in Android 5.1. Does not work in Android 4.4, 5.0 and 6.0 The callback also triggers on iOS. When toast appears on screen, the callback is triggered with result as a String, not an object.

(sorry for my bad english)

rodrigodobbin commented 8 years ago

Same here,

The versions is the same as @lantonello.

my callback:

// implement the success callback
function(result) {
    console.log(result);
    if (result && result.event) {
        ...My code goes here
    }
}

Problem is: the result parameter is return a "OK" string, then we can't capture the result.event when the user touch the screen.

EddyVerbruggen commented 8 years ago

Let me try to make time for this tomorrow.

EddyVerbruggen commented 8 years ago

Before digging into this deeper I really need to confirm something with you. I've installed cordova-plugin-x-toast (mind the x) and threw a button on a vanilla Cordova CLI app which triggers this code:

  function tap() {
     window.plugins.toast.showWithOptions(
      {
        message: "hey there",
        duration: 1500, // ms
        position: "bottom",
        addPixelsY: -40,  // (optional) added a negative value to move it up a bit (default 0)
        data: {'foo':'bar'} // (optional) pass in a JSON object here (it will be sent back in the success callback below)
      },
      // implement the success callback
      function(result) {
        if (result && result.event) {
          console.log("The toast was tapped or got hidden, see the value of result.event");
          console.log("Event: " + result.event); // "touch" when the toast was touched by the user or "hide" when the toast geot hidden
          console.log("Message: " + result.message); // will be equal to the message you passed in
          console.log("data.foo: " + result.data.foo); // .. retrieve passed in data here

          if (result.event === 'hide') {
            console.log("The toast has been shown");
          }
        }
      }
    );
  }

On my KitKat (4.4) device this gives me this (expected) output in the console when tapping the toast:

[INFO:CONSOLE(35)] "The toast was tapped or got hidden, see the value of result.event", source: file:///android_asset/www/index.html (35)
[INFO:CONSOLE(36)] "Event: touch", source: file:///android_asset/www/index.html (36)
[INFO:CONSOLE(37)] "Message: hey there", source: file:///android_asset/www/index.html (37)
[INFO:CONSOLE(38)] "data.foo: bar", source: file:///android_asset/www/index.html (38)

What's different in your setups that you don't see this?

frcol commented 8 years ago

In my case, I´m using in an Ionic 1 project. I have a service with:

function ToastService($cordovaToast) {
        return {
            showToast: function(message, duration = 'short', location = 'bottom') {
                $cordovaToast.show(message, duration, location)
                .then(function(result) {
                    console.log("result: "+result);
                    return;
                }, function (error) {
                    console.log("The toast was not shown due to " + error);
                    return;
                });
            }
        }
    };

and the log always shows an "OK" string.

EddyVerbruggen commented 8 years ago

@frcol Which plugin version are you using and do you have the same problem if you remove ngCordova from the equation? So replacing $cordovaToast.show by my snippet above?

ds8k commented 8 years ago

I'm experiencing the same problem on a Samsung Galaxy S6 running Android 5.1.1, as well as an S7 Edge on 6.0.1.

However I'm not experiencing this on a Galaxy Avant running 4.4.2 or a Nexus 6P on 7.0. Coincidentally, these are the same devices that have an issue with #95

EddyVerbruggen commented 7 years ago

I don't have a S6 or S7 so can't help here..

jbasinger commented 7 years ago

I have an S4 with 5.0.1 and tapping the toast does nothing =(

shogunfighter commented 7 years ago

I have the same problem, the touch event is not coming out for s7 edge.

So i tinkered in the Toast.java file for ANDROIDE located in: <app>/platforms/android/src/nl/xservices/plugins/Toast.java

I commented this entire line:

if (IS_AT_LEAST_LOLLIPOP) {
getViewGroup().setOnTouchListener(new View.OnTouchListener() {
  @Override
  public boolean onTouch(View view, MotionEvent motionEvent) {
    if (motionEvent.getAction() != MotionEvent.ACTION_DOWN) {
      return false;
    }
    if (mostRecentToast == null || !mostRecentToast.getView().isShown()) {
      getViewGroup().setOnTouchListener(null);
      return false;
    }

    float w = mostRecentToast.getView().getWidth();
    float startX = (view.getWidth() / 2) - (w / 2);
    float endX = (view.getWidth() / 2) + (w / 2);

    float startY;
    float endY;

    float g = mostRecentToast.getGravity();
    float y = mostRecentToast.getYOffset();
    float h = mostRecentToast.getView().getHeight();

    if (g == GRAVITY_BOTTOM) {
      startY = view.getHeight() - y - h;
      endY = view.getHeight() - y;
    } else if (g == GRAVITY_CENTER) {
      startY = (view.getHeight() / 2) + y - (h / 2);
      endY = (view.getHeight() / 2) + y + (h / 2);
    } else {
      // top
      startY = y;
      endY = y + h;
    }

    float tapX = motionEvent.getX();
    float tapY = motionEvent.getY();

    final boolean tapped = tapX >= startX && tapX <= endX &&
        tapY >= startY && tapY <= endY;

    return tapped && returnTapEvent("touch", msg, data, callbackContext);
  }
});
} else {
toast.getView().setOnTouchListener(new View.OnTouchListener() {
  @Override
  public boolean onTouch(View view, MotionEvent motionEvent) {
    return motionEvent.getAction() == MotionEvent.ACTION_DOWN && returnTapEvent("touch", msg, data, callbackContext);
  }
});
}

Replaced it with this:

toast.getView().setOnTouchListener(new View.OnTouchListener() {
  @Override
  public boolean onTouch(View view, MotionEvent motionEvent) {
    toast.cancel(); //new code
    return motionEvent.getAction() == MotionEvent.ACTION_DOWN && returnTapEvent("touch", msg, data, callbackContext);
  }
});

Now, I can receive the touch event.

rafaellop commented 6 years ago

Another observation: https://github.com/EddyVerbruggen/Toast-PhoneGap-Plugin/issues/93#issuecomment-366701994

elewin commented 5 years ago

I am having a similar issue where on some android (8 and 9) phones, the result from the callback after touching the toast has event set to "hide" instead of "touch", though seems to work properly on iOS

gabriele-sacchi commented 4 years ago

Same issue here on multiple Android devices.

The touch event is correctly received in a Pixel_2_API_R emulator but that's not the case for some physical devices (eg. Galaxy S9).

This issue is blocking my release to production 😿

gabriele-sacchi commented 4 years ago

( Same issue as https://github.com/EddyVerbruggen/Toast-PhoneGap-Plugin/issues/80 )

gabriele-sacchi commented 4 years ago

shogunfighter's suggestion above did the trick for me 👍

PS. but introduced the same issue on other devices 😩

Trying to use both handlers for > lollipop + a workaround on the JS side..