Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify will voice and will display APIs #1233

Closed

Conversation

Guardiola31337
Copy link
Contributor

Fixes #1224 and #1107 (comment)

Right now, it's pretty complicated to override SpeechAnnouncement and BannerInstructions objects without knowing their internals and clients of willVoice and willDisplay APIs are having a hard time to get them working. This PR simplifies willVoice and willDisplay APIs so they are user-friendly and work as expected.

Ultimately, I think that what clients would want from them is just to voice / display the announcement / banner text they want.

I added the DO NOT MERGE label (for now) because I'd love to discuss if the changes introduced make sense / will benefit clients. What do you think @danesfeder @devotaaabel? I'd love to hear your thoughts 🙏

cc'ing @akitchen to know:

  • also your inputs here
  • how this is implemented in iOS

Refs. #1074

@Danny-James
Copy link

@Guardiola31337 will this PR allow me to update the Banner Instruction and the Instruction List?

Updating just the Banner Instruction will only update the current Instruction Text I believe if the user taps on this they can see all the upcoming instuctions i would want to overwrite/hide the arrival instructions so this doesn't confuse the users as i'm using the Map Matching API after 100 Coordinates the user actually hasn't arrived at the destination.

Many Thanks.

Copy link
Contributor

@devotaaabel devotaaabel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The speech portion looks good 👍 , but I think we need to rethink the display portion and decide the intended functionality, specifically whether/how to retain abbreviations and highway signs.

String textBanner = bannerInstructionsListener.willDisplay(instructions);
List<BannerComponents> bannerComponents = new ArrayList<>(ONE);
bannerComponents.add(instructions.primary().components().get(FIRST).toBuilder().text(textBanner)
.abbreviation(textBanner).build());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't have to set an abbreviation, and there shouldn't be one unless there's an abbreviationPriority as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah, if not included the banner is not overridden at all. This is because how the final banner text to display is generated. We should revisit that logic.

return bannerInstructionsListener.willDisplay(instructions);
String textBanner = bannerInstructionsListener.willDisplay(instructions);
List<BannerComponents> bannerComponents = new ArrayList<>(ONE);
bannerComponents.add(instructions.primary().components().get(FIRST).toBuilder().text(textBanner)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with this is it's going to get rid of any formatting (abbreviations, highway signs). So, if the developer is only overriding some of the instructions, it's still going to remove the formatting from all of them. Also, do we think some advanced developers might take advantage of the abbreviations and/or road signs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with this is it's going to get rid of any formatting (abbreviations, highway signs). So, if the developer is only overriding some of the instructions, it's still going to remove the formatting from all of them.

Yeah, that's true and the tradeoff that we need to discuss / agree on.

Also, do we think some advanced developers might take advantage of the abbreviations and/or road signs?

Nope as far as I know.

That being said, I'd prefer to keep it simple for now (until a specific request comes in and at that point we can revisit).

}
return announcement;
}

BannerInstructions onBannerDisplay(BannerInstructions instructions) {
if (bannerInstructionsListener != null) {
return bannerInstructionsListener.willDisplay(instructions);
String textBanner = bannerInstructionsListener.willDisplay(instructions);
List<BannerComponents> bannerComponents = new ArrayList<>(ONE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you rename this bannerComponentsList? It's confusing since the object name is plural (BannerComponents).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, as you mentioned the problem here is that the object name is plural (not the best one though IMO). Will try to come up with a better name and update. Thanks for flagging.

*/
SpeechAnnouncement willVoice(SpeechAnnouncement announcement);
String willVoice(SpeechAnnouncement announcement);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 This is a good idea, in the case of speech announcements which are simpler.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, as you mentioned voice instructions are simpler because basically there's only one option to override - the announcement that you want the speech engine to speak. To be concrete here I want to note that we're removing the ssmlAnnouncement - which I don't think that any developer would want to take advantage of but as said, if the time comes we can revisit.

@Guardiola31337
Copy link
Contributor Author

Hey @Danny-James 👋 thanks a lot for the feedback here. You're correct here > Updating just the Banner Instruction will only update the current Instruction Text I believe if the user taps on this they can see all the upcoming instuctions

i would want to overwrite/hide the arrival instructions

To achieve this, we will need to revisit how the instructions list works and expose an API that allows so. But I think it's technically feasible. We will prioritize internally and discuss a solution for this and then report back here on this ticket. Thanks again!

@Guardiola31337
Copy link
Contributor Author

Another use case to think about / discuss is what to do with the "then" banner instruction when clients override the banner with the willDisplay API 👀

then_banner_instruction_not_overridden

Maybe, hiding it for now?

@Danny-James
Copy link

Another use case to think about / discuss is what to do with the "then" banner instruction when clients override the banner with the willDisplay API 👀

Maybe, hiding it for now?

In my case @Guardiola31337 the BannerInstruction says You will arrive the then instructions says You have arrived

in my turn i'd like the ability to hide this when required, would this be possible as you can see i would like to overide the main text with something like Continue along route and hide the then section until my next 100 coordinates are calculated.

@Guardiola31337
Copy link
Contributor Author

@Danny-James
Yeah, as I mentioned this is something that we're going to look into too. We'll circle back here when the approaches to take are decided. Stay tuned! Thanks 🙏

Copy link
Contributor

@danesfeder danesfeder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per our discussion, we will simplify these APIs for now as no one has specific needs for SSML voice instructions or complex banner updates. Thanks for running with this @Guardiola31337.

Please rebase and 🚢 🚀

@devotaaabel
Copy link
Contributor

Approved and moved the topic I brought up into it's own issue #1262

@akitchen
Copy link

Let's split this into two efforts, one for voice instructions and one for banner instructions.

@Guardiola31337 Guardiola31337 force-pushed the pg-1224-intercept-voice-banner-instructions branch from d893576 to b5bd454 Compare September 11, 2018 09:33
@Guardiola31337
Copy link
Contributor Author

Let's split this into two efforts, one for voice instructions and one for banner instructions.

Voice instructions follow up work 👉 #1281

@Danny-James
Copy link

@Guardiola31337 do you have an idea of when the BannerText changes will be released?

@Guardiola31337
Copy link
Contributor Author

@Danny-James

do you have an idea of when the BannerText changes will be released?

As you've seen above, the display changes are not trivial. There are some design questions that need answers before implementing a solution that covers all the cases / scenarios. So we're going to keep discussing the intended functionality internally and then report back when we have a plan of attack.

That being said, for now, in order to override the banner instruction text (I believe that's what you're asking for in #1224, right?) you can implement the following when willDisplay callback is fired:

  @Override
  public BannerInstructions willDisplay(BannerInstructions instructions) {
    List<BannerComponents> bannerComponents = new ArrayList<>();
    bannerComponents.add(instructions.primary().components().get(0).toBuilder().text("All banners will be the same.")
      .abbreviation("All banners will be the same.").build());
    BannerInstructions bannerToBeDisplayed = instructions.toBuilder().primary(instructions.primary().toBuilder()
      .components(bannerComponents).build()).build();
    return bannerToBeDisplayed;
  }

The snippet above showcases how to override the step primary text that is displayed. You can add / modify the logic in willDisplay to address your use case but you get the idea.

Hope this helps. Thanks!

@Danny-James
Copy link

@Guardiola31337 do this mean anything to you?

Code

    @Override
    public BannerInstructions willDisplay(BannerInstructions instructions) {
        if (instructions.primary().text().contains("arrive") && points.size() > 1){
            Log.d(TAG, "Overide Banner Text");
            List<BannerComponents> bannerComponents = new ArrayList<>();
            bannerComponents.add(instructions.primary().components().get(0).toBuilder().text("Continue along route")
                    .abbreviation("Continue").build());
            BannerInstructions bannerToBeDisplayed = instructions.toBuilder().primary(instructions.primary().toBuilder()
                    .components(bannerComponents).build()).build();

            return bannerToBeDisplayed;

        }
        return instructions;
    }

Error

09-14 13:30:24.394 28946-28946/uk.co.ainscough.routeinfo E/AndroidRuntime: FATAL EXCEPTION: main
    Process: uk.co.ainscough.routeinfo, PID: 28946
    java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
        at com.mapbox.services.android.navigation.ui.v5.instruction.AbbreviationCoordinator.abbreviateUntilTextFits(AbbreviationCoordinator.java:74)
        at com.mapbox.services.android.navigation.ui.v5.instruction.AbbreviationCoordinator.abbreviateBannerText(AbbreviationCoordinator.java:65)
        at com.mapbox.services.android.navigation.ui.v5.instruction.InstructionLoader.getAbbreviatedBannerText(InstructionLoader.java:98)
        at com.mapbox.services.android.navigation.ui.v5.instruction.InstructionLoader.setText(InstructionLoader.java:93)
        at com.mapbox.services.android.navigation.ui.v5.instruction.InstructionLoader.loadInstruction(InstructionLoader.java:54)
        at com.mapbox.services.android.navigation.ui.v5.instruction.InstructionView.updateDataFromBannerInstruction(InstructionView.java:873)
        at com.mapbox.services.android.navigation.ui.v5.instruction.InstructionView.access$100(InstructionView.java:80)
        at com.mapbox.services.android.navigation.ui.v5.instruction.InstructionView$2.onChanged(InstructionView.java:200)
        at com.mapbox.services.android.navigation.ui.v5.instruction.InstructionView$2.onChanged(InstructionView.java:196)
        at android.arch.lifecycle.LiveData.considerNotify(LiveData.java:109)
        at android.arch.lifecycle.LiveData.dispatchingValue(LiveData.java:126)
        at android.arch.lifecycle.LiveData.setValue(LiveData.java:282)
        at android.arch.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)
        at com.mapbox.services.android.navigation.ui.v5.NavigationViewModel.updateBannerInstruction(NavigationViewModel.java:393)
        at com.mapbox.services.android.navigation.ui.v5.NavigationViewModel.access$800(NavigationViewModel.java:49)
        at com.mapbox.services.android.navigation.ui.v5.NavigationViewModel$3.onMilestoneEvent(NavigationViewModel.java:286)
        at com.mapbox.services.android.navigation.v5.navigation.NavigationEventDispatcher.onMilestoneEvent(NavigationEventDispatcher.java:137)
        at com.mapbox.services.android.navigation.v5.navigation.RouteProcessorThreadListener.onMilestoneTrigger(RouteProcessorThreadListener.java:46)
        at com.mapbox.services.android.navigation.v5.navigation.RouteProcessorHandlerCallback$1.run(RouteProcessorHandlerCallback.java:98)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6938)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

@Danny-James
Copy link

@Guardiola31337 i've taken out the following section of the code .abbreviation("Continue") which is now working.

However, the BannerText has been overwritten, but the Notification Text is still saying You will arrive.

See below;

screenshot_20180914-141331_route info
screenshot_20180914-141342_route info

@danesfeder
Copy link
Contributor

@Guardiola31337 can the willDisplay work / behavior be ticket out separately here? And then this PR can be closed

@Danny-James
Copy link

@Guardiola31337 @danesfeder I've noticed one more issue when overriding the BannerText, the Then text is no longer displayed once overwritting, once the next instructions is displayed/voiced the Then text is never shown.

@Danny-James
Copy link

Danny-James commented Sep 27, 2018

@Guardiola31337 do we have an update on this?

Outstanding Issues I've Found;

  • NotificationText does not align with overwritten banner text.
  • Adding .abbreviation("Continue") causes crash.
  • After overwriting BannerText, the Then section is no longer displayed.
  • Overwrite list of upcoming instructions (Shown when bannerText is touched)

@danesfeder
Copy link
Contributor

@Guardiola31337 can we close this / write up a follow-up ticket for the willDisplay work if one is not created already? Thanks

@Guardiola31337
Copy link
Contributor Author

@Danny-James

do we have an update on this?

Outstanding Issues I've Found;

  • Adding .abbreviation("Continue") causes crash.

I thought you get this working per comment #1233 (comment)

i've taken out the following section of the code .abbreviation("Continue") which is now working.

  • After overwriting BannerText, the Then section is no longer displayed.

How are you overwriting BannerText? "then" banner instructions still appear here 👀 #1233 (comment)

I'm going to reopen #1224 and track the missing willDisplay work there and closing here.

Thanks @Danny-James for your thoroughly testing here 🙏 Really appreciate it!

@Danny-James
Copy link

@Guardiola31337

Adding .abbreviation("Continue") causes crash. - I left this out of the code as adding this in caused a crash.

After overwriting BannerText, the Then section is no longer displayed. - It seems to be once the banner text has been changed I no longer get the Then instructions.

    @Override
    public BannerInstructions willDisplay(BannerInstructions instructions) {
        if (instructions.primary().text().contains("arrive") && points.size() > 1){
            Log.d(TAG, "Override Banner Text");
            Log.d(TAG, "OVERRIDE TEXT: " + instructions.primary().text() + " with Continue along route");
            List<BannerComponents> bannerComponents = new ArrayList<>();
                bannerComponents.add(instructions.primary().components().get(0).toBuilder().text("Continue along route").build());
            BannerInstructions bannerToBeDisplayed = instructions.toBuilder().primary(instructions.primary().toBuilder()
                    .components(bannerComponents).build()).build();
            return bannerToBeDisplayed;
        }
        return instructions;
    }

@Guardiola31337 Guardiola31337 deleted the pg-1224-intercept-voice-banner-instructions branch January 16, 2019 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⚠️ DO NOT MERGE PR should not be merged!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants