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

Add EventHub, add fav, reblog events, improve timelines #562

Merged
merged 17 commits into from
May 27, 2018
Merged

Conversation

charlag
Copy link
Collaborator

@charlag charlag commented Apr 7, 2018

This is an experiment on better handling of events like fav, boost, reply.
Basically we need something like EventBus but

  • it is limited
  • I'm tired to see this verbose error handling across the project (onResponse ... if response.body ... onFailure ...)
  • I also consider LocalBroadcastManager a huge hack added for the sake of convenience

So my solution is RxJava.
How is this better than broadcasts? Well, imagine we want to update a thread after posting a reply (#552). We would have to serialize/deserialize status somehow or make extra network request. But we can pass anything through RxJava so we don't have such a problem/overhead.

I didn't touch any other parts (like replacing all Calls with Singles or getting rid of broadcasts) just yet but that's what I would like to do in some point in the future if everyone agrees.

I've also converted TimelineFragment to Kotlin because at one point it just became unreadable. Sorry about that.

This is not complete in any sense (doesn't handle boosted things e.g.), just wanted to hear your opinion on fixing some things with RxJava.

(to make it clear: in TimelineFragment I just added a couple of methods on the bottom, not much else)

@connyduck
Copy link
Collaborator

I like your initative on this <3 We definitely need something like this and might as well do it with RxJava.

Regarding your current code: when liking/boosting, notifyItemChanged(position) makes the item "flimmer" (you can see its updated), I really don't want this. (maybe its possible to tell RecyclerView to not play animation, but only updating the button is definitely preferable)

Please use Kotlin Android Extensions instead of findViewById

And can you merge master back in please?

I would really like it if you continue to work on this!

@charlag
Copy link
Collaborator Author

charlag commented Apr 16, 2018

Thanks for review! 🙇
Yes, I agree, we should be able to disable animation in this case!
Indeed
I will probably work on this in May only, but we'll see! I will definitely rebase it.
Thanks a lot!

@charlag charlag changed the title [WIP, Experimental] Add AppStore, add fav, reblog events [WIPl] Add AppStore, add fav, reblog events Apr 30, 2018
} else if (event instanceof ReblogEvent) {
handleReblogEvent((ReblogEvent) event);
}
if (event instanceof BlockEvent) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

oops, missing else here

@charlag
Copy link
Collaborator Author

charlag commented Apr 30, 2018

Something is still wrong with boosted toots, needs more love, sigh

@charlag
Copy link
Collaborator Author

charlag commented Apr 30, 2018

Updating threads after reply is buggy too.

@charlag
Copy link
Collaborator Author

charlag commented May 1, 2018

I didn't find the bug with boosts bug I've fixed things with inserting new toots in threads and only in specific timelines. I'm not sure if we should insert "load more" in profiles because it doesn't seem to work there. Otherwise it should be good.

I've spent half a day trying to make Robolectric work but I've stumbled upon couple of bugs so I give up. It doesn't worth trying to make it work until we refactor logic into separate entity.
I am not sure if it's worth making things public and test them this way at least because everything is stateful.

@charlag
Copy link
Collaborator Author

charlag commented May 2, 2018

It crashed for me when the app did unload and then i tooted

@charlag
Copy link
Collaborator Author

charlag commented May 5, 2018

Will fix #471 #280

@connyduck connyduck added this to the Tusky 1.9 milestone May 6, 2018
Copy link
Collaborator

@connyduck connyduck left a comment

Choose a reason for hiding this comment

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

This is awesome and works really well! Will continue testing.

When I post a status, it always shows a "load more" below the new status, but usually does not load anything when clicking there? It might be better to send a fetch timeline request instead of inserting the placeholder?

@@ -169,6 +170,8 @@
public MastodonApi mastodonApi;
@Inject
public AccountManager accountManager;
@Inject
Copy link
Collaborator

Choose a reason for hiding this comment

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

yes, more injecting 😎

@@ -91,6 +94,8 @@
public AccountManager accountManager;
@Inject
public DispatchingAndroidInjector<Fragment> dispatchingAndroidInjector;
@Inject
public AppStore appstore;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a better name for this? It just reminds me so much of fdroid/google play 🙈

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's a Redux/Flux terminology to name such a thing Store. Can rename to GlobalStore or something

@charlag
Copy link
Collaborator Author

charlag commented May 6, 2018

About load more: the way we do it now will make timeline move on fetch result and it's very annoying to lose your postiion in timeline when you reply to someone. Do you have any idea how to fix this?

@connyduck
Copy link
Collaborator

I think in TimelineAdapter.update we should not call notifyDataSetChanged but notifyItemRangeInserted, that should make the jumping go away?

@charlag
Copy link
Collaborator Author

charlag commented May 6, 2018

But we have to calculate what we inserted then because we may not have loaded anything?
I propose usage of hasStableIds until we migrate to DiffUtils. Need to give placesholders IDs tho.

@charlag
Copy link
Collaborator Author

charlag commented May 13, 2018

Anyway, @connyduck , if you insist we should actually refresh timeline on every post, I can try to make it work. It's kinda wasteful IMO but I see UX value in this.

@connyduck
Copy link
Collaborator

I do not think its wasteful, the UX improvement is huge.

@charlag
Copy link
Collaborator Author

charlag commented May 20, 2018

I've made some progress on it.
I ended up re-doing part of timelines stuff with DiffUtil. I also think that when I'll finish with "load more" progress it will be better than now.

@charlag
Copy link
Collaborator Author

charlag commented May 24, 2018

I've stumbled upon some super weird bug, adding spinner as the last item crashes app with inconsistency exception. Will look at it tomorrow

@charlag
Copy link
Collaborator Author

charlag commented May 25, 2018

I've figured out the crash, it was a race condition because I used AsyncListDiffer incorrectly.
Now timelines work mostly correctly (I remove "load more" spinner in the wrong place). The real problem I have is that it gets into infinite loop on short lists because I changed the way InfiniteScrollListener (or whatever it's called) was only firing callbacks when amount of items increased. It caused unpleasant things (like if one timeline fetch failed we wouldn't load the rest). Now I fire them every time but I have to track when we stumbled upon bottom. Here is some problem, it doesn't work.

Fix infinite loading. Remove spinner correctly.
Don't refresh timeline without need.
@charlag charlag changed the title [WIPl] Add AppStore, add fav, reblog events Add AppStore, add fav, reblog events May 26, 2018
@charlag charlag changed the title Add AppStore, add fav, reblog events Add EventHub, add fav, reblog events, improve timelines May 26, 2018
@charlag
Copy link
Collaborator Author

charlag commented May 26, 2018

I think that's it. It's a much bigger PR than I wanted but IMO it feels much better.
I'm mostly concerned about criteria for stopping loading things on the bottom but I didn't find a better one. It seems to work just fine.
Please check @connyduck and everyone else ❤️

@connyduck
Copy link
Collaborator

Works like a charm and code is way cleaner - really awesome work

One thing that personally bugs me with timelines is, when pulling down to refresh, it always jumps to the top instead of just scrolling down a little bit, enough to see that something new has loaded. The Twitter app does this really good. But we should probably handle this in a new pull request?

@charlag
Copy link
Collaborator Author

charlag commented May 27, 2018

Cool, thanks for the review
As discussed in a dedicated issue it is tricky to pick one option. I would love to handle this without any preferences and knobs. Probably keeping position would be the best but yeah, I think it's worth another PR, I tried to match current behavior. Keeping position is trivial, we just need to delete a couple of lines.

@connyduck
Copy link
Collaborator

ok you can merge this PR :)

@charlag
Copy link
Collaborator Author

charlag commented May 27, 2018

Okay, let's hope you tested it properly 😉

@charlag charlag merged commit 3756a1f into master May 27, 2018
@connyduck connyduck deleted the events branch July 10, 2018 17:45
nailyk-fr pushed a commit to nailyk-fr/Tusky that referenced this pull request Aug 4, 2018
* Add AppStore, add fav, reblog events

* Add events, add handling to Timeline

* Add event handling to Notifications

* Mostly finish events

* Fix unsubscribing

* Cleanup timeline

* Fix newStatusEvent in thread, fix deleteEvent

* Insert new toots only in specific timelines

* Add missing else

* Rename AppStore to EventHub

* Fix tests

* Use DiffUtils for timeline

* Fix empty timeline bug. Improve loading placeholder

* Fix AsyncListDiff, loading indicator, "load more"

* Timeline fixes & improvements.

Fix infinite loading. Remove spinner correctly.
Don't refresh timeline without need.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants