feat(mobile): compare table scroll fade and native share sheet
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 12s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 48s
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 12s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 48s
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 14s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
MOB-14: PerformanceChart and ComparisonChart both already configure legend position 'top' — no change needed. MOB-15: Compare's detailedTable is 774px wide inside an overflow-x: auto wrapper. Add a right-edge mask-image fade at ≤640px so phone users see the table extends past the viewport. MOB-16: ComparisonView's Share button previously did clipboard-only. Prefer navigator.share when available (iOS/Android native sheet) so users can send straight to Messages / WhatsApp / Mail / etc. Fall back to clipboard with the existing "Copied!" toast otherwise. User cancellations swallow silently; only real errors trigger fallback. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -157,8 +157,29 @@ export function ComparisonView({
|
||||
};
|
||||
|
||||
const handleShare = async () => {
|
||||
const url = window.location.href;
|
||||
const count = selectedSchools.length;
|
||||
const shareData = {
|
||||
title: 'School comparison · SchoolCompare',
|
||||
text: count > 0
|
||||
? `Comparing ${count} school${count === 1 ? '' : 's'} on SchoolCompare`
|
||||
: 'SchoolCompare',
|
||||
url,
|
||||
};
|
||||
// Prefer the native share sheet on platforms that support it (iOS / Android).
|
||||
// canShare is feature-detected because Safari iOS exposes share() but
|
||||
// some configurations refuse the payload.
|
||||
if (typeof navigator !== 'undefined' && navigator.share && (!navigator.canShare || navigator.canShare(shareData))) {
|
||||
try {
|
||||
await navigator.share(shareData);
|
||||
return;
|
||||
} catch (err) {
|
||||
// User cancelled — bail silently. Any other error falls through to clipboard.
|
||||
if ((err as DOMException)?.name === 'AbortError') return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
await navigator.clipboard.writeText(window.location.href);
|
||||
await navigator.clipboard.writeText(url);
|
||||
setShareConfirm(true);
|
||||
setTimeout(() => setShareConfirm(false), 2000);
|
||||
} catch { /* fallback: do nothing */ }
|
||||
|
||||
Reference in New Issue
Block a user