Skip to content

WIP friends widget#3156

Draft
HaonRekcef wants to merge 1 commit into
lichess-org:mainfrom
HaonRekcef:friends-widget
Draft

WIP friends widget#3156
HaonRekcef wants to merge 1 commit into
lichess-org:mainfrom
HaonRekcef:friends-widget

Conversation

@HaonRekcef
Copy link
Copy Markdown
Collaborator

@HaonRekcef HaonRekcef commented May 10, 2026

Closes #3003
To reduce the server loads this PR works as follows

  • onlineFriendsSnapshotProvider that requests the online and playing friends without listening for updates, that is called every app start and home screen refresh
  • a following cache, that is stored in a sqllite db, because of this the server has to compute the heavy rel/api/following only once a day, except if the user navigates explicitly to the FriendsScreen or the PickPlayerScreen screen.
  • As users can follow up to 400 players, and the following widget only shows up to 10, the users are sorted:
  1. Playing players
  2. Online players
  3. Players from the offline cache next, ordered by a mixture of factors (Amount of user interaction with that player, recently active, recently interacted with and some randomness)

The interactions are stored in the sqllite db locally when the player interacts with the widget.

Draft for now as I need to test it more and probably I should also write some tests.

Note: The local cache can get out of sync, if the user (un)-follows other players from a different device, however only for max 24h.

Screencast_20260510_093744.webm

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new “friends/following” home widget that prioritizes playing/online friends while reducing server load by caching the user’s following list in SQLite and refreshing it infrequently, with explicit syncs when entering Friends/Pick Player screens.

Changes:

  • Introduces a SQLite-backed following cache (cachedFollowingFriendsProvider) plus local interaction tracking to influence ordering.
  • Adds a one-shot online friends snapshot provider (onlineFriendsSnapshotProvider) and integrates the new carousel widget on the Home tab.
  • Updates follow/unfollow and player-picking flows to use/refresh the cache and register interactions.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
lib/src/view/user/user_screen.dart Optimistically updates the local following cache on follow/unfollow from the user profile screen.
lib/src/view/user/user_context_menu.dart Adjusts challenge action to pass LightUser into UserScreen.challengeUser.
lib/src/view/user/pick_player_screen.dart Forces cache sync on entry, uses cached following list, and records interactions on taps.
lib/src/view/relation/friend_screen.dart Replaces direct following fetch with cached following provider; forces sync on entry and records interactions.
lib/src/view/home/home_tab_screen.dart Adds the new home “following” editable widget and refreshes the new providers during pull-to-refresh.
lib/src/view/home/following_carousel.dart New home carousel widget that merges online snapshot + cached following and ranks users for display.
lib/src/model/relation/online_friends.dart Adds the one-shot online friends snapshot provider and shared parsing helpers.
lib/src/model/relation/following_cache.dart New cache service + async notifier managing SQLite persistence, refresh cadence, and interaction updates.
lib/src/model/account/home_widgets.dart Registers a new editable home widget entry for following/friends.
lib/src/db/database.dart Bumps DB version and creates the new following_users table.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/src/view/home/following_carousel.dart Outdated
Comment thread lib/src/view/home/following_carousel.dart Outdated
Comment thread lib/src/view/home/following_carousel.dart Outdated
Comment thread lib/src/view/user/user_screen.dart Outdated
Comment thread lib/src/model/relation/following_cache.dart Outdated
Comment thread lib/src/model/relation/following_cache.dart Outdated
Comment thread lib/src/model/relation/online_friends.dart Outdated
Comment thread lib/src/model/relation/following_cache.dart Outdated
@ijm8710
Copy link
Copy Markdown

ijm8710 commented May 10, 2026

Super duper excited about this one!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.

Comments suppressed due to low confidence (1)

