From 033babd1ac1149343d9ef628aead754ac796208b Mon Sep 17 00:00:00 2001 From: Thebora Kompanioni Date: Fri, 12 Aug 2022 11:01:54 +0200 Subject: [PATCH] feat: click on active "joining" icon opens relevant screen (#463) * fix: pass api token to session request (cherry picked from commit bb4a875271347b846480af4727d1970d7ae8ae20) * dev: add offers and nickname to ServiceInfo (cherry picked from commit 3b3154ea20899404ac651ba3503c44dc4271d986) * dev: add schedule to ServiceInfo * feat: click on navbar joining icon opens relevant screen * review: remove joining icon from navbar * review: add property schedule to ServiceInfo * review: add some space to tab activity indicator --- src/components/ActivityIndicators.jsx | 5 ++- src/components/Navbar.jsx | 41 ++++++++++--------- src/context/ServiceInfoContext.tsx | 59 +++++++++++++++++++++++++-- src/i18n/locales/en/translation.json | 1 - src/i18n/locales/fr/translation.json | 1 - src/libs/JmWalletApi.ts | 4 +- 6 files changed, 81 insertions(+), 30 deletions(-) diff --git a/src/components/ActivityIndicators.jsx b/src/components/ActivityIndicators.jsx index f3d04610d..fb502abac 100644 --- a/src/components/ActivityIndicators.jsx +++ b/src/components/ActivityIndicators.jsx @@ -1,5 +1,6 @@ import React from 'react' import Sprite from './Sprite' +import classnames from 'classnames/bind' function ActivityIndicator({ isOn, children }) { return ( @@ -19,9 +20,9 @@ export function JoiningIndicator({ isOn, size = 30, className, ...props }) { ) } -export function TabActivityIndicator({ isOn }) { +export function TabActivityIndicator({ isOn, className }) { return ( - + ) diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index 5099470bc..17784b0cc 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -4,7 +4,7 @@ import * as rb from 'react-bootstrap' import { useTranslation } from 'react-i18next' import Sprite from './Sprite' import Balance from './Balance' -import { TabActivityIndicator, JoiningIndicator } from './ActivityIndicators' +import { TabActivityIndicator } from './ActivityIndicators' import { useSettings } from '../context/SettingsContext' import { useCurrentWallet, useCurrentWalletInfo } from '../context/WalletContext' import { useServiceInfo, useSessionConnectionError } from '../context/ServiceInfoContext' @@ -34,7 +34,7 @@ const WalletPreview = ({ wallet, totalBalance, unit, showBalance }) => { ) } -const CenterNav = ({ makerRunning, cjRunning, onClick }) => { +const CenterNav = ({ makerRunning, schedulerRunning, singleCollaborativeTransactionRunning, onClick }) => { const { t } = useTranslation() return ( @@ -61,7 +61,7 @@ const CenterNav = ({ makerRunning, cjRunning, onClick }) => { >
{t('Jam')} - +
@@ -89,26 +89,21 @@ const CenterNav = ({ makerRunning, cjRunning, onClick }) => { 'center-nav-link nav-link d-flex align-items-center justify-content-center' + (isActive ? ' active' : '') } > - {t('navbar.tab_send')} +
+ {t('navbar.tab_send')} + +
) } -const TrailingNav = ({ coinjoinInProgess, onClick }) => { +const TrailingNav = ({ onClick }) => { const { t } = useTranslation() return ( - {coinjoinInProgess && ( - -
- {t('navbar.joining_in_progress')} - -
-
- )} setIsExpanded(!isExpanded)} - /> - setIsExpanded(!isExpanded)} /> + setIsExpanded(!isExpanded)} /> - +
- +
diff --git a/src/context/ServiceInfoContext.tsx b/src/context/ServiceInfoContext.tsx index f3f42ff20..2b9b9d4a0 100644 --- a/src/context/ServiceInfoContext.tsx +++ b/src/context/ServiceInfoContext.tsx @@ -10,19 +10,59 @@ import * as Api from '../libs/JmWalletApi' // interval in milliseconds for periodic session requests const SESSION_REQUEST_INTERVAL = 10_000 +type AmountFraction = number +type AmountCounterparties = number +type SchedulerDestinationAddress = 'INTERNAL' | Api.BitcoinAddress +type WaitTimeInMinutes = number +type Rounding = number +type StateFlag = 0 | 1 | Api.TxId + +// [mixdepth, amount-fraction, N-counterparties (requested), destination address, wait time in minutes, rounding, flag indicating incomplete/broadcast/completed (0/txid/1)] +// e.g. +// - [ 2, 0.2456498211214867, 4, "INTERNAL", 0.01, 16, 1 ] +// - [ 3, 0, 8, "bcrt1qpnv3nze7u6ecw63mn06ksxh497a3lryagh233q", 0.04, 16, 0 ] +type ScheduleEntry = [ + Api.Mixdepth, + AmountFraction, + AmountCounterparties, + SchedulerDestinationAddress, + WaitTimeInMinutes, + Rounding, + StateFlag +] +type Schedule = ScheduleEntry[] + +interface Offer { + oid: number + ordertype: string + minsize: Api.AmountSats + maxsize: Api.AmountSats + txfee: Api.AmountSats + cjfee: string +} + interface JmSessionData { session: boolean maker_running: boolean coinjoin_in_process: boolean wallet_name: Api.WalletName | 'None' + schedule: Schedule | null + offer_list: Offer[] | null + nickname: string | null } type SessionFlag = { sessionActive: boolean } type MakerRunningFlag = { makerRunning: boolean } type CoinjoinInProgressFlag = { coinjoinInProgress: boolean } -type WalletName = { walletName: Api.WalletName | null } -type ServiceInfo = SessionFlag & MakerRunningFlag & CoinjoinInProgressFlag & WalletName +type ServiceInfo = SessionFlag & + MakerRunningFlag & + CoinjoinInProgressFlag & { + walletName: Api.WalletName | null + schedule: Schedule | null + offers: Offer[] | null + nickname: string | null + } type ServiceInfoUpdate = ServiceInfo | MakerRunningFlag | CoinjoinInProgressFlag interface ServiceInfoContextEntry { @@ -76,15 +116,26 @@ const ServiceInfoProvider = ({ children }: React.PropsWithChildren<{}>) => { const fetch = Api.getSession({ signal, token: currentWallet?.token }) .then((res) => (res.ok ? res.json() : Api.Helper.throwError(res))) - .then((data: JmSessionData) => { + .then((data: JmSessionData): ServiceInfo => { const { session: sessionActive, maker_running: makerRunning, coinjoin_in_process: coinjoinInProgress, wallet_name: walletNameOrNoneString, + offer_list: offers, + schedule, + nickname, } = data const activeWalletName = walletNameOrNoneString !== 'None' ? walletNameOrNoneString : null - return { sessionActive, makerRunning, coinjoinInProgress, walletName: activeWalletName } as ServiceInfo + return { + walletName: activeWalletName, + sessionActive, + makerRunning, + coinjoinInProgress, + schedule, + offers, + nickname, + } }) fetchSessionInProgress.current = fetch diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index 93ab48d4e..68e6570f2 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -16,7 +16,6 @@ "tab_send": "Send", "tab_receive": "Receive", "tab_earn": "Earn", - "joining_in_progress": "Joining", "menu_mobile": "Menu", "menu_mobile_settings": "Settings" }, diff --git a/src/i18n/locales/fr/translation.json b/src/i18n/locales/fr/translation.json index 2b9f85ad8..3860e3b96 100644 --- a/src/i18n/locales/fr/translation.json +++ b/src/i18n/locales/fr/translation.json @@ -5,7 +5,6 @@ "tab_send": "Envoyer", "tab_receive": "Recevoir", "tab_earn": "Générer", - "joining_in_progress": "Joindre", "menu_mobile": "Menu", "menu_mobile_settings": "Réglages" }, diff --git a/src/libs/JmWalletApi.ts b/src/libs/JmWalletApi.ts index b8aef3c3c..dd5871090 100644 --- a/src/libs/JmWalletApi.ts +++ b/src/libs/JmWalletApi.ts @@ -15,12 +15,12 @@ const basePath = () => `${window.JM.PUBLIC_PATH}/api` export type ApiToken = string export type WalletName = `${string}.jmdat` -type Mixdepth = number +export type Mixdepth = number export type AmountSats = number // TODO: should be BigInt! Remove once every caller migrated to TypeScript. export type BitcoinAddress = string type Vout = number -type TxId = string +export type TxId = string export type UtxoId = `${TxId}:${Vout}` type WithWalletName = {