Invite friends: fix web dead buttons/links, harden scanner, dedupe utils

Addresses code-review findings on the invite-friends feature:
- Gate the profile-header share button and followers promo banner to
  native; the invite dialog is a no-op on web, so these were dead buttons.
- Show the real canonical profile URL in the invite-link field so the
  displayed text matches what Copy/Share/QR actually use.
- Add a web fallback for the QR scanner screen (route is registered on
  all platforms) and remove the unimplemented gallery picker button.
- Reuse shared hexToRgb/rgbToHex from alf/util/colorGeneration in ThemedQrCard.
- Rebuild ThemePicker on the shared Menu component instead of a hand-rolled
  Modal dropdown.
- Fix an import-sort lint error in dialogs/nuxs/index.
This commit is contained in:
vineyardbovines
2026-06-01 12:43:22 -04:00
parent 5b4d7fa175
commit 7e6198edb2
10 changed files with 170 additions and 216 deletions
@@ -39,7 +39,7 @@ import * as Prompt from '#/components/Prompt'
import {RichText} from '#/components/RichText'
import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
import {IS_IOS} from '#/env'
import {IS_IOS, IS_NATIVE} from '#/env'
import {InviteFriendsDialog} from '#/features/inviteFriends'
import {useActorStatus} from '#/features/liveNow'
import {GermButton} from '../components/GermButton'
@@ -350,20 +350,24 @@ export function HeaderStandardButtons({
<Trans>Edit Profile</Trans>
</ButtonText>
</Button>
<Button
testID="profileHeaderShareButton"
size="small"
color="secondary"
shape="round"
onPress={() => {
playHaptic('Light')
inviteFriendsControl.open()
}}
label={_(msg`Invite friends`)}>
<ButtonIcon icon={ArrowShareRight} />
</Button>
{/* Invite friends is a native-only share sheet (the dialog is a
no-op on web), so gate the entry point to avoid a dead button. */}
{IS_NATIVE && (
<Button
testID="profileHeaderShareButton"
size="small"
color="secondary"
shape="round"
onPress={() => {
playHaptic('Light')
inviteFriendsControl.open()
}}
label={_(msg`Invite friends`)}>
<ButtonIcon icon={ArrowShareRight} />
</Button>
)}
<EditProfileDialog profile={profile} control={editProfileControl} />
<InviteFriendsDialog control={inviteFriendsControl} />
{IS_NATIVE && <InviteFriendsDialog control={inviteFriendsControl} />}
</>
) : profile.viewer?.blocking ? (
profile.viewer?.blockingByList ? null : (