Skip to content
This repository has been archived by the owner on Sep 21, 2024. It is now read-only.

Commit

Permalink
Merge pull request #68 from pixelaw/fix/some-UIUXs
Browse files Browse the repository at this point in the history
fix: some UIUX errors and add emoji to each address.
  • Loading branch information
0xshora authored Jul 7, 2024
2 parents 6de6680 + c43c0b2 commit 1855730
Show file tree
Hide file tree
Showing 12 changed files with 183 additions and 97 deletions.
80 changes: 80 additions & 0 deletions src/components/Avatar/emojiAvatarForAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
const colors = [
'#FC5C54',
'#FFD95A',
'#E95D72',
'#6A87C8',
'#5FD0F3',
'#75C06B',
'#FFDD86',
'#5FC6D4',
'#FF949A',
'#FF8024',
'#9BA1A4',
'#EC66FF',
'#FF8CBC',
'#FF9A23',
'#C5DADB',
'#A8CE63',
'#71ABFF',
'#FFE279',
'#B6B1B6',
'#FF6780',
'#A575FF',
'#4D82FF',
'#FFB35A',
] as const;

const avatars = [
{ color: colors[0], emoji: '🌶' },
{ color: colors[1], emoji: '🤑' },
{ color: colors[2], emoji: '🐙' },
{ color: colors[3], emoji: '🫐' },
{ color: colors[4], emoji: '🐳' },
{ color: colors[0], emoji: '🤶' },
{ color: colors[5], emoji: '🌲' },
{ color: colors[6], emoji: '🌞' },
{ color: colors[7], emoji: '🐒' },
{ color: colors[8], emoji: '🐵' },
{ color: colors[9], emoji: '🦊' },
{ color: colors[10], emoji: '🐼' },
{ color: colors[11], emoji: '🦄' },
{ color: colors[12], emoji: '🐷' },
{ color: colors[13], emoji: '🐧' },
{ color: colors[8], emoji: '🦩' },
{ color: colors[14], emoji: '👽' },
{ color: colors[0], emoji: '🎈' },
{ color: colors[8], emoji: '🍉' },
{ color: colors[1], emoji: '🎉' },
{ color: colors[15], emoji: '🐲' },
{ color: colors[16], emoji: '🌎' },
{ color: colors[17], emoji: '🍊' },
{ color: colors[18], emoji: '🐭' },
{ color: colors[19], emoji: '🍣' },
{ color: colors[1], emoji: '🐥' },
{ color: colors[20], emoji: '👾' },
{ color: colors[15], emoji: '🥦' },
{ color: colors[0], emoji: '👹' },
{ color: colors[17], emoji: '🙀' },
{ color: colors[4], emoji: '⛱' },
{ color: colors[21], emoji: '⛵️' },
{ color: colors[17], emoji: '🥳' },
{ color: colors[8], emoji: '🤯' },
{ color: colors[22], emoji: '🤠' },
] as const;

function hashCode(text: string) {
let hash = 0;
if (text.length === 0) return hash;
for (let i = 0; i < text.length; i++) {
const chr = text.charCodeAt(i);
hash = (hash << 5) - hash + chr;
hash |= 0;
}
return hash;
}

export function emojiAvatarForAddress(address: string) {
const resolvedAddress = typeof address === 'string' ? address : '';
const avatarIndex = Math.abs(hashCode(resolvedAddress.toLowerCase()) % avatars.length);
return avatars[avatarIndex ?? 0];
}
20 changes: 2 additions & 18 deletions src/components/Loading/Loading.module.css
Original file line number Diff line number Diff line change
@@ -1,23 +1,7 @@
.loadingContainer {
@apply fixed inset-0 z-50 flex items-center justify-center bg-primary/90;
@apply fixed inset-0 z-50 flex items-center justify-center bg-bg-primary/90;
}

.loadingText {
@apply text-3xl font-bold text-white;
animation: loadingAnimation 1s steps(4, end) infinite;
}

@keyframes loadingAnimation {
0% {
content: 'Loading.';
}
25% {
content: 'Loading..';
}
50% {
content: 'Loading...';
}
75% {
content: 'Loading...';
}
}
}
28 changes: 23 additions & 5 deletions src/components/Loading/Loading.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
import React, { useState, useEffect } from 'react';
import styles from './Loading.module.css';

