Skip to content

Conversation

@dharit-tan
Copy link
Contributor

@dharit-tan dharit-tan commented Sep 5, 2024

Description

  • Move a bunch of the hooks/utils for chat blasts to a shared hook
  • Add ChatListBlastItem to mobile
  • Small cleanup on web ChatListBlastItem to prevent chatBlastTitle and contentTitle from wrapping

Note - ideally the contentTitle would ellipsize as it gets cut off.. some css finnagling to do there but I couldn't figure it out first-pass.

How Has This Been Tested?

mobile:
Simulator Screenshot - iPhone 15 Pro - 2024-09-05 at 17 01 36
web:
Screenshot 2024-09-05 at 5 13 55 PM

@changeset-bot
Copy link

changeset-bot bot commented Sep 5, 2024

⚠️ No Changeset found

Latest commit: 58616f1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@audius-infra
Copy link
Collaborator

Preview this change https://demo.audius.co/rt-mobile-chat-blast-item

audience,
audience_content_id: audienceContentId,
audience_content_type: audienceContentType
} = chat as ChatBlast
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is potential jank. i can't do if is_blast return null bc hooks are below, and they depend on the blast-specific fields.
i could pass the whole chat (of type ChatBlast) in but i prefer passing in the ID and selecting at the leaf?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

chatgpt has offered: = chat?.is_blast ? chat : ({} as ChatBlast)

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah it's a tricky one. There are a couple of ways to do this.

One way is to split it up into a child component where you only render the child component when the data matches the pattern you're looking for.

const BlastChat = ({chat}) => {
  return <SomeStuffUsingTheChatFields} />
}

const ChatComponent = ({chatId}) => {
  const chat = useProxySelector((state) => getChat(state, chatId), [chatId])

  return is_blast ? <BlastChat chat={chat} /> : null
}

or something like that. You can also split it into a "loader" and "display" component, where the exported component is just in charge of the hook which fetches the data, and the display component is an internal component in the module which takes in the fetched data (not optionally) and assumes it will be fully formed and have all the necessary fields. That way there isn't a bunch of casting/null-checking/etc.

The general idea is if you find yourself in a place where you want to return null before some other hooks run that depend on data that may or may not exist, then you move those hooks into a nested component and conditionally render said component based on whether the data exists.

I would caution against trying to push absolutely all data fetching down into the leaf. It's okay if the "leaf" is a series of nested "display" components that all act on pieces of a single piece of data that's fetched at a relatively low point.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this would solve my problems. i can pass the chat object in its entirety and guarantee that it will be a ChatBlast. perhaps i am over-eager in selecting at leaf.

} = chat as ChatBlast

const decodedContentId = audienceContentId
? decodeHashId(audienceContentId) ?? undefined
Copy link
Contributor Author

@dharit-tan dharit-tan Sep 6, 2024

Choose a reason for hiding this comment

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

this is also weird - decodeHashId could return null but i want decodedContentId to only be number | undefined

Copy link
Contributor

Choose a reason for hiding this comment

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

If you wanted a slightly cleaner version, you could write the inverse of the OptionalId zod schema: the OptionalHashId. The idea being that you could then do OptionalHashId.parse(audienceContentId) and it will either give you a number or undefined.

However, I would also say that this field should already be parsed before we get here. The pattern being established in SDK migration is that if you need to transform something that comes back from the API, you use an adapter on the value right after its fetched. And that adapter will decode all the ids for you.

As an example: https://github.com/AudiusProject/audius-protocol/blob/885479a84034590e0781b1aee1cb4590ce652cf3/packages/common/src/adapters/favorite.ts#L8

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah nice.. i will see if we can do this.

{
playlistId: decodedContentId!
},
{ disabled: !audienceContentId || audienceContentType !== 'album' }
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this not be !decodedContentId? Since that's the argument you're passing above...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hm actually i think it doesn't matter bc decodedContentId comes from audienceContentId.. but i guess it's cleaner

} = chat as ChatBlast

const decodedContentId = audienceContentId
? decodeHashId(audienceContentId) ?? undefined
Copy link
Contributor

Choose a reason for hiding this comment

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

If you wanted a slightly cleaner version, you could write the inverse of the OptionalId zod schema: the OptionalHashId. The idea being that you could then do OptionalHashId.parse(audienceContentId) and it will either give you a number or undefined.

However, I would also say that this field should already be parsed before we get here. The pattern being established in SDK migration is that if you need to transform something that comes back from the API, you use an adapter on the value right after its fetched. And that adapter will decode all the ids for you.

As an example: https://github.com/AudiusProject/audius-protocol/blob/885479a84034590e0781b1aee1cb4590ce652cf3/packages/common/src/adapters/favorite.ts#L8

audience,
audience_content_id: audienceContentId,
audience_content_type: audienceContentType
} = chat as ChatBlast
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah it's a tricky one. There are a couple of ways to do this.

One way is to split it up into a child component where you only render the child component when the data matches the pattern you're looking for.

const BlastChat = ({chat}) => {
  return <SomeStuffUsingTheChatFields} />
}

const ChatComponent = ({chatId}) => {
  const chat = useProxySelector((state) => getChat(state, chatId), [chatId])

  return is_blast ? <BlastChat chat={chat} /> : null
}

or something like that. You can also split it into a "loader" and "display" component, where the exported component is just in charge of the hook which fetches the data, and the display component is an internal component in the module which takes in the fetched data (not optionally) and assumes it will be fully formed and have all the necessary fields. That way there isn't a bunch of casting/null-checking/etc.

