Page MenuHomePhabricator

[native] community list item component
AcceptedPublic

Authored by varun on Nov 21 2024, 9:51 AM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Dec 23, 9:34 PM
Unknown Object (File)
Sun, Dec 22, 4:49 PM
Unknown Object (File)
Sun, Dec 22, 4:18 PM
Unknown Object (File)
Sun, Dec 22, 6:39 AM
Unknown Object (File)
Sun, Dec 22, 6:39 AM
Unknown Object (File)
Sun, Dec 22, 6:39 AM
Unknown Object (File)
Sun, Dec 22, 6:39 AM
Subscribers

Details

Reviewers
ashoat
Summary

Depends on D13987

https://linear.app/comm/issue/ENG-9897/communitylistitem-component

this component will be used in the CommunityList component that I introduce next

Test Plan

tested with later diffs (not yet published) and verified that join/leave work as expected. see video

Diff Detail

Repository
rCOMM Comm
Lint
No Lint Coverage
Unit
No Test Coverage

Event Timeline

fix activityIndicator location

This comment was removed by varun.

the search bar placeholder text is in the following diff, where it is actually "Search communities" (see D13995)

ashoat requested changes to this revision.Nov 21 2024, 6:50 PM

It looks like you got a lot of this from another file. If any of my feedback here applies to the original file, can you make sure to make the changes there too?

native/components/community-list-item.react.js
44–46 ↗(On Diff #45931)

What's the point of this, as opposed to just using the ThreadInfo we're passed?

61–64 ↗(On Diff #45931)

Can these be moved closer to where they're used?

139 ↗(On Diff #45931)

I'd like to iterate a bit on the design of the button here. Some thoughts:

  1. What do you think of using PrimaryButton, or perhaps building a more compact variation of it? I think it would look sleaker to have the rounded corners, and it gives us in-progress state for free
  2. I think it might look better right-aligned
  3. I'm not sure about the colors, they seem a little too basic
This revision now requires changes to proceed.Nov 21 2024, 6:50 PM
native/components/community-list-item.react.js
44–46 ↗(On Diff #45931)

the thread info we're passed doesn't have the latest membership status or permissions for the user. this leads to bad user experiences like the leave button not displaying for communities that a user joins through the modal

native/components/community-list-item.react.js
44–46 ↗(On Diff #45931)

Okay, in that case:

  1. Let's update the component to only take the threadID instead of the whole threadInfo
  2. There are several places where you use threadInfo below instead of reduxThreadInfo. It seems like you could use reduxThreadInfo in all cases
  3. I suspect that there's a potential risk here that the thread is deauthorized (eg. user leaves the thread on a different client), the thread is removed from Redux, and then this component crashes before it's unmounted by its parent. It's worth investigating if this issue exists, and if it does, we can address in a similar way to ThreadSettings (store the threadInfo in a state, update it when Redux changes but NOT when it disappears from Redux)

It looks like you got a lot of this from another file. If any of my feedback here applies to the original file, can you make sure to make the changes there too?

The only feedback that really applies to the original file is replacing the buttons, which feels out of scope for this diff. I've created a follow-up task:
https://linear.app/comm/issue/ENG-10005/consider-using-primarybutton-in-friend-list-and-block-list

native/components/community-list-item.react.js
44–46 ↗(On Diff #45931)

I think there's some confusion here. You're suggesting using reduxThreadInfo in the following places:

const communityID = getCommunity(threadInfo);
const resolvedThreadInfo = useResolvedThreadInfo(threadInfo);

we cannot use reduxThreadInfo in either line because it's possible that it's undefined for the given community (user has not joined it yet so it's not in redux). therefore, we have to use threadInfo in both cases. threadInfo comes from the fetchAllCommunityInfosWithNames keyserver call, which returns all thread infos, including ones that the viewer is not a member of

the reason we use reduxThreadInfo at all is, we need the latest membership and permissions info for the thread. if we use threadInfo to determine canLeaveThread (line 75 below), then the leave button will never display. if we use it to determine isMember, then the join button will display for already-joined communities when the user opens the directory (unless we refetch fetchAllCommunityInfosWithNames, which would be expensive)

This should've probably been a code comment, in retrospect. I'll add a comment once this reply is acknowledged.

I think the risk you identified in point 3 is valid, even if we stick with the current approach. I'll do some testing with multiple clients now

native/components/community-list-item.react.js
44–46 ↗(On Diff #45931)

Sounds like we should just do what we're doing in ThreadSettings, which I explained above:

(store the threadInfo in a state, update it when Redux changes but NOT when it disappears from Redux)

Can you please review how that file handles things, and update this file to work the same way? Once you grok that, you should be able to:

  1. Update the component to only take the threadID instead of the whole threadInfo
  2. Update all places where you use threadInfo to instead use a non-nullable reduxThreadInfo
  3. Make sure we handle the deauthorization case correctly

Move joinStatus closer to where it's used

Simulator Screenshot - iPhone 16 Pro - 2024-12-13 at 11.29.03.png (2×1 px, 284 KB)

Latest look at the modal with the redesigned CommunityListItem component

ashoat requested changes to this revision.Fri, Dec 13, 8:29 AM

Can you share updated videos of how this looks in both dark mode and light mode?

native/components/community-list-item.react.js
53–59 ↗(On Diff #46449)

Why did you do this differently than in ThreadSettings?

  1. You don't need a new state, as far as I can tell
  2. You shouldn't need to set anything when the reduxThreadInfo is falsey
152–153 ↗(On Diff #46449)

We shouldn't pass in arrays like this that get recomputed on every render. Should be wrapped in a React.useMemo

61–64 ↗(On Diff #45931)

Looks like these weren't moved?

native/themes/colors.js
123–124 ↗(On Diff #46449)

Is this really a "primary" button? I would expect the primaryButton color to be used by PrimaryButton when variant="enabled", but that doesn't seem to be the case

This revision now requires changes to proceed.Fri, Dec 13, 8:29 AM

Also: in the screenshot you shared, the vertical padding seems uneven between top / bottom

native/components/community-list-item.react.js
53–59 ↗(On Diff #46449)
  1. isn't the new state equivalent to how we use setParams in ThreadSettings? here's the code from ThreadSettings:
React.useEffect(() => {
  if (reduxThreadInfo) {
    setParams({ threadInfo: reduxThreadInfo });
  }
}, [reduxThreadInfo, setParams]);

I've probably misunderstood something...

  1. i don't think this is true.
const isMember = useViewerIsMember(threadInfo);
const [joinStatus, setJoinStatus] = useState<
  'joined' | 'notJoined' | 'joining' | 'leaving',
>(`notJoined`);
React.useEffect(() => {
  setJoinStatus(isMember ? 'joined' : 'notJoined');
}, [isMember]);

this hook, and consequently the useEffect, won't re-run if we don't set anything when reduxThreadInfo is falsey

there's been a lot of back and forth on this, so probably best to just pair after lunch today

Talked about this offline – I was wrong in much of my assessment above. We paired after lunch, and afterwards Varun figured out a way forward to unblock the work

ashoat added inline comments.
native/themes/colors.js
122

In a separate diff, can we rename this to primaryButton, to match the new names you've introduced below?

This revision is now accepted and ready to land.Mon, Dec 23, 8:19 AM
native/themes/colors.js
122

Never mind, we talked about this and can just leave it as-is