const Loading = () => (
<div className={styles.loadingContainer}>
<span className={styles.loadingText}>Loading...</span>
</div>
);
const Loading: React.FC = () => {
const [loadingText, setLoadingText] = useState('Loading.');

useEffect(() => {
const interval = setInterval(() => {
setLoadingText(prev => {
if (prev === 'Loading...') {
return 'Loading.';
}
return prev + '.';
});
}, 500);

return () => clearInterval(interval);
}, []);

return (
<div className={styles.loadingContainer}>
<span className={styles.loadingText}>{loadingText}</span>
</div>
);
};

export default Loading;
4 changes: 2 additions & 2 deletions src/components/MenuBar/MenuBar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import styles from './MenuBar.module.css';
import { formatWalletAddress } from '@/global/utils.ts';
import { formatWalletAddressWithEmoji } from '@/global/utils.ts';
import PxCounter from '@/components/MenuBar/PxCounter.tsx';

interface MenuBarProps {
Expand Down Expand Up @@ -45,7 +45,7 @@ const MenuBar: React.FC<MenuBarProps> = ({ address, endTime }) => {
<div className={styles.countdownContainer}>{timeLeft}</div>

<div className={styles.rightSection}>
<div className={styles.addressContainer}>{formatWalletAddress(address || '')}</div>
<div className={styles.addressContainer}>{formatWalletAddressWithEmoji(address || '')}</div>
<PxCounter />
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/MenuBar/PxCounter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ const PxCounter = () => {
const player = usePlayer(address);
const pixelRecoveryRate = usePixelRecoveryRate();

const playerPx = player?.data?.current_px ?? 10;
const maxPx = player?.data?.max_px ?? 10;
const playerPx = player?.data?.current_px ?? 10; // Default to 10 if player is not loaded
const maxPx = player?.data?.max_px ?? 10; // Default to 10 if player is not loaded
const recoveryRate = pixelRecoveryRate?.data?.rate ?? 0;
const playerLastDate = player?.data?.last_date ?? 0;

Expand Down
6 changes: 3 additions & 3 deletions src/components/ProposalList/ProposalItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { usePixelawProvider } from '@/providers/PixelawProvider.tsx';
import { ProposalType } from '@/global/types.ts';
import { numRGBAToHex } from '@/webtools/utils.ts';
import { GAME_ID, NEEDED_YES_PX } from '@/global/constants.ts';
import { formatWalletAddress, toastContractError, formatTimeRemaining, formatTimeRemainingFotTitle } from '@/global/utils.ts';
import { formatWalletAddressWithEmoji, toastContractError, formatTimeRemaining, formatTimeRemainingFotTitle } from '@/global/utils.ts';
import { type ProposalDataType } from '@/hooks/useProposals.ts';
import useGetPixelsToReset from "@/hooks/useGetPixelsToReset.ts";

Expand All @@ -30,7 +30,7 @@ const createProposalTitle = (proposalType: ProposalType, target_args_1: number,
case ProposalType.AddNewColor:
return `Adding A New Color: ${numRGBAToHex(target_args_1).toUpperCase()}`;
case ProposalType.ResetToWhiteByColor:
return `Make A Disaster: ${numRGBAToHex(target_args_1).toUpperCase()}`;
return `Reset To White: ${numRGBAToHex(target_args_1).toUpperCase()}`;
case ProposalType.ExtendGameEndTime:
return `Extend Game End Time: ${formatTimeRemainingFotTitle(target_args_1)}`;
case ProposalType.ExpandArea:
Expand Down Expand Up @@ -167,7 +167,7 @@ const ProposalItem: React.FC<PropsType> = ({ proposal, onStartVote, filter, sear
</div>
</div>
<div className='mb-2 text-xs text-gray-400'>
proposed by {formatWalletAddress(proposal.author.toString())}
proposed by {formatWalletAddressWithEmoji(proposal.author.toString())}
</div>
<div
className='mr-30 relative mb-1 flex h-2 rounded-full bg-gray-700'

Check warning on line 173 in src/components/ProposalList/ProposalItem.tsx

View workflow job for this annotation

GitHub Actions / lint-n-format (20.x)

Classname 'mr-30' is not a Tailwind CSS class!
Expand Down
9 changes: 7 additions & 2 deletions src/dojo/createSystemCalls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,17 @@ export function createSystemCalls({ client }: { client: IWorld }) {
await new Promise((resolve) => setTimeout(resolve, 1000));
};

const activateProposal = async (account: AccountInterface, gameId: number, index: number, clearData?: {x: number, y: number}[]) => {
const activateProposal = async (
account: AccountInterface,
gameId: number,
index: number,
clearData?: { x: number; y: number }[],
) => {
const { transaction_hash } = await client.actions.activateProposal({
account,
gameId,
index,
clearData
clearData,
});

await account.waitForTransaction(transaction_hash, {
Expand Down
24 changes: 9 additions & 15 deletions src/dojo/generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,36 +94,30 @@ export async function setupWorld(provider: DojoProvider) {
account,
gameId,
index,
clearData
clearData,
}: {
account: AccountInterface;
gameId: number;
index: number;
clearData?: {x: number, y: number}[]
clearData?: { x: number; y: number }[];
}) => {

const clearDataArgs: number[] = []
const clearDataArgs: number[] = [];
if (clearData) {
clearData.forEach(({x, y}) => {
clearDataArgs.push(x)
clearDataArgs.push(y)
})
clearData.forEach(({ x, y }) => {
clearDataArgs.push(x);
clearDataArgs.push(y);
});
}

if (clearData) console.log(clearDataArgs)
if (clearData) console.log(clearDataArgs);

try {
return await provider.execute(
account,
{
contractAddress: PROPOSAL_CONTRACT_ADDRESS,
entrypoint: 'activate_proposal',
calldata: [
gameId,
index,
clearData?.length ?? 0,
...clearDataArgs
],
calldata: [gameId, index, clearData?.length ?? 0, ...clearDataArgs],
},
{
skipValidate: true,
Expand Down
9 changes: 9 additions & 0 deletions src/global/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { shortString } from 'starknet';
import { toastError, toastSuccess } from '@/components/Toast';
import { type Position } from '@/global/types.ts';
import { type Coordinate } from '@/webtools/types.ts';
import { emojiAvatarForAddress } from '@/components/Avatar/emojiAvatarForAddress';

/*
* @notice converts a number to hexadecimal
Expand Down Expand Up @@ -72,6 +73,14 @@ export const formatWalletAddress = (address: string) => {
return address;
};

export const formatWalletAddressWithEmoji = (address: string) => {
const avatar = emojiAvatarForAddress(address);
if (address.length > 10) {
return avatar.emoji + `${address.slice(0, 4)}...${address.slice(-4)}`;
}
return avatar.emoji + address;
};

// Takes a RGB hex nr and converts it to numeric rgba (0 alpha)
export const coordinateToPosition = (coord: Coordinate): Position => {
return { x: coord[0], y: coord[1] };
Expand Down
42 changes: 19 additions & 23 deletions src/hooks/useGetPixelsToReset.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import {useMutation} from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { GraphQLClient } from 'graphql-request';
import GetResetPixels from '@/../graphql/GetPixelsToReset.graphql';
import { useSettingsStore } from '@/stores/SettingsStore.ts';
import useBoard from "@/hooks/useBoard.ts";
import {GAME_ID} from "@/global/constants.ts";
import useBoard from '@/hooks/useBoard.ts';
import { GAME_ID } from '@/global/constants.ts';

type Data = {
pixelModels: {
edges: {
node: {
x: number,
y: number
x: number;
y: number;
};
}[];
};
Expand All @@ -21,27 +21,23 @@ const useGetPixelsToReset = () => {
const baseUrl = settings?.config?.toriiUrl ?? 'http://localhost:8080';
const gqlClient = new GraphQLClient(`${baseUrl}/graphql`);

const board = useBoard(GAME_ID)
const board = useBoard(GAME_ID);

return useMutation({
mutationKey: ['usePixelRecoveryRate'],
mutationFn: async ({color}: {color: number}) => {
if (!board.data) throw new Error('board data not yet loaded')
const result: Data = await gqlClient
.request(
GetResetPixels,
{
color,
xGTE: board.data.origin.x,
xLTE: board.data.origin.x + board.data.width - 1,
yGTE: board.data.origin.y,
yLTE: board.data.origin.y + board.data.height - 1,
limit: board.data.height * board.data.width
}
);
return result.pixelModels.edges.map(({ node: { x, y }}) => {
return { x, y }
})
mutationFn: async ({ color }: { color: number }) => {
if (!board.data) throw new Error('board data not yet loaded');
const result: Data = await gqlClient.request(GetResetPixels, {
color,
xGTE: board.data.origin.x,
xLTE: board.data.origin.x + board.data.width - 1,
yGTE: board.data.origin.y,
yLTE: board.data.origin.y + board.data.height - 1,
limit: board.data.height * board.data.width,
});
return result.pixelModels.edges.map(({ node: { x, y } }) => {
return { x, y };
});
},
retryDelay: (failureCount) => failureCount * 1_000,
});
Expand Down
Loading

0 comments on commit 1855730

Please sign in to comment.