The general idea is if you find yourself in a place where you want to return null before some other hooks run that depend on data that may or may not exist, then you move those hooks into a nested component and conditionally render said component based on whether the data exists.

I would caution against trying to push absolutely all data fetching down into the leaf. It's okay if the "leaf" is a series of nested "display" components that all act on pieces of a single piece of data that's fetched at a relatively low point.

Copy link
Contributor

@amendelsohn amendelsohn left a comment

Choose a reason for hiding this comment

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

Awesome!

Comment on lines +46 to +47
width={spacing.xl}
height={spacing.xl}
Copy link
Contributor

Choose a reason for hiding this comment

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

isn't there a size prop?
maybe not for mobile?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

seems like no :(

Comment on lines +25 to +27
useChatBlastAudienceContent({
chat
})
Copy link
Contributor

Choose a reason for hiding this comment

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

love this change!
can reuse the hook for web too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep! slots in nicely

@audius-infra
Copy link
Collaborator

Preview this change https://demo.audius.co/rt-mobile-chat-blast-item

@dharit-tan dharit-tan merged commit 34d5a5a into main Sep 6, 2024
@dharit-tan dharit-tan deleted the rt-mobile-chat-blast-item branch September 6, 2024 21:11
audius-infra pushed a commit that referenced this pull request Sep 7, 2024
[34d5a5a] [PAY-3213] ChatListBlastItem mobile UI (#9656) Reed
[518f4d8] fix typecheck on main (#9669) Andrew Mendelsohn
[f183d96] fix type for spl_usdc_payout_wallet on user adapter (#9667) Randy Schott
[dab6070] [QA-1528] Move audius-query force ref tracking to useState (#9661) Andrew Mendelsohn
[d9022cb] fix typecheck in ChatBlastSelectAudienceFields (#9668) Andrew Mendelsohn
[cdb428a] [QA-1529] Add guard for -1 ids to audius-query api hooks (#9647) Andrew Mendelsohn
[ec1dd85] [QA-1542] Fix mobile top supporters crashing profile page (#9646) Andrew Mendelsohn
[7f49a62] [PAY-3416] Adds v1 account endpoint (#9651) Randy Schott
[807d569] [C-5009] Add debug theme (#9611) Dylan Jeffers
[9f75690] [C-5005] Add comment counts (#9630) Dylan Jeffers
[dc74998] [C-4872, C-4993, QA-1538] Add ComposerInput component and update comments and DMs to user the input (#9638) Kyle Shanks
[2bec1f2] [PAY-3420] Update styles on checkout UI (#9649) Raymond Jacobson
[d90eeac] [QA-1545] Fix cover art size on album search results (#9654) Raymond Jacobson
[842a762] Set audienceContentType=track for remix chat blasts (#9655) Reed
[0e6b44e] [C-4975] Comments pagination (#9633) JD Francis
[85fe0e7] Display audience counts in chat blast items (#9640) Reed
[8236a47] [PAY-3401] Consolidate pay with anything tx (#9645) Raymond Jacobson
[f897d8f] [PAY-3411] Enable monetization for everyone when network cut is enabled (#9644) Marcus Pasell
[0902048] Add stems api for v1 (#9513) Raymond Jacobson
[d04bf16] [C-4956] Add mobile comments sort ui (#9637) Sebastian Klingler
[b915249] Fix purchasers count in chat blast modal (#9639) Reed
[adf2207] [PAY-3370] Always use encoded content IDs in chats (#9636) Reed
[53fe54e] [PAY-3388] Migrate feed to SDK (#9593) Randy Schott
[59435ae] Show content title in chat blast item (#9627) Reed
[824fc47] [C-4752] Reduce border width for small Avatar (#9612) Dylan Jeffers
[fa9b498] [C-4952] Mobile comment overflow action confirmations (#9622) Sebastian Klingler
[065e8b8] [PAY-3408][PAY-3409][PAY-3408][PAY-3405][PAY-3413] Update Sales/Purchase Modal (#9624) Marcus Pasell
[04f810a] [PAY-3404] Fix floor() for negative numbers that are already floored (#9623) Marcus Pasell
[fdc7cf3] Fix purchasing without network split (#9629) Marcus Pasell
[682e7d4] [PAY-3410][PAY-3406] Update Sales Table help link and "Value" => "Total" (#9625) Marcus Pasell
[2e621bb] [QA-1439] Don't block gated tracks from being remixes (#9620) Andrew Mendelsohn
[cb753b3] [C-5008] Add single and multi lineHeight options to Text (#9610) Dylan Jeffers
[11911da] [PAY-3378] Disable blast audiences radios with no recipients (#9619) Reed
[826d3ae] Only add blasts to store for sender (#9617) Reed
[661cca7] [PAY-3206] Populate content targeting dropdowns for blast modal (web) (#9601) Andrew Mendelsohn
[f365f01] Add support for expand rounding mode to FixedDecimal (#9606) Marcus Pasell
[d6344cb] Fix web external-text-link style propagation (#9609) Dylan Jeffers
[90b3b41] [PAY-3324] Add copy notice around network take rate (#9608) Marcus Pasell
[d876547] Release mobile apps to 113 (#9614) Dylan Jeffers
[e9091d8] [C-5001] Add comment disabling for tracks (#9594) Dylan Jeffers
[66b1e99] Fix broken common tests (#9605) Marcus Pasell
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants