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

fix: some UIUX errors and add emoji to each address. #68

Merged
merged 2 commits into from
Jul 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 { 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 @@
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,10 +167,10 @@
</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!
style={{ marginRight: '7rem' }}
>
<div
Expand All @@ -187,7 +187,7 @@
/>
</div>
<div
className='mr-30 flex justify-between text-xs text-gray-300'

Check warning on line 190 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!
style={{ marginRight: '7rem' }}
>
<div>For {proposal.yes_px} points</div>
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
Loading