mobile optimizations
This commit is contained in:
parent
449cd4bad4
commit
e9913b1a4f
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import { useState, useEffect, useImperativeHandle, forwardRef } from 'react';
|
import { useState, useEffect, useImperativeHandle, forwardRef } from 'react';
|
||||||
import { useWallet } from '@solana/wallet-adapter-react';
|
import { useWallet } from '@solana/wallet-adapter-react';
|
||||||
import { WalletMultiButton } from '@solana/wallet-adapter-react-ui';
|
import { WalletName } from '@solana/wallet-adapter-base';
|
||||||
import { Connection, PublicKey } from '@solana/web3.js';
|
import { Connection, PublicKey } from '@solana/web3.js';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import '@solana/wallet-adapter-react-ui/styles.css';
|
import '@solana/wallet-adapter-react-ui/styles.css';
|
||||||
|
|
@ -13,6 +13,86 @@ export interface HeaderRef {
|
||||||
refreshBalance: () => Promise<void>;
|
refreshBalance: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom Wallet Button Component
|
||||||
|
const CustomWalletButton = () => {
|
||||||
|
const { publicKey, disconnect, select, wallets } = useWallet();
|
||||||
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
||||||
|
|
||||||
|
const handleWalletSelect = (walletName: WalletName) => {
|
||||||
|
select(walletName);
|
||||||
|
setIsDropdownOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDisconnect = () => {
|
||||||
|
disconnect();
|
||||||
|
setIsDropdownOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (publicKey) {
|
||||||
|
return (
|
||||||
|
<div className="relative">
|
||||||
|
<button
|
||||||
|
onClick={() => setIsDropdownOpen(!isDropdownOpen)}
|
||||||
|
className="bg-gradient-to-r from-green-600 to-emerald-600 hover:from-green-700 hover:to-emerald-700 text-white rounded-xl px-4 py-2 md:px-6 md:py-3 text-xs md:text-sm font-semibold shadow-lg shadow-green-500/25 hover:shadow-xl hover:shadow-green-500/30 transition-all duration-300 hover:scale-105 hover:-translate-y-0.5 flex items-center space-x-2"
|
||||||
|
>
|
||||||
|
<div className="w-2 h-2 bg-green-300 rounded-full"></div>
|
||||||
|
<span className="truncate max-w-[80px] md:max-w-[120px]">
|
||||||
|
{publicKey.toString().slice(0, 4)}...{publicKey.toString().slice(-4)}
|
||||||
|
</span>
|
||||||
|
<svg className="w-3 h-3 md:w-4 md:h-4 transition-transform duration-200" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{isDropdownOpen && (
|
||||||
|
<div className="absolute right-0 mt-2 w-48 bg-white rounded-xl shadow-xl border border-gray-200 py-2 z-50">
|
||||||
|
<button
|
||||||
|
onClick={handleDisconnect}
|
||||||
|
className="w-full text-left px-4 py-2 text-gray-700 hover:bg-gray-50 transition-colors duration-200"
|
||||||
|
>
|
||||||
|
Disconnect
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relative">
|
||||||
|
<button
|
||||||
|
onClick={() => setIsDropdownOpen(!isDropdownOpen)}
|
||||||
|
className="bg-gradient-to-r from-green-600 to-emerald-600 hover:from-green-700 hover:to-emerald-700 text-white rounded-xl px-4 py-2 md:px-6 md:py-3 text-xs md:text-sm font-semibold shadow-lg shadow-green-500/25 hover:shadow-xl hover:shadow-green-500/30 transition-all duration-300 hover:scale-105 hover:-translate-y-0.5 flex items-center space-x-2"
|
||||||
|
>
|
||||||
|
<svg className="w-4 h-4 md:w-5 md:h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" />
|
||||||
|
</svg>
|
||||||
|
<span className="whitespace-nowrap">Select Wallet</span>
|
||||||
|
<svg className="w-3 h-3 md:w-4 md:h-4 transition-transform duration-200" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{isDropdownOpen && (
|
||||||
|
<div className="absolute right-0 mt-2 w-48 bg-white rounded-xl shadow-xl border border-gray-200 py-2 z-50">
|
||||||
|
{wallets.map((wallet) => (
|
||||||
|
<button
|
||||||
|
key={wallet.adapter.name}
|
||||||
|
onClick={() => handleWalletSelect(wallet.adapter.name)}
|
||||||
|
className="w-full text-left px-4 py-2 text-gray-700 hover:bg-gray-50 transition-colors duration-200 flex items-center space-x-3"
|
||||||
|
>
|
||||||
|
{wallet.adapter.icon && (
|
||||||
|
<img src={wallet.adapter.icon} alt={wallet.adapter.name} className="w-6 h-6" />
|
||||||
|
)}
|
||||||
|
<span>{wallet.adapter.name}</span>
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const Header = forwardRef<HeaderRef>((props, ref) => {
|
const Header = forwardRef<HeaderRef>((props, ref) => {
|
||||||
const { publicKey } = useWallet();
|
const { publicKey } = useWallet();
|
||||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||||
|
|
@ -178,22 +258,16 @@ const Header = forwardRef<HeaderRef>((props, ref) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<WalletMultiButton className="!bg-gradient-to-r !from-green-600 !to-emerald-600 hover:!from-green-700 hover:!to-emerald-700 !text-white !rounded-xl !px-6 !py-3 !text-sm !font-semibold !shadow-lg !shadow-green-500/25 hover:!shadow-xl hover:!shadow-green-500/30 transition-all duration-300 hover:!scale-105 hover:!-translate-y-0.5" />
|
<CustomWalletButton />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<WalletMultiButton className="!bg-gradient-to-r !from-green-600 !to-emerald-600 hover:!from-green-700 hover:!to-emerald-700 !text-white !rounded-xl !px-6 !py-3 !text-sm !font-semibold !shadow-lg !shadow-green-500/25 hover:!shadow-xl hover:!shadow-green-500/30 transition-all duration-300 hover:!scale-105 hover:!-translate-y-0.5" />
|
<CustomWalletButton />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mobile Menu Button */}
|
{/* Mobile Menu Button */}
|
||||||
<div className="md:hidden flex items-center space-x-3">
|
<div className="md:hidden flex items-center space-x-3">
|
||||||
<button
|
<CustomWalletButton />
|
||||||
onClick={handleBuyDino}
|
|
||||||
className="bg-gradient-to-r from-orange-500 to-red-500 text-white font-bold py-2 px-4 rounded-lg shadow-lg shadow-orange-500/25 text-sm"
|
|
||||||
>
|
|
||||||
Buy $DINO
|
|
||||||
</button>
|
|
||||||
<WalletMultiButton className="!bg-gradient-to-r !from-green-600 !to-emerald-600 !text-white !rounded-lg !px-4 !py-2 !text-sm !font-semibold !shadow-lg !shadow-green-500/25" />
|
|
||||||
<button
|
<button
|
||||||
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||||||
className="w-10 h-10 bg-gray-100 hover:bg-green-100 rounded-lg flex items-center justify-center transition-all duration-300 hover:scale-105"
|
className="w-10 h-10 bg-gray-100 hover:bg-green-100 rounded-lg flex items-center justify-center transition-all duration-300 hover:scale-105"
|
||||||
|
|
|
||||||
|
|
@ -114,11 +114,6 @@ export default function Leaderboard({ leaderboard, loading, error, attemptsCount
|
||||||
: entry.owner
|
: entry.owner
|
||||||
}
|
}
|
||||||
</p>
|
</p>
|
||||||
{entry.owner.length > 20 && (
|
|
||||||
<p className="text-xs text-gray-500 font-mono">
|
|
||||||
{entry.owner}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
{/* Prize indicators for top 3 */}
|
{/* Prize indicators for top 3 */}
|
||||||
{index < 3 && (
|
{index < 3 && (
|
||||||
<div className="flex items-center space-x-1 mt-1">
|
<div className="flex items-center space-x-1 mt-1">
|
||||||
|
|
|
||||||
123
app/globals.css
123
app/globals.css
|
|
@ -48,3 +48,126 @@
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Wallet button text layout fixes */
|
||||||
|
@layer utilities {
|
||||||
|
/* Fix Solana wallet button text layout */
|
||||||
|
.wallet-adapter-button {
|
||||||
|
white-space: nowrap !important;
|
||||||
|
line-height: 1 !important;
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: center !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
text-overflow: ellipsis !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-adapter-button-text {
|
||||||
|
white-space: nowrap !important;
|
||||||
|
line-height: 1 !important;
|
||||||
|
display: inline !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
text-overflow: ellipsis !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Override any default wallet button styles that might cause text wrapping */
|
||||||
|
[data-testid="wallet-adapter-button"] {
|
||||||
|
white-space: nowrap !important;
|
||||||
|
line-height: 1 !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
text-overflow: ellipsis !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-testid="wallet-adapter-button"] span {
|
||||||
|
white-space: nowrap !important;
|
||||||
|
line-height: 1 !important;
|
||||||
|
display: inline !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
text-overflow: ellipsis !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Additional wallet adapter overrides */
|
||||||
|
.wallet-adapter-button-trigger {
|
||||||
|
white-space: nowrap !important;
|
||||||
|
line-height: 1 !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
text-overflow: ellipsis !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure text stays within button boundaries */
|
||||||
|
.wallet-adapter-button,
|
||||||
|
.wallet-adapter-button-trigger,
|
||||||
|
[data-testid="wallet-adapter-button"] {
|
||||||
|
max-width: fit-content !important;
|
||||||
|
min-width: fit-content !important;
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Force single line text and prevent line breaks */
|
||||||
|
.wallet-adapter-button *,
|
||||||
|
.wallet-adapter-button-trigger *,
|
||||||
|
[data-testid="wallet-adapter-button"] * {
|
||||||
|
white-space: nowrap !important;
|
||||||
|
line-height: 1 !important;
|
||||||
|
display: inline !important;
|
||||||
|
word-break: keep-all !important;
|
||||||
|
word-wrap: normal !important;
|
||||||
|
overflow-wrap: normal !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Specific override for any text content */
|
||||||
|
.wallet-adapter-button-text,
|
||||||
|
.wallet-adapter-button span,
|
||||||
|
[data-testid="wallet-adapter-button"] span {
|
||||||
|
display: inline-block !important;
|
||||||
|
vertical-align: middle !important;
|
||||||
|
line-height: 1 !important;
|
||||||
|
white-space: nowrap !important;
|
||||||
|
word-break: keep-all !important;
|
||||||
|
word-wrap: normal !important;
|
||||||
|
overflow-wrap: normal !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure proper text positioning within button */
|
||||||
|
.wallet-adapter-button,
|
||||||
|
.wallet-adapter-button-trigger,
|
||||||
|
[data-testid="wallet-adapter-button"] {
|
||||||
|
position: relative !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Center text vertically and horizontally */
|
||||||
|
.wallet-adapter-button > *,
|
||||||
|
.wallet-adapter-button-trigger > *,
|
||||||
|
[data-testid="wallet-adapter-button"] > * {
|
||||||
|
position: relative !important;
|
||||||
|
top: 50% !important;
|
||||||
|
transform: translateY(-50%) !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure proper flexbox behavior */
|
||||||
|
.wallet-adapter-button,
|
||||||
|
.wallet-adapter-button-trigger,
|
||||||
|
[data-testid="wallet-adapter-button"] {
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center !important;
|
||||||
|
justify-content: center !important;
|
||||||
|
flex-direction: row !important;
|
||||||
|
flex-wrap: nowrap !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prevent any unwanted spacing in flexbox */
|
||||||
|
.wallet-adapter-button > *,
|
||||||
|
.wallet-adapter-button-trigger > *,
|
||||||
|
[data-testid="wallet-adapter-button"] > * {
|
||||||
|
flex: 0 0 auto !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ export default function Home() {
|
||||||
|
|
||||||
{/* Game iframe - shown when user has a ticket */}
|
{/* Game iframe - shown when user has a ticket */}
|
||||||
{hasTicket && (
|
{hasTicket && (
|
||||||
<div className="w-full h-screen flex justify-center items-center bg-white">
|
<div className="w-full h-screen flex justify-center items-center bg-white" style={{ marginTop: '80px' }}>
|
||||||
<iframe
|
<iframe
|
||||||
src={`/Build/index.html?tx=${ticketTxHash}&highscore=${highscore}`}
|
src={`/Build/index.html?tx=${ticketTxHash}&highscore=${highscore}`}
|
||||||
className="w-full h-full"
|
className="w-full h-full"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user