Skip to content

Commit

Permalink
feat: add airdrop settings tab
Browse files Browse the repository at this point in the history
  • Loading branch information
BalazsSevecsek committed Oct 3, 2024
1 parent 997dddf commit ce9ef31
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 8 deletions.
3 changes: 3 additions & 0 deletions public/locales/en/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"applyInviteCode": "Apply Invite Code",
"settings": "Settings",
"seed-words": "Seed words",
"send-logs": "Submit an Issue & Logs",
Expand All @@ -9,6 +10,7 @@
"logs": "Logs",
"open-logs-directory": "Open logs directory",
"debug-info": "Debug",
"disconnect": "Disconnect from Airdrop",
"hardware-status": "Hardware status",
"update-versions": "Update versions",
"refresh-versions": "Refresh versions",
Expand Down Expand Up @@ -49,6 +51,7 @@
"reset-settings": "Reset Settings",
"reset-permanently": "Are you sure you want to reset all settings permanently?",
"reset-wallet": "Reset wallet",
"inviteCode": "Invite Code",
"experimental-title": "Experimental Features",
"experimental-warning": "⚠️ Warning: These features are under active development and could behave unpredictably. Please proceed carefully.",
"connected-to-tari": "Connected to the Tari Network",
Expand Down
26 changes: 21 additions & 5 deletions src/containers/Airdrop/Settings/Logout.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
import { Button } from '@app/components/elements/Button';
import { Typography } from '@app/components/elements/Typography';
import {
SettingsGroupContent,
SettingsGroupTitle,
SettingsGroupWrapper,
} from '@app/containers/Settings/components/SettingsGroup.styles';
import { useAirdropStore } from '@app/store/useAirdropStore';
import { useAppConfigStore } from '@app/store/useAppConfigStore';
import { useTranslation } from 'react-i18next';

export default function AirdropLogout() {
const { t } = useTranslation(['settings'], { useSuspense: false });

const airdropUIEnabled = useAppConfigStore((s) => s.airdrop_ui_enabled);
const logout = useAirdropStore((state) => state.logout);
const { userDetails } = useAirdropStore();

if (!airdropUIEnabled || !userDetails) return null;
return (
<div style={{ maxWidth: 'fit-content', marginLeft: 'auto', padding: '20px' }}>
<Button color="error" variant="text" size="medium" onClick={logout}>
Disconnect from Airdrop
</Button>
</div>
<SettingsGroupWrapper>
<SettingsGroupTitle>
<Typography variant="h6">{t('connection')}</Typography>
</SettingsGroupTitle>
<SettingsGroupContent>
<div style={{ maxWidth: 'fit-content', marginLeft: 'auto', padding: '20px' }}>
<Button color="error" variant="text" size="medium" onClick={logout}>
{t('disconnect')}
</Button>
</div>
</SettingsGroupContent>
</SettingsGroupWrapper>
);
}
9 changes: 9 additions & 0 deletions src/containers/Settings/AirdropSettings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useAirdropStore } from '@app/store/useAirdropStore';
import AirdropLogout from '../Airdrop/Settings/Logout';
import { ApplyInviteCode } from './sections/airdrop/ApplyInviteCode';

export const AirdropSettings = () => {
const { authUuid } = useAirdropStore();

return <>{authUuid ? <AirdropLogout /> : <ApplyInviteCode />}</>;
};
2 changes: 0 additions & 2 deletions src/containers/Settings/GeneralSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import AirdropPermissionSettings from './sections/general/AirdropPermissionSetti
import LogsSettings from './sections/general/LogsSettings.tsx';
import LanguageSettings from './sections/general/LanguageSettings.tsx';
import { ResetSettingsButton } from './sections/general/ResetSettingsButton.tsx';
import AirdropLogout from '../Airdrop/Settings/Logout.tsx';

export const GeneralSettings = () => {
return (
Expand All @@ -11,7 +10,6 @@ export const GeneralSettings = () => {
<LogsSettings />
<AirdropPermissionSettings />
<ResetSettingsButton />
<AirdropLogout />
</>
);
};
5 changes: 5 additions & 0 deletions src/containers/Settings/SettingsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,22 @@ import { WalletSettings } from './WalletSettings.tsx';

import { SettingsType } from './types.ts';
import { Container, ContentContainer, HeaderContainer, SectionWrapper, variants } from './SettingsModal.styles.ts';
import { AirdropSettings } from './AirdropSettings.tsx';
import { useAppConfigStore } from '@app/store/useAppConfigStore.ts';

export default function SettingsModal() {
const { t } = useTranslation(['settings'], { useSuspense: false });
const isSettingsOpen = useAppStateStore((s) => s.isSettingsOpen);
const setIsSettingsOpen = useAppStateStore((s) => s.setIsSettingsOpen);
const airdropUIEnabled = useAppConfigStore((s) => s.airdrop_ui_enabled);

const [activeSection, setActiveSection] = useState<SettingsType>('mining');

const miningMarkup = activeSection === 'mining' ? <MiningSettings /> : null;
const generalMarkup = activeSection === 'general' ? <GeneralSettings /> : null;
const walletMarkup = activeSection === 'wallet' ? <WalletSettings /> : null;
const experimentalMarkup = activeSection === 'experimental' ? <ExperimentalSettings /> : null;
const airdropMarkup = airdropUIEnabled && activeSection === 'airdrop' ? <AirdropSettings /> : null;

function onOpenChange() {
if (isSettingsOpen) {
Expand Down Expand Up @@ -56,6 +60,7 @@ export default function SettingsModal() {
{generalMarkup}
{walletMarkup}
{experimentalMarkup}
{airdropMarkup}
</SectionWrapper>
</AnimatePresence>
</ContentContainer>
Expand Down
90 changes: 90 additions & 0 deletions src/containers/Settings/sections/airdrop/ApplyInviteCode.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { SettingsGroupContent, SettingsGroupTitle, SettingsGroupWrapper } from '../../components/SettingsGroup.styles';
import { Typography } from '@app/components/elements/Typography';
import { useTranslation } from 'react-i18next';
import { useCallback, useEffect, useState } from 'react';
import { Input } from '@app/components/elements/inputs/Input';
import { Button } from '@app/components/elements/Button';
import { v4 as uuidv4 } from 'uuid';
import { useAirdropStore } from '@app/store/useAirdropStore';
import { Stack } from '@app/components/elements/Stack';
import { useAppConfigStore } from '@app/store/useAppConfigStore';

export const ApplyInviteCode = () => {
const { t } = useTranslation(['settings'], { useSuspense: false });
const setAllowTelemetry = useAppConfigStore((s) => s.setAllowTelemetry);

const [claimCode, setClaimCode] = useState('');

const { authUuid, setAuthUuid, setAirdropTokens, setUserPoints, backendInMemoryConfig } = useAirdropStore();

const handleAuth = useCallback(
(code?: string) => {
const token = uuidv4();
if (backendInMemoryConfig?.airdropTwitterAuthUrl) {
setAuthUuid(token);
setAllowTelemetry(true);

open(
`${backendInMemoryConfig?.airdropTwitterAuthUrl}?tauri=${token}${code ? `&universeReferral=${code}` : ''}`
);
}
},
[backendInMemoryConfig?.airdropTwitterAuthUrl, setAllowTelemetry, setAuthUuid]
);

useEffect(() => {
if (authUuid && backendInMemoryConfig?.airdropApiUrl) {
const interval = setInterval(() => {
if (authUuid) {
fetch(`${backendInMemoryConfig?.airdropApiUrl}/auth/twitter/get-token/${authUuid}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => response.json())
.then((data) => {
if (!data.error) {
clearInterval(interval);
setAirdropTokens(data);
}
});
}
}, 1000);
const timeout = setTimeout(
() => {
clearInterval(interval);
setAuthUuid('');
},
1000 * 60 * 5
);

return () => {
clearInterval(interval);
clearTimeout(timeout);
};
}
}, [authUuid, backendInMemoryConfig?.airdropApiUrl, setAirdropTokens, setAuthUuid, setUserPoints]);

return (
<SettingsGroupWrapper>
<SettingsGroupTitle>
<Typography variant="h6">{t('inviteCode')}</Typography>
</SettingsGroupTitle>
<SettingsGroupContent>
<Stack direction="row" gap={4} justifyContent="flex-start">
<Input
name="apply-invite-code"
patternType="text"
value={claimCode}
onChange={(event) => setClaimCode(event.target.value)}
style={{ maxWidth: '20rem' }}
></Input>
<Button color="error" variant="text" size="medium" onClick={() => handleAuth(claimCode)}>
{t('applyInviteCode')}
</Button>
</Stack>
</SettingsGroupContent>
</SettingsGroupWrapper>
);
};
2 changes: 1 addition & 1 deletion src/containers/Settings/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const SETTINGS_TYPES = ['mining', 'general', 'wallet', 'experimental'] as const;
export const SETTINGS_TYPES = ['mining', 'general', 'wallet', 'experimental', 'airdrop'] as const;
type SettingsTuple = typeof SETTINGS_TYPES;
export type SettingsType = SettingsTuple[number];

0 comments on commit ce9ef31

Please sign in to comment.