-
Notifications
You must be signed in to change notification settings - Fork 319
Dynamic abbreviations in banner instructions #887
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
Conversation
…ng shield and abbreviation logic
…abbreviations by abbreviationPriority while also keeping track of index
danesfeder
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a couple nit picks - overall this looks great. Nice work @devotaaabel
| this.abbreviations = new HashMap<>(); | ||
| this.textViewUtils = textViewUtils; | ||
| } | ||
|
|
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
|
|
||
| int currAbbreviationPriority = 0; | ||
| int maxAbbreviationPriority = Collections.max(abbreviations.keySet()); | ||
| while (!textViewUtils.textFits(textView, bannerText) && (currAbbreviationPriority <= maxAbbreviationPriority)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we pull this while out into a private method to make abbreviateBannerText more readable?
We can also extract !textViewUtils.textFits(textView, bannerText) && (currAbbreviationPriority <= maxAbbreviationPriority) into two booleans that better explain what is being checked by the loop.
Guardiola31337
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this is looking great. Well done @devotaaabel
Some comments to discuss before merging the PR.
| * BannerComponents containing abbreviation information and given a list of BannerComponentNodes, | ||
| * constructed by InstructionLoader. | ||
| */ | ||
| public class AbbreviationCoordinator { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to expose this class and its methods publicly?
Classes are private until the opposite is proved.
😂
It's only consumed by InstructionLoader (+ tests) which is in the same package so I guess we could make it package-private. Also the IDE hints you about doing that (constructors).
| private Map<Integer, List<Integer>> abbreviations; | ||
| private TextViewUtils textViewUtils; | ||
|
|
||
| public AbbreviationCoordinator(TextViewUtils textViewUtils) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Access can be package-private
|
|
||
| /** | ||
| * Using the abbreviations HashMap which should already be populated, abbreviates the text in the | ||
| * bannerConmponentNodes until the text fits the given TextView. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT Typo *bannerConmponentNodes
| */ | ||
| public void addPriorityInfo(BannerComponents bannerComponents, int index) { | ||
| int abbreviationPriority = bannerComponents.abbreviationPriority(); | ||
| if (abbreviations.get(Integer.valueOf(abbreviationPriority)) == null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary boxing 'Integer.valueOf(abbreviationPriority)'
| int maxAbbreviationPriority = Collections.max(abbreviations.keySet()); | ||
|
|
||
| while (shouldKeepAbbreviating(textView, bannerText, currAbbreviationPriority, maxAbbreviationPriority)) { | ||
| List<Integer> indices = abbreviations.get(new Integer(currAbbreviationPriority++)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary boxing 'new Integer(currAbbreviationPriority++)'
| private BannerShield shield; | ||
| private InstructionLoadedCallback instructionLoadedCallback; | ||
|
|
||
| InstructionTarget(TextView textView, Spannable instructionSpannable, |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
| import android.graphics.Paint; | ||
| import android.widget.TextView; | ||
|
|
||
| public class TextViewUtils { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to expose this class and its method publicly?
Classes are private until the opposite is proved.
😂
It's only consumed by AbbreviationCoordinator (+ tests) so I guess this should live under com.mapbox.services.android.navigation.ui.v5.instruction package.
| public class InstructionLoaderTest { | ||
|
|
||
| @Test | ||
| public void testPriorityInfoIsAdded() { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
|
|
||
| public class AbbreviationCoordinatorTest extends BaseTest { | ||
| @Test | ||
| public void textIsAbbreviatedWhenItDoesntFit() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency we should name the tests following the same style (e.g. onResetCamera_trackingIsResumed).
In any case, test prefix is not necessary because it's implicit with the usage of @Test annotation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normally is good to structure the tests following the triple A 👀 https://speakerdeck.com/guardiola31337/elegant-unit-testing-mobilization-2016?slide=40 http://wiki.c2.com/?ArrangeActAssert
Here we're including the Act inside the Assert. It'd be great to have them separated and take advantage of giving great names to variables so it's easy to understand what's going on.
AbbreviationCoordinator abbreviationCoordinator = new AbbreviationCoordinator(textViewUtils);
abbreviationCoordinator.addPriorityInfo(bannerComponents, 0);
List<InstructionLoader.BannerComponentNode> bannerComponentNodes = new ArrayList<>();
bannerComponentNodes.add(new AbbreviationCoordinator.AbbreviationNode(bannerComponents, 0));Should be in the Arrange part.
This applies to other tests included in AbbreviationCoordinatorTest.
|
|
||
| import com.mapbox.api.directions.v5.models.BannerComponents; | ||
|
|
||
| public class BannerComponentsFaker { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why BannerComponentsFaker needs to be public?
Classes are private until the opposite is proved.
😂
I guess we could make it package-private, it's only consumed by the tests.
7e0e2c8 to
f2b0dd3
Compare
f2b0dd3 to
4a8427b
Compare
danesfeder
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚢 Awesome work @devotaaabel!
#807 I moved the image loading logic from
InstructionLoaderinto the new classInstructionImageLoaderto separate concerns, and addedAbbreviationCoordinator. Both new classes are accessed byInstructionLoader, which now coordinates the use of both new classes.