+48
-41
src/pages/Results.tsx
+48
-41
src/pages/Results.tsx
···
1
-
import { Sparkles, Heart } from "lucide-react";
1
+
import { Sparkles } from "lucide-react";
2
+
import { useMemo } from "react";
2
3
import { PLATFORMS } from "../constants/platforms";
3
4
import { ATPROTO_APPS } from "../constants/atprotoApps";
4
5
import AppHeader from "../components/AppHeader";
···
77
78
const PlatformIcon = platform.icon;
78
79
const destinationApp = ATPROTO_APPS[destinationAppId];
79
80
81
+
// Memoize sorted results to avoid re-sorting on every render
82
+
const sortedResults = useMemo(() => {
83
+
return [...searchResults].sort((a, b) => {
84
+
// 1. Users with matches first
85
+
const aHasMatches = a.atprotoMatches.length > 0 ? 0 : 1;
86
+
const bHasMatches = b.atprotoMatches.length > 0 ? 0 : 1;
87
+
if (aHasMatches !== bHasMatches) return aHasMatches - bHasMatches;
88
+
89
+
// 2. For matched users, sort by highest posts count of their top match
90
+
if (a.atprotoMatches.length > 0 && b.atprotoMatches.length > 0) {
91
+
const aTopPosts = a.atprotoMatches[0]?.postCount || 0;
92
+
const bTopPosts = b.atprotoMatches[0]?.postCount || 0;
93
+
if (aTopPosts !== bTopPosts) return bTopPosts - aTopPosts;
94
+
95
+
// 3. Then by followers count
96
+
const aTopFollowers = a.atprotoMatches[0]?.followerCount || 0;
97
+
const bTopFollowers = b.atprotoMatches[0]?.followerCount || 0;
98
+
if (aTopFollowers !== bTopFollowers)
99
+
return bTopFollowers - aTopFollowers;
100
+
}
101
+
102
+
// 4. Username as tiebreaker
103
+
return a.sourceUser.username.localeCompare(b.sourceUser.username);
104
+
});
105
+
}, [searchResults]);
106
+
80
107
return (
81
108
<div className="min-h-screen pb-24">
82
109
<AppHeader
···
155
182
156
183
{/* Feed Results */}
157
184
<div className="max-w-3xl mx-auto px-4 py-4 space-y-4">
158
-
{[...searchResults]
159
-
.sort((a, b) => {
160
-
// Sort logic here, match sortSearchResults function
161
-
const aHasMatches = a.atprotoMatches.length > 0 ? 0 : 1;
162
-
const bHasMatches = b.atprotoMatches.length > 0 ? 0 : 1;
163
-
if (aHasMatches !== bHasMatches) return aHasMatches - bHasMatches;
164
-
165
-
if (a.atprotoMatches.length > 0 && b.atprotoMatches.length > 0) {
166
-
const aTopPosts = a.atprotoMatches[0]?.postCount || 0;
167
-
const bTopPosts = b.atprotoMatches[0]?.postCount || 0;
168
-
if (aTopPosts !== bTopPosts) return bTopPosts - aTopPosts;
169
-
170
-
const aTopFollowers = a.atprotoMatches[0]?.followerCount || 0;
171
-
const bTopFollowers = b.atprotoMatches[0]?.followerCount || 0;
172
-
if (aTopFollowers !== bTopFollowers)
173
-
return bTopFollowers - aTopFollowers;
174
-
}
175
-
176
-
return a.sourceUser.username.localeCompare(b.sourceUser.username);
177
-
})
178
-
.map((result, idx) => {
179
-
// Find the original index in unsorted array
180
-
const originalIndex = searchResults.findIndex(
181
-
(r) => r.sourceUser.username === result.sourceUser.username,
182
-
);
183
-
return (
184
-
<SearchResultCard
185
-
key={originalIndex}
186
-
result={result}
187
-
resultIndex={originalIndex} // Use original index for state updates
188
-
isExpanded={expandedResults.has(originalIndex)}
189
-
onToggleExpand={() => onToggleExpand(originalIndex)}
190
-
onToggleMatchSelection={(did) =>
191
-
onToggleMatchSelection(originalIndex, did)
192
-
}
193
-
sourcePlatform={sourcePlatform}
194
-
destinationAppId={destinationAppId}
195
-
/>
196
-
);
197
-
})}
185
+
{sortedResults.map((result) => {
186
+
// Find the original index in unsorted array for state updates
187
+
const originalIndex = searchResults.findIndex(
188
+
(r) => r.sourceUser.username === result.sourceUser.username,
189
+
);
190
+
return (
191
+
<SearchResultCard
192
+
key={originalIndex}
193
+
result={result}
194
+
resultIndex={originalIndex}
195
+
isExpanded={expandedResults.has(originalIndex)}
196
+
onToggleExpand={() => onToggleExpand(originalIndex)}
197
+
onToggleMatchSelection={(did) =>
198
+
onToggleMatchSelection(originalIndex, did)
199
+
}
200
+
sourcePlatform={sourcePlatform}
201
+
destinationAppId={destinationAppId}
202
+
/>
203
+
);
204
+
})}
198
205
</div>
199
206
200
207
{/* Fixed Bottom Action Bar */}