Dimillian / IceCubesApp

A SwiftUI Mastodon client
https://apps.apple.com/us/app/ice-cubes-for-mastodon/id6444915884
GNU Affero General Public License v3.0
5.31k stars 494 forks source link

Loading followers from other instances #195

Open MariaFeodora opened 1 year ago

MariaFeodora commented 1 year ago

When looking at the Following list of someone (John Gruber) with over 300 people heโ€™s following, I only get 6 results

Image

Dimillian commented 1 year ago

Unfortunately that will not be possible but I'll add a message.

fifafu commented 1 year ago

Just checking: why do you think this won't be possible? The Mona client is using these API's which are publicly accessible on each instance:

https://docs.joinmastodon.org/methods/accounts/#lookup https://docs.joinmastodon.org/methods/accounts/#following https://docs.joinmastodon.org/methods/accounts/#followers

It works great there. (Extracting the server-url from the handle, then calling these endpoints on the other instance)

Dimillian commented 1 year ago

There is a high chance it can be private and on top of that, it'll show you the followers of the user on your instance and their instance but what about the potential 10000 other instances?

fifafu commented 1 year ago

I have not encountered a single instance where it was private (if private, a message could be shown). It doesn't only show you the followers on that instance, it shows you all followers it knows about. And I think the instance must know about the follower relations for much of the functionality, so it should have all info.

Examples from my account: It's the same API that is used in the web interface: https://troet.cafe/@llo_ai/followers

https://troet.cafe/api/v1/accounts/lookup?acct=llo_ai

https://troet.cafe/api/v1/accounts/109406390169610879/followers

https://troet.cafe/api/v1/accounts/109406390169610879/followers?max_id=1611232

https://troet.cafe/api/v1/accounts/109406390169610879/following?max_id=1611232

It's only if you call this API on your instance for an account on a different instance, then your instance doesn't know much about it. But if you call it on the instance of the user you are looking at, it will usually know (and return) everything.

Dimillian commented 1 year ago

I don't understand. It's already what the app is doing? If you tap on a user followers / following. You can see the list. And on the web they added a label to tell you they don't show users from other instances.

Dimillian commented 1 year ago

Maybe I've missed something.

fifafu commented 1 year ago

Let's say I open the IceCubes app and I'm logged in with my instance (troet.cafe), and I want to see the people you (dimillian@mastodon.social) follow (or those who follow you). Currently the app only shows a handful of accounts because IceCubes does not try to load them from your instance (which would be mastodon.social), but instead it tries to load them from the instance I'm logged in with (troet.cafe).

To solve this I think it should call these endpoints on your instance (mastodon.social), even if I'm logged in with troet.cafe. (Because your instance has to know about all your followers and followings) 1.) https://mastodon.social/api/v1/accounts/lookup?acct=dimillian 2.) Use the returned account id to call https://mastodon.social/api/v1/accounts/109523208135675669/followers

These do not require authentication and they return all your followers / followings

Dimillian commented 1 year ago

Totally make sense! Will add that. It's clearly an oversight that it's not loading people from the user current instance. Thanks for explaining.

fifafu commented 1 year ago

That would be awesome and it would definitely make Ice Cubes my favorite Mastodon app ๐Ÿ‘ (currently I'm sometimes switching to Mona just for that feature, but I love the Ice Cubes UI). It's the only thing I have been missing (especially because I'm on a smaller instance)

Maybe the current implementation should still be kept as a fallback in case the other instance blocks access to these APIs.

pshadov commented 8 months ago

Hey @Dimillian ๐Ÿ‘‹๐Ÿป Is this feature request in progress? Would you mind if I took a look?

Dimillian commented 8 months ago

Feel free. Don't really know what we can do about it

fifafu commented 8 months ago

Just in case somebody wants to work on this, a concrete example of how it would need to be done:

0.) Figure out the instance the user is on - in case of @Dimillian it's mastodon.social 1.) Lookup the user id by querying the user's instance with his username: https://mastodon.social/api/v1/accounts/lookup?acct=dimillian

2.) Use the user id to call the accounts/:userid/followers endpoint

https://mastodon.social/api/v1/accounts/109523208135675669/followers?limit=80

3.) Use paging to load more:

https://mastodon.social/api/v1/accounts/109523208135675669/followers?max_id=51115796&limit=80

This API is not protected, so it can be called without any authentication. (And the user's instance has cached all his followers/followings, even if they are from other instances)

pshadov commented 8 months ago

Unfortunately, after digging deeper into the problem, I found that it is not so straightforward and requires many more changes.

To make it shorter, I will call the instance I am logged in MI (my instance) and the instance of the user I am looking at TI (target instance)

I identified 3 problems (I assume there might be more down the road):

  1. The relationships with the followed/following users. If I get the list of the users on TI, their IDs will be different there comparing to MI. For example, @Dimillian ID on mastodon.social is 109523208135675669, but on mas.to - 109523215128421330. So basically, I have a nice list of all the users from TI, but I don't know if I am already following them on MI, and I haven't found any API for the user or relationships IDs mapping;
  2. Let's imagine I press on some user from the followers list. Their ID is from TI. This means that without the mentioned IDs mapping, l cannot get all the information related to MI on their Profile screen;
  3. I haven't gone too far into the codebase yet, but it looks to me that the main business logic of how Mastodon client passed in the app is coupled to SwiftUI environments. Making the logic more friendly to multiple clients (MI and TIs) can require a lot of architectural changes that can lead to more bugs.

I will dig deeper into the codebase and MastodonAPI, as I find them very interesting overall, but so far, I cannot promise that I will the issue soon. You can find the POC with disabled relationships but working followers/following lists on the branch on my fork here.

fifafu commented 8 months ago

Yes that's true. Other clients (e.g. Mona) continue by resolving the user you want to view via /api/v2/search?resolve=true&q=dimillian%40mastodon.social&type=accounts&limit=1 (on the logged in instance) This gives the required ids for the given user handle on the logged in instance.

However this only works for point 2. Point 1 is probably hard to solve as it would require too many API calls. Other clients that offer this feature also don't show the "relationship status" for users from other instances.

Dimillian commented 8 months ago

I'm using the resolver for loading remote timelines and embedding remote statuses. But yes, it's an id by id case. No way to do it on lists of entities.