Skip to content

Commit

Permalink
feat(ui): earnings recap (#807)
Browse files Browse the repository at this point in the history
Description
---
- refactored win/lose animation triggers to check transactions (remove
balance change checks since we have transaction history now)
- also includes moving some of the mining hooks & store updaters around
and into `useMiningStatesSync`
- moved wallet, transaction, and mining metrics 'fetch' functions out of
the stores and into their own hooks so they can be used independently of
the stores
- store missed wins if `canAnimate` was false for a won block
- show the recap once window is focused again
- adjusted `Earnings` styling to cater for the new recap section
- updated the debug settings block time counter to use block_time from
base_node instead of the display block height (also updates when not
mining)


Motivation and Context
---
- no ticket but resolves Recap History
[(figma)](https://www.figma.com/design/Tyh0UcWVo44z66gYHd0TBs/Tari-Universe-Planning-%26-Wires?node-id=2922-148285&node-type=canvas&m=dev)



How Has This Been Tested?
---

- locally

### **recap after minimised:**


https://github.com/user-attachments/assets/7b071ea8-8a1b-48ad-93cd-7218146bf8cc

----

### **recap after just being on a different screen:**

(and a win right after focusing, cos i am DOMINATING esmeralda
apparently)


https://github.com/user-attachments/assets/bacc978e-d6f4-4eb0-8bed-ad9bf6069aa1

----

### **win while focused still works as normal + debug block time:**



https://github.com/user-attachments/assets/45f3f7e4-6a0d-49db-868e-3982aa374f99

----

**~~still trying to get a fail animation, but i think i'm the only
person on esme right now or something, but it does work :3~~**

### **lose while focused still working as before:**



https://github.com/user-attachments/assets/9aa6b04e-f3fa-44aa-8305-dd14196d74f6


----

What process can a PR reviewer use to test or verify this change?
---

- run app
- check if winning and losing a block still works as before 
- leave the app minimized or on a non-focused screen for a while
- come back and check that the blocks you won previously are accounted
for

---------

Co-authored-by: Brian Pearce <[email protected]>
  • Loading branch information
shanimal08 and brianp authored Oct 14, 2024
1 parent 3b2d1d0 commit 2c5bd07
Show file tree
Hide file tree
Showing 26 changed files with 404 additions and 266 deletions.
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"@floating-ui/react": "^0.26.24",
"@tauri-apps/api": "^1",
"emoji-regex": "^10.4.0",
"framer-motion": "^11.11.4",
"framer-motion": "^11.11.7",
"globals": "^15.11.0",
"i18next": "^23.15.2",
"i18next-browser-languagedetector": "^8.0.0",
Expand Down Expand Up @@ -55,4 +55,4 @@
"typescript-eslint": "^8.8.1",
"vite": "^5.4.8"
}
}
}
1 change: 1 addition & 0 deletions public/locales/en/mining-view.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"floor": "Floor",
"current-block-time": "Current block time",
"your-reward-is": "Your reward is",
"you-won-while-away": "<span>You won {{ blocks }}</span> while you were away",
"connection-to-node-lost": "Connection to miner lost. Please wait for the miner to reconnect or restart the miner.",
"mining-button-text": {
"starting-mining": "Starting Mining",
Expand Down
18 changes: 5 additions & 13 deletions src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
},
"updater": {
"active": true,
"endpoints": [
"https://raw.githubusercontent.com/tari-project/universe/main/.updater/alpha-latest.json"
],
"endpoints": ["https://raw.githubusercontent.com/tari-project/universe/main/.updater/alpha-latest.json"],
"dialog": false,
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEYxNUJBOEFEQkQ4RjJBMjYKUldRbUtvKzlyYWhiOFJIUmFFditENVV3d3hRbjNlZm1DMi9aMjluRUpVdHhQTytadTV3ODN3bUMK"
},
Expand Down Expand Up @@ -53,8 +51,8 @@
"label": "main",
"width": 1380,
"height": 780,
"minWidth": 997,
"minHeight": 620,
"minWidth": 1144,
"minHeight": 660,
"resizable": true,
"fullscreen": false,
"decorations": true,
Expand All @@ -68,13 +66,7 @@
"active": true,
"targets": "all",
"identifier": "com.tari.universe.alpha",
"icon": [
"icons/icon.icns",
"icons/icon.ico",
"icons/icon.png",
"icons/StoreLogo.png",
"icons/tari.png"
],
"icon": ["icons/icon.icns", "icons/icon.ico", "icons/icon.png", "icons/StoreLogo.png", "icons/tari.png"],
"copyright": "Copyright (c) 2024 Tari Labs, LLC",
"shortDescription": "Tari Universe is a mining app for Tari.",
"longDescription": "Introducing Tari Universe, the beautifully simple mining app for Tari. Install it on your Mac or PC and start mining Tari with one click.",
Expand All @@ -85,4 +77,4 @@
},
"macOSPrivateApi": true
}
}
}
17 changes: 9 additions & 8 deletions src/components/CharSpinner/CharSpinner.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,20 @@ interface Props {
$variant?: CharSpinnerVariant;
}

export const Wrapper = styled.div<{ $letterHeight?: number }>`
export const Wrapper = styled.div<{ $variant?: Props['$variant']; $alignment?: string }>`
width: 100%;
display: flex;
overflow: hidden;
flex-direction: row;
align-items: baseline;
align-items: ${({ $alignment }) => $alignment};
font-family: ${({ $variant }) => ($variant == 'simple' ? 'Poppins' : 'DrukWide')}, sans-serif;
gap: 4px;
`;

span {
display: flex;
font-weight: 600;
letter-spacing: -1px;
}
export const XTMWrapper = styled.span`
display: flex;
font-weight: 600;
letter-spacing: -1px;
`;

export const SpinnerWrapper = styled(m.div)<Props>`
Expand All @@ -45,7 +46,7 @@ export const Characters = styled(m.div)<Props>`
display: flex;
flex-direction: column;
align-items: center;
font-weight: ${({ $variant }) => ($variant == 'simple' ? 600 : 700)};
font-weight: ${({ $variant }) => ($variant == 'simple' ? 600 : 900)};
font-family: ${({ $variant }) => ($variant == 'simple' ? 'Poppins' : 'DrukWide')}, sans-serif;
font-size: ${({ $fontSize }) => `${$fontSize}px`};
line-height: ${({ $letterHeight }) => `${$letterHeight}px`};
Expand Down
16 changes: 11 additions & 5 deletions src/components/CharSpinner/CharSpinner.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Character, Characters, CharacterWrapper, SpinnerWrapper, Wrapper } from './CharSpinner.styles.ts';
import { LayoutGroup, m } from 'framer-motion';
import { Character, Characters, CharacterWrapper, SpinnerWrapper, Wrapper, XTMWrapper } from './CharSpinner.styles.ts';
import { LayoutGroup } from 'framer-motion';

const transition = {
type: 'spring',
Expand All @@ -14,6 +14,7 @@ interface CharSpinnerProps {
value: string;
fontSize: number;
variant?: CharSpinnerVariant;
XTMAlignment?: 'baseline' | 'center';
}

const sizing = {
Expand All @@ -27,7 +28,12 @@ const sizing = {
},
};

export default function CharSpinner({ value, variant = 'large', fontSize }: CharSpinnerProps) {
export default function CharSpinner({
value,
variant = 'large',
fontSize,
XTMAlignment = 'baseline',
}: CharSpinnerProps) {
const letterHeight = Math.ceil(fontSize * 1.01);
const charArray = value.split('').map((c) => c);
const letterWidth = Math.floor(fontSize / sizing[variant].widthDiv);
Expand Down Expand Up @@ -90,14 +96,14 @@ export default function CharSpinner({ value, variant = 'large', fontSize }: Char
});

return (
<Wrapper>
<Wrapper $alignment={XTMAlignment} $variant={variant}>
<LayoutGroup id="char-spinner">
<SpinnerWrapper style={{ height: letterHeight }} $variant={variant}>
<CharacterWrapper style={{ height: letterHeight * 10 }}>
<LayoutGroup id="characters">{charMarkup}</LayoutGroup>
</CharacterWrapper>
</SpinnerWrapper>
{value === '-' ? null : <m.span layout>tXTM</m.span>}
{value === '-' ? null : <XTMWrapper>tXTM</XTMWrapper>}
</LayoutGroup>
</Wrapper>
);
Expand Down
1 change: 1 addition & 0 deletions src/containers/Dashboard/MiningView/MiningView.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export const MiningViewContainer = styled(m.div)`
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
`;
71 changes: 59 additions & 12 deletions src/containers/Dashboard/MiningView/components/Earnings.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,71 @@ export const EarningsContainer = styled.div`
justify-content: center;
width: 100%;
height: 100%;
position: relative;
`;

export const EarningsWrapper = styled(m.div)`
export const RecapText = styled.div`
display: flex;
align-items: flex-end;
flex-direction: row;
justify-content: center;
font-family: DrukWide, sans-serif;
font-weight: 700;
font-size: 22px;
text-transform: uppercase;
text-align: center;
letter-spacing: -0.3px;
span {
background: #c2d41a;
display: flex;
font-family: DrukWide, sans-serif;
font-weight: 700;
font-size: 14px;
letter-spacing: -0.1px;
margin-right: 3px;
padding: 0 3px;
}
@media (max-width: 1200px) {
font-size: 16px;
}
`;

@media (max-width: 1100px) {
flex-direction: column;
align-items: center;
export const WinText = styled.div`
text-transform: uppercase;
display: flex;
font-family: DrukWide, sans-serif;
font-size: 14px;
letter-spacing: -0.1px;
white-space: pre;
@media (max-width: 1200px) {
font-size: 12px;
}
`;
export const WinWrapper = styled(m.div)`
align-items: center;
display: flex;
flex-direction: row;
span {
font-weight: 500;
line-height: 1.1;
@media (max-width: 1200px) {
font-size: 12px;
}
}
`;

export const ShinyWrapper = styled.div`
display: flex;
position: relative;
&:after {
content: '';
position: absolute;
width: 50%;
height: 80%;
top: 0;
left: 35%;
background-image: linear-gradient(135deg, transparent 45%, rgba(255, 255, 255, 0.25) 50%, transparent 55%);
}
`;
export const EarningsWrapper = styled(m.div)`
display: flex;
align-items: center;
flex-direction: column;
justify-content: flex-end;
gap: 10px;
position: relative;
`;
36 changes: 28 additions & 8 deletions src/containers/Dashboard/MiningView/components/Earnings.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { AnimatePresence } from 'framer-motion';

import { EarningsContainer, EarningsWrapper } from './Earnings.styles.ts';
import { EarningsContainer, EarningsWrapper, RecapText, ShinyWrapper, WinText, WinWrapper } from './Earnings.styles.ts';
import formatBalance from '@app/utils/formatBalance.ts';

import CharSpinner from '@app/components/CharSpinner/CharSpinner.tsx';
import { useTranslation } from 'react-i18next';
import { Trans, useTranslation } from 'react-i18next';
import { useBlockchainVisualisationStore } from '@app/store/useBlockchainVisualisationStore.ts';

const variants = {
visible: {
opacity: 1,
y: -190,
y: '-150%',
scale: 1.05,
transition: {
duration: 1.25,
Expand All @@ -22,7 +22,7 @@ const variants = {
},
hidden: {
opacity: 0.2,
y: -160,
y: '-100%',
transition: { duration: 0.2, delay: 3, ease: 'linear' },
},
};
Expand All @@ -31,15 +31,35 @@ export default function Earnings() {
const { t } = useTranslation('mining-view', { useSuspense: false });

const earnings = useBlockchainVisualisationStore((s) => s.earnings);
const formatted = formatBalance(earnings || 0);
const recapData = useBlockchainVisualisationStore((s) => s.recapData);

const displayEarnings = recapData?.totalEarnings || earnings;

const formatted = formatBalance(displayEarnings || 0, 1);

return (
<EarningsContainer>
<AnimatePresence mode="wait">
{earnings ? (
{displayEarnings ? (
<EarningsWrapper variants={variants} initial="hidden" animate="visible" exit="hidden">
<span>{t('your-reward-is')}</span>
<CharSpinner value={formatted.toString()} fontSize={72} />
{recapData?.totalEarnings ? (
<RecapText>
<Trans
ns="mining-view"
i18nKey={'you-won-while-away'}
values={{
blocks: `${recapData.count} block${recapData.count === 1 ? `` : 's'}`,
}}
components={{ span: <span /> }}
/>
</RecapText>
) : null}
<WinWrapper>
<WinText>{t('your-reward-is')}</WinText>
<ShinyWrapper>
<CharSpinner value={formatted.toString()} fontSize={76} XTMAlignment="center" />
</ShinyWrapper>
</WinWrapper>
</EarningsWrapper>
) : null}
</AnimatePresence>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { useMemo } from 'react';

export default function DebugSettings() {
const { t } = useTranslation(['common', 'settings'], { useSuspense: false });
const lastBlockTime = useBlockchainVisualisationStore((state) => state.displayBlockTime);
const lastBlockTime = useBlockchainVisualisationStore((state) => state.debugBlockTime);
const isConnectedToTariNetwork = useMiningStore((s) => s.base_node?.is_connected);
const connectedPeers = useMiningStore((state) => state.base_node?.connected_peers || []);

Expand Down
9 changes: 2 additions & 7 deletions src/containers/SideBar/Miner/Miner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ import { useShallow } from 'zustand/react/shallow';

import { useAppConfigStore } from '@app/store/useAppConfigStore.ts';
import { useHardwareStats } from '@app/hooks/useHardwareStats.ts';
import useMiningMetricsUpdater from '@app/hooks/useMiningMetricsUpdater.ts';
import useMining from '@app/hooks/mining/useMining.ts';
import { useUiMiningStateMachine } from '@app/hooks/mining/useMiningUiStateMachine.ts';
import useMiningStatesSync from '@app/hooks/mining/useMiningStatesSync.ts';

export default function Miner() {
useMiningStatesSync();
const { cpu: cpuHardwareStats, gpu: gpuHardwareStats } = useHardwareStats();
const miningInitiated = useMiningStore((s) => s.miningInitiated);
const isCpuMiningEnabled = useAppConfigStore((s) => s.cpu_mining_enabled);
Expand All @@ -40,10 +39,6 @@ export default function Miner() {
}))
);

useMiningMetricsUpdater();
useMining();
useUiMiningStateMachine();

const isMiningInProgress = cpu_is_mining || gpu_is_mining;

const isWaitingForCPUHashRate = isCpuMiningEnabled && cpu_is_mining && cpu_hash_rate <= 0;
Expand Down
Loading

0 comments on commit 2c5bd07

Please sign in to comment.