Skip to content

Conversation

@usamahamid
Copy link
Contributor

@usamahamid usamahamid commented Aug 7, 2018

This is one of the screens required for custom domain association

This PR introduces a new screen, in which User can be search and select one of the available domain names (identified from /v1.1/domains/suggestions/ API). The navigation to this UI is not included yet, this is intended to keep this PR from affecting any working implementation.

@wpmobilebot
Copy link
Contributor

wpmobilebot commented Aug 7, 2018

1 Warning
⚠️ PR has more than 500 lines of code changing. Consider splitting into smaller PRs if possible.

Generated by 🚫 Danger

@malinajirka malinajirka self-assigned this Aug 7, 2018
@malinajirka malinajirka added this to the 10.8 milestone Aug 7, 2018
@malinajirka
Copy link
Contributor

Thank you @usamahamid! Good job;).

I'm done with my first pass. I haven't tested the app though, as it's not tied to the UI yet. I've left few comments, most of which are just my preference.

Are you planning to create another PR with unit tests?


private fun onDomainSuggestionSelected(suggestion: DomainSuggestionResponse?, position: Int) {
selectedPosition = position
notifyDataSetChanged()
Copy link
Contributor

Choose a reason for hiding this comment

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

Can't we be more specific when notifying the observers about the change and use notifyItemChanged(int position) for example? JavaDoc of the notifyDataSetChanged() method says, it should be used as a last resort. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Of course.
We just have to update selectedPosition and previouslySelectedPosition. I have updated the same in 1c00bdb.

internal fun updateSuggestionsList(items: List<DomainSuggestionResponse>) {
list.clear()
list.addAll(items)
notifyDataSetChanged()
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above. We might want to use DiffUtil. WDYT?

Copy link
Contributor Author

@usamahamid usamahamid Aug 9, 2018

Choose a reason for hiding this comment

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

Since we are resetting the whole list, it might be easier and cheaper (performance wise, since we don't need the diff) to call notifyDataSetChanged().
notifyItemRangeChanged will work as well, but the size of the new suggestions list might be different, which might cause problems. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

Fair enough;)!

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

(activity?.application as WordPress).component()?.inject(this)
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 just my opinion, so please raise your objections if you have any. I'm a big fan of Fail ASAP principle -> the app will crash anyway, if the component is null, right? The crash will be just a bit harder to debug, because it will crash on one of the lines below. So I'd prefer to use checkNotNull(..) instead of ? to fail on our terms. Does it make sense?

}

override fun onSaveInstanceState(outState: Bundle) {
outState.putSerializable(WordPress.SITE, viewModel.site)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to manually save the model? Doesn't it survive configuration changes in the Intent of the parent Activity? Wdyt?

Copy link
Contributor Author

@usamahamid usamahamid Aug 9, 2018

Choose a reason for hiding this comment

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

Of course, since we are not updating in SiteModel here. It need not be preserved in the instanceState. 👍

}

private fun setupObservers() {
viewModel.suggestionsLiveData.observe(this, Observer {
Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer not having any business logic in the view. Couldn't we move this into the ViewModel so it's easily testable. Wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Understandable, I have updated the same in 56af118.

})
}

private fun reloadSuggestions(domainSuggestions: List<DomainSuggestionResponse>) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Again, more of a personal preference. The method is called reloadSuggestions, but it also initializes the adapter. Can't we move the initialization logic somewhere else? Maybe into the setupViews()? Wdyt?


private fun fetchSuggestions() {
// Disable Load more
suggestions = ListState.Loading(suggestions, false)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to explicitly set canLoadMore attribute to false? False is a default value, isn't it?

// Disable Load more
suggestions = ListState.Loading(suggestions, false)

val suggestDomainsPayload = SuggestDomainsPayload(searchQuery, false, false, true, 30)
Copy link
Contributor

Choose a reason for hiding this comment

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

We might consider creating a constant for the 30. Wdyt?

@usamahamid usamahamid changed the base branch from develop to feature/domain-register August 7, 2018 08:49
Removed SIte model from being saved in instance state, since it is not updated.
Moved Recycler view adapter initialization into `setupViews`
…hould be removed before feature branch is merged to develop.
@usamahamid
Copy link
Contributor Author

@malinajirka, I have updated most of PR as per your comments.
Please do check it out, when have a free moment.

I have included a new row in my site page to navigate into domain suggestions listing (for testing purposes).
I will be raising another PR with the Mockito test cases.

Copy link
Contributor

@malinajirka malinajirka left a comment

Choose a reason for hiding this comment

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

Thank you @usamahamid!

I've left one real comment (and few nitpicks:P). But it looks good, overall:). When you fix these, I believe it'll be ready for merge.

suggestionsListProgress.visibility = if (it == true) View.VISIBLE else View.GONE
})
viewModel.suggestionsLiveData.observe(this, Observer {
if (it != null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a just nitpicking, sorry. But the if is a business logic as well. If you just suppress all the nulls anyway, can't we just make sure the items in the LiveData are NonNull?
Note: Btw I'm not sure how the API works, but doesn't it return null when it doesn't find any results (not ideal solution, but I've seen it).

Copy link
Contributor Author

@usamahamid usamahamid Aug 9, 2018

Choose a reason for hiding this comment

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

The it will never be null in here, we have defined the LiveData within the ViewModel as NonNull.
But the Observer.observe() always gives a Nullable object, since this is Kotlin, this requires a defensive check here.
We can overcome this by introducing a NonNullObserver, like mentioned in the below link.
https://proandroiddev.com/nonnull-livedata-with-kotlin-extension-26963ffd0333

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you @usamahamid for bringing this up! Definitely an interesting idea! I wouldn't delay this PR on such a minor issue. We can introduce the NonNullObserver anytime later if we see same null check pattern reoccurring.

// Network Request

private fun fetchSuggestions() {
// Disable Load more
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if this comment still makes sense. Wdyt?

suggestions = ListState.Error(suggestions, event.error.message)
return
}
suggestions = ListState.Success(event.suggestions, false) // Disable load more
Copy link
Contributor

Choose a reason for hiding this comment

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

The false is a default value even here. We might want to remove it as well to keep it consistent. Wdyt?

ToastUtils.showToast(activity, "Still under development.")
}
domainSearchEditText.setOnEditorActionListener { view, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I've missed this reading the code, but testing the functionality on an emulator revealed it.

We might want to search as the user types not just when they press Done. That's why we have a handler in the ViewModel, right (the handler is used in submitSearch(..))? Also we use this approach in other parts of the app, so we should keep it consistent (eg. My Site -> Media -> Search)

@usamahamid
Copy link
Contributor Author

@malinajirka, I have updated the PR to include a TextWatcher as you mentioned (which is a definite improvement). 👍
I have replied to one of your comments, Please check it out and tell me what you think. 🙂

@malinajirka
Copy link
Contributor

Thank you for fixing the issues @usamahamid!

I'm sorry, but I have overlooked one issue, which we should fix before we merge this PR.

I've been reviewing the code and functionality, but I totally forgot to check the design. I believe some of the colors don't match the design

  • background, radio buttons and the choose domain button colors don't match

There are two more tiny issues, which are not in the proposed design, but we should probably try to be consistent with the SiteCreation flow.

Updated Layout design as per review comments.
Additional fix to retain selection in default search screen during orientation change.
@usamahamid
Copy link
Contributor Author

@malinajirka, I have updated the PR with the UI changes you requested (Seems, I missed to update the theme for the new activity).
Additionally I have fixed a minor bug where the search query is reset if it is empty, during orientation change.

The PR is ready for another pass. Please do check it out, when you have free moment.

Copy link
Contributor

@malinajirka malinajirka left a comment

Choose a reason for hiding this comment

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

Thank you @usamahamid!

After taking a closer look, I noticed that some colors still don't match. I think we should try to be consistent with the SiteCreation screen as much as possible, so the app seems polished:).
sitecreation_vs_domainregistration


<ProgressBar
android:id="@+id/suggestionsProgressBar"
android:layout_width="24dp"
Copy link
Contributor

Choose a reason for hiding this comment

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

We might consider extracting this into dimens.xml. Wdyt?

@usamahamid
Copy link
Contributor Author

@malinajirka, I have updated the layout design to match the Site Creation layout and it is ready for another pass.
Please do check it out, when you have a free moment. 👍

@malinajirka
Copy link
Contributor

Thank you @usamahamid! I've just done a final test and it looks awesome:)!

@malinajirka malinajirka reopened this Aug 10, 2018
@malinajirka malinajirka merged commit c7bd8ee into wordpress-mobile:feature/domain-register Aug 10, 2018
mzorz added a commit that referenced this pull request Jun 12, 2020
1a43e016c6 Merge pull request #29 from wordpress-mobile/issue/28-empty-img-tag-crash-fix
a4c24373e5 Updated the release version to 1.24
a33296f4d6 Check if img source is null before checking for image smileys
1dd7406ad5 Merge pull request #27 from wordpress-mobile/combined-updates-from-wpandroid
b918b23ac5 Check if announcement is available in App Settings before showing option. Updated AppLog to include announcement related tracker.
94e23e28c1 Rename build.gradle fields with invalid name syntax
d0be1240ca Make sure url utils recognizes atomic image proxy as valid image url.
9bdbdff3a9 Merge branch 'feature/support-private-at-sites' of https://github.com/wordpress-mobile/WordPress-Android into feature/support-private-at-sites
fcc5c99e37 Updated Photon utils to utilize new url for private AT proxy.
130195092f Gutenberg/integrate release 1.25.0 with dark mode (#11580)
a25096c291 Restoring Utils lib version to 1.24
edfef1e58c Merge branch 'develop' into issue/11249-media-not-load-jetpack
60d516266e Merge pull request #11536 from wordpress-mobile/add/log-persistence
1aceca9950 Make the linter happy
18c8447fe3 Change provider visibility
dac4e5ce38 Fixes to LogFileHelpersTest
76f9f75f5d Variablize recent created files test
a4d0a773e7 Small fixes for LogFileCleanerTest
24ac53fabf Make the queue private
64ea6a8cdf Use correct hungarian notation for static member
1c978ca61a Refactor tests to match project refactoring
565b88903c Persist log files in a background thread
3ae86d48e4 Refactor LogEntry.toString method
b900bdda83 Refactor LogFileHelpers to not use context and be a LogFileProvider
225e1db645 Upgrading lib version.
6fd47e8eb6 Using the assertThat pattern.
0948a93056 Adding connected testing.
dc5c2e3cd6 Refactor LogFileWriter to use LogFileProvider instead of context
2d5d0b65c0 Refactor LogFileCleaner to not need context and use a LogFileProvider instead
84b7a8a87d Minor changes in LogFileWriter to make it more idiomatic
8cfa0950aa Merge branch 'develop' into issue/11249-media-not-load-jetpack
31a14daeb4 Bump the utils minSdkVersion to 18
f65fd78414 Add log persistence
fe3960d6b7 Updating ssl logic for photon addresses.
1b4b31bf88 Merge pull request #11524 from wordpress-mobile/fix/wordpressutils-tests
6c80419806 Fix WordPressUtils tests
def5be4e88 Revert "Feature/material theme and Dark Theme support (#11469)" (#11486)
16540e85f1 Feature/material theme and Dark Theme support (#11469)
0ae297bbd3 Adding ssl parameter to query for Photon https.
89725645a6 made method name more meaningful.
76343d3d6d Added util function to check if a Uri is a content one.
75790052ef Merge pull request #11072 from wordpress-mobile/issue-10843/latitude_fix_api_29
981eb82158 Merge branch 'develop' into try/media-upload-completion-processor
8799a19ec4 removes safe check due to nature of RecyclerView
7906f07645 Fixed latitude missing column issue on api 29
882a64faf3 updated gradle wrapper of utils project.
b012d38c3f resolved conflicts and merged utils subtree
e8aae6d282 Merge branch 'develop' into try/media-upload-completion-processor
da19376391 Add MediaFile method to generate attachment page url
e35a9e0cd8 Used delegate safe method for focused accessibility event listener
de02499434 Merge remote-tracking branch 'origin/develop' into issue/10894-aztec-media-talkback
1812393e22 Added accessibility heading
30aa9a3132 Added a safe way to set accessibility delegates.
870518ff07 Moved method to util class that's more appropriate for it's behavior
a998f6e877 added annotations to event listener method
43013a5a79 Moved behavior to Utils so that it can be replicated in other areas.
54ca204429 Removed unused imports.
373db7c13f Removed unneeded whitespace and added necessary whiteline
785da6617b WP Media Picker now announces when an image is selected.
75f0913259 "Done" button now has a content description of "Cancel"
42ec1fb96c Disabled hint announcements and applied accessibility headings
916e2b0d96 Add comment to downloadExternalMedia method
573ba7f5e8 Clean up AddMediaToEditor logic
dda3a1ebb8 Merge pull request #10565 from wordpress-mobile/clean-up-after-legacy-editor
d84fb1f61f Upgrade Gradle to 5.4.1, gradle plugin to 3.5.1 and fix various errors
0511354994 Remove WPEditText
19d3f4aaf0 Optimize AppLog
b4401cd84f Fix simple date format concurrency issue
15ee1b27d0 Remove usages of buggy DateTimeUtils methods
e9f01e5e3c Fixed loop.
47eec63356 Merge branch 'develop' of github.com:wordpress-mobile/WordPress-Android into issue/9815-email-verification-reminder
25d1310312 Fix AndroidX import order
a21c7120d8 Fix import ordering for androidx
35b99bc73e Migrate to AndroidX
d40e8773bb Merge branch 'issue/9815-create-call-to-action' into issue/9815-add-reminder-message
892eacce49 Make getPath private again
ae6291c612 Use existing method instead of creating a new one in MediaUtils
10b59f8d06 Implement comments from PR
f1b21d0acc Add logging for the failing cases
702881b26f A crash fix for uploaded docs
cc1c0334a8 Added reminder message toast after domain has been registered
9a14564929 Merge branch 'develop' of github.com:wordpress-mobile/WordPress-Android into issue/9452-domain-suggestions
a4d8873a2e Update style config from style-config-android
1c10935b8c Merge branch 'develop' of github.com:wordpress-mobile/WordPress-Android into issue/9452-domain-suggestions
971cf76d96 Remove unused get snackbar duration method from accessibility utils class
28b0685ae7 Update is accessibility enabled method in accessibility utils for simplicity
a418cb7dc8 Update get snackbar duration method in accessibility utils for indefinite constant
e0dd4824c9 Merge branch 'develop' of github.com:wordpress-mobile/WordPress-Android into issue/9452-domain-suggestions
506f9883ce refactored ToastUtils to be able to pass gravity as param. Also showing toast after back-dating a scheduled post on top anchor now
e164cd7a61 Fixing merge conflicts from domain register branch.
586222ec51 Merge pull request #8164 from usamahamid/feature/domain-register
50de29e20a Introduced Domain Suggestion Network request in ViewModel

git-subtree-dir: libs/utils
git-subtree-split: 1a43e016c63bd9dc19f3e27d39b8dc1cba7c5263
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants