Skip to content

Swiping! - #116

Merged
clementroze merged 11 commits into
mainfrom
clement-swipiing-v1-proto
Apr 26, 2026
Merged

Swiping!#116
clementroze merged 11 commits into
mainfrom
clement-swipiing-v1-proto

Conversation

@clementroze

@clementroze clementroze commented Mar 11, 2026

Copy link
Copy Markdown
Collaborator

Changes:

  • Replaced “Matches” tab with “Home” and updated icons.
  • Added FilledHomeIcon component.
  • Updated _layout.tsx and index.tsx for tab navigation.
  • Added mock and UI card data for daily feed (CardContent, CardSheetContent, CardStack, cardTypes, mockCards).

Features

  • Daily feed cards: profile actions, preferences, mock matches, weekly prompts, tutorials.
  • Animated cards
  • DEBUG Reset tour button (to be removed, but just to simualte the tutorial)
  • Filters for choosing what kind of cards to show in the stack

Details

Swiping a card

Screen.Recording.2026-04-08.at.1.45.47.AM.mov

Opening a sheet from the card

Screen.Recording.2026-04-08.at.1.46.02.AM.mov

Done state

Screen.Recording.2026-04-08.at.1.46.23.AM.mov

Tour/tutorial

Screen.Recording.2026-04-08.at.1.46.45.AM.mov

FIlter menu

Screen.Recording.2026-04-08.at.1.48.41.AM.mov

@netlify

netlify Bot commented Mar 11, 2026

Copy link
Copy Markdown

Deploy Preview for redi-love ready!

Name Link
🔨 Latest commit fa42e33
🔍 Latest deploy log https://app.netlify.com/projects/redi-love/deploys/69ea87a967b8cf0008b63a5c
😎 Deploy Preview https://deploy-preview-116--redi-love.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@clementroze
clementroze marked this pull request as draft March 11, 2026 01:15
@clementroze
clementroze requested a review from abrar-amin April 8, 2026 04:30
@clementroze
clementroze marked this pull request as ready for review April 8, 2026 04:30
@clementroze
clementroze requested a review from glopes2023 April 8, 2026 05:49

@clementroze clementroze left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Hello! note to my reviewers - lots of this was Claude-generated since im just a lil designer dabbling in frontend, but its the result of me carefully prompting my pet LLM and feeding it enough information for it to achieve the vision i had (trust trust guys)

