Skip to content

Commit

Permalink
feat: click on active "joining" icon opens relevant screen (#463)
Browse files Browse the repository at this point in the history
* fix: pass api token to session request

(cherry picked from commit bb4a875)

* dev: add offers and nickname to ServiceInfo

(cherry picked from commit 3b3154e)

* 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
  • Loading branch information
theborakompanioni authored Aug 12, 2022
1 parent b743357 commit 033babd
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 30 deletions.
5 changes: 3 additions & 2 deletions src/components/ActivityIndicators.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react'
import Sprite from './Sprite'
import classnames from 'classnames/bind'

function ActivityIndicator({ isOn, children }) {
return (
Expand All @@ -19,9 +20,9 @@ export function JoiningIndicator({ isOn, size = 30, className, ...props }) {
)
}

export function TabActivityIndicator({ isOn }) {
export function TabActivityIndicator({ isOn, className }) {
return (
<span className="earn-indicator">
<span className={classnames('earn-indicator', className)}>
<ActivityIndicator isOn={isOn} />
</span>
)
Expand Down
41 changes: 21 additions & 20 deletions src/components/Navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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 (
Expand All @@ -61,7 +61,7 @@ const CenterNav = ({ makerRunning, cjRunning, onClick }) => {
>
<div className="d-flex align-items-start">
{t('Jam')}
<TabActivityIndicator isOn={cjRunning} />
<TabActivityIndicator isOn={schedulerRunning} />
</div>
</NavLink>
</rb.Nav.Item>
Expand Down Expand Up @@ -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')}
<div className="d-flex align-items-start">
{t('navbar.tab_send')}
<TabActivityIndicator isOn={singleCollaborativeTransactionRunning} className="ms-1" />
</div>
</NavLink>
</rb.Nav.Item>
</rb.Nav>
)
}

const TrailingNav = ({ coinjoinInProgess, onClick }) => {
const TrailingNav = ({ onClick }) => {
const { t } = useTranslation()

return (
<rb.Nav className="justify-content-center align-items-stretch">
{coinjoinInProgess && (
<rb.Nav.Item className="d-flex align-items-center justify-content-center pe-2">
<div className="d-flex align-items-center px-0">
<rb.Navbar.Text>{t('navbar.joining_in_progress')}</rb.Navbar.Text>
<JoiningIndicator isOn={coinjoinInProgess} className="navbar-text" />
</div>
</rb.Nav.Item>
)}
<rb.Nav.Item className="d-flex align-items-stretch">
<NavLink
to={routes.settings}
Expand Down Expand Up @@ -224,21 +219,27 @@ export default function Navbar() {
<rb.Offcanvas.Body>
<CenterNav
makerRunning={serviceInfo?.makerRunning}
cjRunning={serviceInfo?.coinjoinInProgress}
onClick={() => setIsExpanded(!isExpanded)}
/>
<TrailingNav
coinjoinInProgess={serviceInfo?.coinjoinInProgress}
schedulerRunning={serviceInfo?.coinjoinInProgress && serviceInfo?.schedule !== null}
singleCollaborativeTransactionRunning={
serviceInfo?.coinjoinInProgress && serviceInfo?.schedule === null
}
onClick={() => setIsExpanded(!isExpanded)}
/>
<TrailingNav onClick={() => setIsExpanded(!isExpanded)} />
</rb.Offcanvas.Body>
</rb.Navbar.Offcanvas>
<rb.Container className="d-none d-md-flex flex-1 flex-grow-0 align-items-stretch">
<CenterNav makerRunning={serviceInfo?.makerRunning} cjRunning={serviceInfo?.coinjoinInProgress} />
<CenterNav
makerRunning={serviceInfo?.makerRunning}
schedulerRunning={serviceInfo?.coinjoinInProgress && serviceInfo?.schedule !== null}
singleCollaborativeTransactionRunning={
serviceInfo?.coinjoinInProgress && serviceInfo?.schedule === null
}
/>
</rb.Container>
<rb.Container className="d-none d-md-flex flex-1 align-items-stretch">
<div className="ms-auto d-flex align-items-stretch">
<TrailingNav coinjoinInProgess={serviceInfo?.coinjoinInProgress} />
<TrailingNav />
</div>
</rb.Container>
</>
Expand Down
59 changes: 55 additions & 4 deletions src/context/ServiceInfoContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion src/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
"tab_send": "Send",
"tab_receive": "Receive",
"tab_earn": "Earn",
"joining_in_progress": "Joining",
"menu_mobile": "Menu",
"menu_mobile_settings": "Settings"
},
Expand Down
1 change: 0 additions & 1 deletion src/i18n/locales/fr/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down
4 changes: 2 additions & 2 deletions src/libs/JmWalletApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down

0 comments on commit 033babd

Please sign in to comment.