-
Notifications
You must be signed in to change notification settings - Fork 1
Merge/copilot push now into main #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -196,9 +196,9 @@ | |||||
| const [savedAddresses, setSavedAddresses] = useState<Array<{ id: string; name: string; address: string }>>([]); | ||||||
|
|
||||||
| // Favorites & filters | ||||||
| const [favoriteIds, setFavoriteIds] = useState<Set<number>>(new Set()); | ||||||
| const [dietaryFilter, setDietaryFilter] = useState<string>("All"); | ||||||
|
Check warning on line 200 in app/page.tsx
|
||||||
| const [showFavoritesOnly, setShowFavoritesOnly] = useState(false); | ||||||
|
Check warning on line 201 in app/page.tsx
|
||||||
|
|
||||||
| // Chat | ||||||
| const [chatMessages, setChatMessages] = useState<ChatMessage[]>([ | ||||||
|
|
@@ -211,7 +211,9 @@ | |||||
| const [chatInput, setChatInput] = useState(""); | ||||||
| const [chatLoading, setChatLoading] = useState(false); | ||||||
| const [statusMessage, setStatusMessage] = useState<string | null>(null); | ||||||
| const messagesEndRef = useRef<HTMLDivElement>(null); | ||||||
| const contentScrollRef = useRef<HTMLDivElement>(null); | ||||||
| const chatSectionRef = useRef<HTMLHeadingElement>(null); | ||||||
| const chatScrollRef = useRef<HTMLDivElement>(null); | ||||||
|
|
||||||
| // ─── Load from localStorage ─────────────────────────────────────────────── | ||||||
|
|
||||||
|
|
@@ -243,10 +245,12 @@ | |||||
| }); | ||||||
| }, [aiView, selectedRestaurantId, restaurants]); | ||||||
|
|
||||||
| // ─── Auto-scroll chat ───────────────────────────────────────────────────── | ||||||
| // ─── Auto-scroll chat container only ───────────────────────────────────── | ||||||
|
|
||||||
| useEffect(() => { | ||||||
| messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); | ||||||
| const el = chatScrollRef.current; | ||||||
| if (!el) return; | ||||||
| el.scrollTo({ top: el.scrollHeight, behavior: "smooth" }); | ||||||
| }, [chatMessages]); | ||||||
|
|
||||||
| // ─── Fetch restaurants ──────────────────────────────────────────────────── | ||||||
|
|
@@ -329,6 +333,9 @@ | |||||
| ); | ||||||
| const deliveryFee = items.length > 0 ? (selectedRestaurant?.deliveryFee ?? 0) : 0; | ||||||
| const orderTotal = Math.max(0, totalPrice + deliveryFee + tip - promoDiscount); | ||||||
| const restaurantGridClass = isOpen | ||||||
| ? "grid gap-4 sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4" | ||||||
| : "grid gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5"; | ||||||
|
|
||||||
| // ─── Saved meals ────────────────────────────────────────────────────────── | ||||||
|
|
||||||
|
|
@@ -354,7 +361,7 @@ | |||||
|
|
||||||
| // ─── Favorites ──────────────────────────────────────────────────────────── | ||||||
|
|
||||||
| const toggleFavorite = (rId: number) => { | ||||||
| setFavoriteIds((prev) => { | ||||||
| const next = new Set(prev); | ||||||
| if (next.has(rId)) next.delete(rId); | ||||||
|
|
@@ -436,6 +443,17 @@ | |||||
| ]); | ||||||
| }; | ||||||
|
|
||||||
| const scrollToChatSection = () => { | ||||||
| const container = contentScrollRef.current; | ||||||
| const target = chatSectionRef.current; | ||||||
| if (!container || !target) return; | ||||||
|
|
||||||
| const containerRect = container.getBoundingClientRect(); | ||||||
| const targetRect = target.getBoundingClientRect(); | ||||||
| const top = targetRect.top - containerRect.top + container.scrollTop - 12; | ||||||
| container.scrollTo({ top: Math.max(top, 0), behavior: "smooth" }); | ||||||
| }; | ||||||
|
|
||||||
| const handleSendMessage = async (presetText?: string) => { | ||||||
| const text = (presetText ?? chatInput).trim(); | ||||||
| if (!text || chatLoading) return; | ||||||
|
|
@@ -444,8 +462,13 @@ | |||||
| setChatInput(""); | ||||||
| setChatLoading(true); | ||||||
| setStatusMessage(null); | ||||||
| // Switch back to chat view when user sends a message | ||||||
| // Keep current panel selections while sending a message | ||||||
|
||||||
| // Keep current panel selections while sending a message | |
| // Close any open sidebar panel while sending a message |
Copilot
AI
Apr 14, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The nested requestAnimationFrame calls make the scroll timing hard to reason about and maintain. Consider using a single scheduling mechanism (e.g., one requestAnimationFrame, or triggering the scroll in an effect that runs after sidebarView becomes "none") and add a brief comment explaining why the extra frame is needed if you keep it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scrollToChatSectionuses a hard-coded- 12offset when computing the scroll target. Please replace this magic number with a named constant and/or derive it from layout (e.g., container padding / desired spacing) so future style changes don’t silently break scroll positioning.