Comment on lines +60 to +61
const TUTORIAL_CARDS: TutorialCard[] = [
{

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

these are the first yellow tutorial cards that a user sees to learn how the system works

it includes the 3 core actions: swiping to dismiss, tapping the card to open the sheet, and opening the filters menu

Comment on lines +156 to +160
useEffect(() => {
AsyncStorage.getItem(TOUR_STORAGE_KEY).then((val: string | null) => {
setTourSeen(val === 'true');
});
}, []);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

tour should only show once

Comment on lines +379 to +384
<AppText
variant="bodySmall"
style={{ color: AppColors.foregroundDimmer }}
>
RESET TOUR
</AppText>

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Temporary button just for debugging tour

Comment on lines -377 to -383
return (
<View
key={`${matchProfile.netid}-${m.promptId ?? matchIndex}`}
style={{
width: width - 60,
marginRight: 12,
}}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

All this was the old UI which we are revamping

style={[
styles.blob,
{
width: 180,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

in the future we might want to make these decoration dots random position but for this MVP version i think we can just do this for now

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I agree

Comment on lines +72 to +77
// Architecture: instead of rotating the cards array (which causes cards to
// jump between DOM slots, producing flashes), we keep cards fixed in the array
// and track the current "top" index. Each card slot has its own z-index driven
// by its distance from the top. The top card flies out, and only AFTER it has
// fully left the screen do we advance the index — with everything already in
// the correct visual position so no flash is possible.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

FYI this entire part i admittedly had not much invovlement with as i had mr claude do it (the swiping, stack mechanis, shadowing, animation/morphing into the sheet, etc.)

So i just made sure to prompt Claude into making something that looked like the mocks and that felt nice to use. And i made sure to test it plenty

Comment on lines +190 to +194
const doSubmit = useCallback(() => {
// 1. Close the sheet immediately (no spring — just hide it).
expandProgress.setValue(0);
setIsExpanded(false);
setCardRect(null);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

this is for the "Done" submission screen -

Image

Comment on lines +366 to +373
const overlayTop = expandProgress.interpolate({ inputRange: [0, 1], outputRange: [cr.y, SHEET_TOP] });
const overlayLeft = expandProgress.interpolate({ inputRange: [0, 1], outputRange: [cr.x, SHEET_MARGIN] });
const overlayRight = expandProgress.interpolate({ inputRange: [0, 1], outputRange: [width - cr.x - cr.w, SHEET_MARGIN] });
const overlayHeight = expandProgress.interpolate({ inputRange: [0, 1], outputRange: [cr.h, SHEET_HEIGHT] });
const backdropOpacity = expandProgress.interpolate({ inputRange: [0, 1], outputRange: [0, 0.5] });
const cardContentOpacity = expandProgress.interpolate({ inputRange: [0, 0.3, 0.5], outputRange: [1, 1, 0], extrapolate: 'clamp' });
const sheetContentOpacity = expandProgress.interpolate({ inputRange: [0.45, 0.75, 1], outputRange: [0, 0, 1], extrapolate: 'clamp' });
const overlayBorderBottomRadius = expandProgress.interpolate({ inputRange: [0, 1], outputRange: [24, 48] });

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

lol this downward curving slope caused by the syntax highlighting is visually quite nice :)


return (
<View style={styles.skipOuter}>
<Animated.View style={[styles.skipFill, styles.skipFillLeft, { transform: [{ translateX: leftTranslateX }, { translateY: fillTranslateY }] }]} pointerEvents="none" />

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

i think one little bug that i've been trying to deal with is that there's a noticeable flash each time you swipe a card to dismiss it for later. it's minor enough to not be catastrophic but i'm still trying to figure out how to fix it 😭

@@ -0,0 +1,230 @@
/**

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

all this is TBD test placeholder data, but here's how i imagine it would look like to edit the stack manually. But ofc ideally all the cards are automatically populated.

@glopes2023

Copy link
Copy Markdown
Collaborator

For the match cards, what did we have in mind to complete the action (Say you open the profile and like / dislike it and want to move forward / discard)? I was able to test the functionality with my account but there isn't a way to resolve it.

This is what I have rn (Was able to hook it up to the backend)

Screen.Recording.2026-04-15.at.6.02.16.PM.mov

@clementroze

Copy link
Copy Markdown
Collaborator Author

For the match cards, what did we have in mind to complete the action (Say you open the profile and like / dislike it and want to move forward / discard)? I was able to test the functionality with my account but there isn't a way to resolve it.

This is what I have rn (Was able to hook it up to the backend)

Screen.Recording.2026-04-15.at.6.02.16.PM.mov

@glopes2023 i think for profiles, there shoudln't be a way to "complete" it? Since match cards are slightly different. Maybe they should always stay in the stack jsut because theyre special. THe "View full profile" functionality you showed in the video looks good though!

@glopes2023

Copy link
Copy Markdown
Collaborator

For the match cards, what did we have in mind to complete the action (Say you open the profile and like / dislike it and want to move forward / discard)? I was able to test the functionality with my account but there isn't a way to resolve it.
This is what I have rn (Was able to hook it up to the backend)
Screen.Recording.2026-04-15.at.6.02.16.PM.mov

@glopes2023 i think for profiles, there shoudln't be a way to "complete" it? Since match cards are slightly different. Maybe they should always stay in the stack jsut because theyre special. THe "View full profile" functionality you showed in the video looks good though!

Should we at least re-integrate the nudge functionality we originally had in place? i.e. adding a button to send a nudge to so users can interact with their match

@clementroze

Copy link
Copy Markdown
Collaborator Author

Should we at least re-integrate the nudge functionality we originally had in place? i.e. adding a button to send a nudge to so users can interact with their match

@glopes2023 yes! that should still be there

i think we coud add a 3rd button here that says Nudge
Screenshot 2026-04-16 at 3 06 21 PM

it should also appear here (we already have the full profile page built out so we can just use that):
Screenshot 2026-04-16 at 3 06 45 PM

@glopes2023

Copy link
Copy Markdown
Collaborator

Summary

frontend/app/components/ui/CardSheetContent.tsx, frontend/app/components/ui/cardTypes.ts, frontend/app/(auth)/(tabs)/index.tsx, frontend/app/components/ui/UserOptionsSheet.tsx

  • Wired revealMatch API call when a user opens a match's full profile, marking the match as seen in Firestore
  • Added "Express interest" nudge button to the profile modal footer: locks after tap, shows "Open chat" button if the nudge is mutual
  • Added UserOptionsSheet component (report/block) accessible via a MoreVertical button in the profile modal header
  • Threaded matchPromptId, matchIndex, matchNetid, and nudgeStatus through the card data pipeline so the sheet has everything it needs

Test Plan

Seeded a test match between gl532 and sona using backend/scripts/seed-test-match.ts
Signed in as both accounts and verified the full flow: card appears → view profile → revealed flips in Firestore → express interest → nudges doc created → mutual nudge → chatUnlocked flips → conversation created
(Didn't commit the test scripts to keep the PR light)

See demo below:
https://github.com/user-attachments/assets/291a8cc6-4704-47c4-895f-b8ee63b5ec63

Notes:

I was between having the back button up on the top left or on the bottom with the rest of the interaction buttons in the profile. Please lmk what would be preferred.

@clementroze

Copy link
Copy Markdown
Collaborator Author

thank you @glopes2023 ! Check out the video and interactions look great, just three lil nits:

  • Is this ripple effect on this button new? I think we should use the regular Button component like throughout the rest of the app without the effect. Happy to explore new visual styles for the button but maybe lets explore that in a different PR?
Screenshot 2026-04-20 at 3 44 52 PM
  • also i noticed when you message someoen, the card swipes done. I think we dont need this behavior, the card should stay where it is without completing itself?
Screenshot 2026-04-20 at 3 45 54 PM
  • i dont think we need the "Pass" button bc this isn't like Tinder where you "reject" a match. I think the left arrow to go back is enough. Plus, removing "Pass" will fix that overflow issue. Also another nit but i think "interest sent" should be "Nudged!" with the smile icon (kinda like how it currently is in the app)
Screenshot 2026-04-20 at 3 46 25 PM

@glopes2023

Copy link
Copy Markdown
Collaborator

thank you @glopes2023 ! Check out the video and interactions look great, just three lil nits:

  • Is this ripple effect on this button new? I think we should use the regular Button component like throughout the rest of the app without the effect. Happy to explore new visual styles for the button but maybe lets explore that in a different PR?

I didn't change anything about that component, and it looks to be the same for all other buttons of its kind in my version of the app.

Aside from this, I made all the adjustments requested.

@clementroze
clementroze requested a review from nadia-choop April 23, 2026 02:07
@sonarqubecloud

Copy link
Copy Markdown

@abrar-amin abrar-amin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Overall looks pretty sick! I want to mess around with the animations a bit more, but that can be a new PR. I have tested the feature on my end, and fixed a few things, and it seems to work.

To the moon!

clearMatchCache,
getCachedMatchData,
} from '@/app/utils/matchCache';
MOCK_MATCH_CARDS,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We shouldn't have mock data in the final app

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

yupp these were just for testing

const [currentMatches, setCurrentMatches] = useState<MatchWithProfile[]>([]);
// ── TEMPORARY PLACEHOLDER ────────────────────────────────────────────────────
// Seeds match cards from existing chat conversations so the card stack isn't
// empty during development. Remove once the real match pipeline is wired up.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This should be removed

// ── TEMPORARY PLACEHOLDER ───────────────────────────────────────────────
// Builds match cards from existing chat conversations for dev/testing.
// Remove this block once the real weekly-match pipeline populates the feed.
try {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Once again, shouldn't have this here it hink

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

i think we keep it for now cuz we're not done, see here for context

};

const [animationTrigger, setAnimationTrigger] = useState(0);
// Build the daily card list: interleave mock cards with real match cards

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why interleave mock and real cards

<Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
{/* House body */}
<Path
d="M15 13.0005V21.0005H19C19.5304 21.0005 20.0391 20.7898 20.4142 20.4147C20.7893 20.0396 21 19.5309 21 19.0005V10.0005C21.0001 9.70955 20.9367 9.4221 20.8142 9.1582C20.6918 8.89429 20.5132 8.66028 20.291 8.47248L13.291 2.47248C12.93 2.16739 12.4726 2 12 2C11.5274 2 11.07 2.16739 10.709 2.47248L3.709 8.47248C3.4868 8.66028 3.30824 8.89429 3.18579 9.1582C3.06333 9.4221 2.99993 9.70955 3 10.0005V19.0005C3 19.5309 3.21071 20.0396 3.58579 20.4147C3.96086 20.7898 4.46957 21.0005 5 21.0005H9V13.0005C9 12.7353 9.10536 12.4809 9.29289 12.2934C9.48043 12.1058 9.73478 12.0005 10 12.0005H14C14.2652 12.0005 14.5196 12.1058 14.7071 12.2934C14.8946 12.4809 15 12.7353 15 13.0005Z"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Sus

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

this is just the home icon on the navbar

style={[
styles.blob,
{
width: 180,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I agree

@clementroze
clementroze merged commit f108e26 into main Apr 26, 2026
11 checks passed
@clementroze
clementroze deleted the clement-swipiing-v1-proto branch April 26, 2026 04:49
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.

3 participants