Improve share button: mobile-friendly Web Share API, icon button, fallback clipboard

This commit is contained in:
Hördle Bot
2025-11-22 19:39:32 +01:00
parent 328c8fe98a
commit 58e9b4fa60

View File

@@ -28,7 +28,7 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
const { gameState, statistics, addGuess } = useGameState(genre, maxAttempts); const { gameState, statistics, addGuess } = useGameState(genre, maxAttempts);
const [hasWon, setHasWon] = useState(false); const [hasWon, setHasWon] = useState(false);
const [hasLost, setHasLost] = useState(false); const [hasLost, setHasLost] = useState(false);
const [shareText, setShareText] = useState('Share Result'); const [shareText, setShareText] = useState('🔗 Share');
const [lastAction, setLastAction] = useState<'GUESS' | 'SKIP' | null>(null); const [lastAction, setLastAction] = useState<'GUESS' | 'SKIP' | null>(null);
const [isProcessingGuess, setIsProcessingGuess] = useState(false); const [isProcessingGuess, setIsProcessingGuess] = useState(false);
@@ -89,7 +89,7 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
const unlockedSeconds = unlockSteps[Math.min(gameState.guesses.length, unlockSteps.length - 1)]; const unlockedSeconds = unlockSteps[Math.min(gameState.guesses.length, unlockSteps.length - 1)];
const handleShare = () => { const handleShare = async () => {
let emojiGrid = ''; let emojiGrid = '';
const totalGuesses = maxAttempts; const totalGuesses = maxAttempts;
@@ -124,24 +124,33 @@ export default function Game({ dailyPuzzle, genre = null, isSpecial = false, max
const text = `Hördle #${dailyPuzzle.id}\n${genreText}\n${speaker}${emojiGrid}\n\n#Hördle #Music\n\n${shareUrl}`; const text = `Hördle #${dailyPuzzle.id}\n${genreText}\n${speaker}${emojiGrid}\n\n#Hördle #Music\n\n${shareUrl}`;
// Fallback method for copying to clipboard // Try native Web Share API first (mobile-friendly)
const textarea = document.createElement('textarea'); if (navigator.share) {
textarea.value = text;
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
try { try {
document.execCommand('copy'); await navigator.share({
setShareText('Copied!'); title: `Hördle #${dailyPuzzle.id}`,
setTimeout(() => setShareText('Share Result'), 2000); text: text,
});
setShareText('✓ Shared!');
setTimeout(() => setShareText('🔗 Share'), 2000);
return;
} catch (err) { } catch (err) {
console.error('Failed to copy:', err); // User cancelled or error - fall through to clipboard
setShareText('Copy failed'); if ((err as Error).name !== 'AbortError') {
setTimeout(() => setShareText('Share Result'), 2000); console.error('Share failed:', err);
} finally { }
document.body.removeChild(textarea); }
}
// Fallback: Copy to clipboard
try {
await navigator.clipboard.writeText(text);
setShareText('✓ Copied!');
setTimeout(() => setShareText('🔗 Share'), 2000);
} catch (err) {
console.error('Clipboard failed:', err);
setShareText('✗ Failed');
setTimeout(() => setShareText('🔗 Share'), 2000);
} }
}; };