lib/src/view/relation/friend_screen.dart:137

  • Interaction tracking is added for the trailing watch button, but tapping the online friend tile itself does not register an interaction, whereas the offline/following list does. If the goal is to track all widget interactions consistently, consider also calling registerInteraction() in onTap for the tile.
    return ListTile(
      title: UserFullNameWidget(user: user),
      trailing: playing
          ? IconButton(
              tooltip: context.l10n.watchGames,
              onPressed: () {
                ref.read(cachedFollowingFriendsProvider.notifier).registerInteraction(user.id);
                Navigator.of(
                  context,
                  rootNavigator: true,
                ).push(TvScreen.buildRoute(context, user: user));
              },
              icon: const Icon(Icons.live_tv),
            )
          : null,
      onTap: () => Navigator.of(context).push(UserOrProfileScreen.buildRoute(context, user)),
      onLongPress: () => showModalBottomSheet<void>(

Comment thread lib/src/view/user/user_screen.dart Outdated
Comment thread lib/src/view/user/user_screen.dart Outdated
Comment thread lib/src/model/relation/following_cache.dart Outdated
Comment thread lib/src/model/relation/following_cache.dart Outdated
Comment thread lib/src/model/relation/online_friends.dart Outdated
Comment thread lib/src/view/home/following_carousel.dart Outdated
Comment thread lib/src/view/home/following_carousel.dart Outdated
@HaonRekcef HaonRekcef force-pushed the friends-widget branch 3 times, most recently from 95bdfe5 to fe7c690 Compare May 10, 2026 20:00
@veloce
Copy link
Copy Markdown
Contributor

veloce commented May 11, 2026

This is really cool!

Some UI feedback for now:

  • the cards look too cramped: let's add some more vertical space and padding
  • the user name could be more visible, also it may be better to show the avatar (flair or initial) in a ListTile, with the user name as title and the status as subtitle (what we already have in the UserScreen app bar)
  • I like how you use the tonal variant of the button to show the hierarchy of actions
  • however, the button is too big. Its size could be reduced by a third I think, it would still be very visible; it also needs a bit more vertical padding around it.
  • may be worthwhile to have an icon in the button
  • the button would probably be better aligned on the left than central
  • we may want to use the right bottom corner to have a "Send message icon button", that could be useful too (in that case we'd use an OutlinedButton to make it less important than the FilledButton)
  • if it's not too costly to send requests to the server (there is an endpoint to get profiles by sending a list of ID) to get the offline user profiles, displaying "Active 2h ago" would be better than "Offline" as subtitle (this is low priority, I'm just listing here what comes to mind to not forget it)

@HaonRekcef
Copy link
Copy Markdown
Collaborator Author

HaonRekcef commented May 15, 2026

image

@veloce the problem is that like this we can only display 1.5 friends on a normal phone...

in a more compacted form without avatar and inbox (which I am anyways not sure we should display as it is not a friends list really but a following list, so it is not a reflective relation)
image

@ijm8710
Copy link
Copy Markdown

ijm8710 commented May 15, 2026

image

@veloce the problem is that like this we can only display 1.5 friends on a normal phone...

in a more compacted form without avatar and inbox (which I am anyways not sure we should display as it is not a friends list really but a following list, so it is not a reflective relation)

image

I am team Noah on this one. I think 2.5 is much more valuable than 1.5 and he expressed very well why messaging is less vital

I still would love the badge from here on the carousel header. They use it for total friend count but I would love it for online friend count. It's an easy way to bring attention to the widget that you have friends online similar to the old app where the top right friend icon had a badge when friends were online. To me the carousel is most valuable when friends are online which is not always the case when you only follow a few people.
image

@veloce
Copy link
Copy Markdown
Contributor

veloce commented May 19, 2026

Capture d’écran 2026-05-19 à 10 41 39

@HaonRekcef agreed, the compact form is better as we have 2.5 instead of 1.5 displayed friends.

Inbox button looked weird too I agree.

However in that screenshot I still find the button is way too big. The button is taking as much space as the whole user block. Seeing this I got the feeling that the button is trying to yell "Hiiiiit meeeee!!". The most important information here should be the user name and status, thus it should take more space and be more visible than the button. The button is already quite visible by itself being a FilledButton, so it should be small.

If that helps for this card design we could even display a bit more information about the user. For instance the website displays the ratings, the score against me, the number of games played, etc.
Note that I said we could, not we have to. I'd rather see less information than useless information here.

Last thing: the "online" not capitalised is an issue here. If Lila translations don't provide this we need to have a mobile one.

@HaonRekcef
Copy link
Copy Markdown
Collaborator Author

However in that screenshot I still find the button is way too big. The button is taking as much space as the whole user block. Seeing this I got the feeling that the button is trying to yell "Hiiiiit meeeee!!". The most important information here should be the user name and status, thus it should take more space and be more visible than the button. The button is already quite visible by itself being a FilledButton, so it should be small.

That was my intention actually, but I reduced the size:
image

If that helps for this card design we could even display a bit more information about the user. For instance the website displays the ratings, the score against me, the number of games played, etc. Note that I said we could, not we have to. I'd rather see less information than useless information here.

I think here simple is better.

Last thing: the "online" not capitalised is an issue here. If Lila translations don't provide this we need to have a mobile one.

What speaks against .capitalize()?

Also the different languages are problematic. The german translation for challenge turns it into: Zu einer Partie herausfordern . I guess we have to create a seperate translation key, asking the translators to be succinct.

@veloce
Copy link
Copy Markdown
Contributor

veloce commented May 19, 2026

What speaks against .capitalize()?

It won't work in some languages.

Also the different languages are problematic. The german translation for challenge turns it into: Zu einer Partie herausfordern . I guess we have to create a seperate translation key, asking the translators to be succinct.

Definitely.

@veloce
Copy link
Copy Markdown
Contributor

veloce commented May 19, 2026

I am still not satisfied with the button size 😅

Some user have long names. The username looks better now, but the font should be a little smaller I think.

@HaonRekcef
Copy link
Copy Markdown
Collaborator Author

Maybe switching to an outline Button would be better?

image

Another problem I noticed, is that if we want the challenge button, we have to ask the server devs to include a field for that, as players can disable that other playes can challenge them.

@veloce
Copy link
Copy Markdown
Contributor

veloce commented May 21, 2026

Another problem I noticed, is that if we want the challenge button, we have to ask the server devs to include a field for that, as players can disable that other playes can challenge them.

good catch

The button size is better now, but I preferred the filled button style to the outlined one.

@HaonRekcef
Copy link
Copy Markdown
Collaborator Author

image

So I should ask them to include the flag? Or we just add a button to the profile?

Some user have long names. The username looks better now, but the font should be a little smaller I think.

We could also make the width depend on the size of the name.

@veloce
Copy link
Copy Markdown
Contributor

veloce commented May 25, 2026

So I should ask them to include the flag? Or we just add a button to the profile?

That would be better imo. Also even if we decide later to just show the profile button we can also support a long press context menu to show more options, where challenge would definitely be useful.

We could also make the width depend on the size of the name.

No, it looks better if all cards have the same width.

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.

Optional 'friends last online' home widget carousel

4 participants