add notifications

This commit is contained in:
Tyler Shipe 2021-04-12 00:17:23 -04:00
parent c67e14ec93
commit 799b9d843c
9 changed files with 109 additions and 107 deletions

View File

@ -4,6 +4,7 @@ import useMangoStore from '../stores/useMangoStore'
import { settleAll } from '../utils/mango'
import useConnection from '../hooks/useConnection'
import Button from '../components/Button'
import { notify } from '../utils/notifications'
const BalancesTable = () => {
const balances = useBalances()
@ -26,23 +27,23 @@ const BalancesTable = () => {
markets,
wallet
)
// notify({
// message: 'Successfully settled funds',
// type: 'info',
// });
notify({
message: 'Successfully settled funds',
type: 'info',
})
} catch (e) {
console.warn('Error settling all:', e)
if (e.message === 'No unsettled funds') {
// notify({
// message: 'There are no unsettled funds',
// type: 'error',
// });
notify({
message: 'There are no unsettled funds',
type: 'error',
})
} else {
// notify({
// message: 'Error settling funds',
// description: e.message,
// type: 'error',
// });
notify({
message: 'Error settling funds',
description: e.message,
type: 'error',
})
}
}
}

View File

@ -1,8 +1,31 @@
import { useState } from 'react'
import { useEffect, useState } from 'react'
import xw from 'xwind'
import useInterval from '../hooks/useInterval'
import {
CheckCircleIcon,
InformationCircleIcon,
XCircleIcon,
} from '@heroicons/react/outline'
import useMangoStore from '../stores/useMangoStore'
const NotificationList = () => {
const setMangoStore = useMangoStore((s) => s.set)
const notifications = useMangoStore((s) => s.notifications)
console.log('notifications', notifications)
useEffect(() => {
if (notifications.length > 0) {
const id = setInterval(() => {
setMangoStore((state) => {
state.notifications = notifications.slice(1, notifications.length)
})
}, 6000)
return () => {
clearInterval(id)
}
}
}, [notifications, setMangoStore])
const NotificationList = ({ notifications }) => {
return (
<div
css={xw`fixed inset-0 flex items-end px-4 py-6 pointer-events-none sm:p-6`}
@ -10,9 +33,11 @@ const NotificationList = ({ notifications }) => {
<div css={xw`flex flex-col w-full`}>
{notifications.map((n, idx) => (
<Notification
key={`${n.title}${idx}`}
title={n.title}
key={`${n.message}${idx}`}
type={n.type}
message={n.message}
description={n.description}
txid={n.txid}
/>
))}
</div>
@ -20,13 +45,9 @@ const NotificationList = ({ notifications }) => {
)
}
const Notification = ({ title, message }) => {
const Notification = ({ type, message, description, txid }) => {
const [showNotification, setShowNotification] = useState(true)
useInterval(() => {
setShowNotification(false)
}, 6000)
if (!showNotification) return null
return (
@ -36,25 +57,20 @@ const Notification = ({ title, message }) => {
<div css={xw`p-4`}>
<div css={xw`flex items-start`}>
<div css={xw`flex-shrink-0`}>
<svg
css={xw`h-6 w-6 text-green-400`}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
aria-hidden="true"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
{type === 'success' ? (
<CheckCircleIcon css={xw`text-green-400 h-9 w-9 mr-1`} />
) : null}
{type === 'info' && (
<XCircleIcon css={xw`text-yellow-400 h-9 w-9 mr-1`} />
)}
{type === 'error' && (
<InformationCircleIcon css={xw`text-red-400 h-9 w-9 mr-1`} />
)}
</div>
<div css={xw`ml-3 w-0 flex-1 pt-0.5`}>
<p css={xw`text-sm font-medium text-gray-900`}>{title}</p>
<p css={xw`mt-1 text-sm text-gray-500`}>{message}</p>
<div css={xw`ml-2 w-0 flex-1`}>
<p css={xw`text-lg font-medium text-gray-900`}>{message}</p>
<p css={xw`mt-0.5 text-base text-gray-500`}>{description}</p>
{txid ? <p css={xw`mt-0.5 text-sm text-gray-500`}>{txid}</p> : null}
</div>
<div css={xw`ml-4 flex-shrink-0 flex`}>
<button

View File

@ -9,7 +9,7 @@ const OpenOrdersTable = () => {
<div css={xw`flex flex-col py-6`}>
<div css={xw`-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8`}>
<div css={xw`align-middle inline-block min-w-full sm:px-6 lg:px-8`}>
{openOrders ? (
{openOrders && openOrders.length > 0 ? (
<div
css={xw`shadow overflow-hidden border-b border-mango-dark-light sm:rounded-md`}
>

View File

@ -197,12 +197,11 @@ export default function TradeForm({
setPrice(undefined)
onSetBaseSize(undefined)
} catch (e) {
console.warn('Error placing trade:', e)
// notify({
// message: 'Error placing order',
// description: e.message,
// type: 'error',
// })
notify({
message: 'Error placing order',
description: e.message,
type: 'error',
})
} finally {
setSubmitting(false)
}

View File

@ -4,45 +4,7 @@ import { PublicKey, AccountInfo } from '@solana/web3.js'
import useConnection from './useConnection'
import useMangoStore from '../stores/useMangoStore'
import useMarketList from './useMarketList'
// function useOrderBookSubscribe(market) {
// const setMangoStore = useMangoStore((s) => s.set)
// const { connection } = useConnection()
// const accountPkAsString = account ? account.toString() : null
// useInterval(async () => {
// if (!account) return
// const info = await connection.getAccountInfo(account)
// console.log('fetching account info on interval', accountPkAsString)
// setMangoStore((state) => {
// state.accountInfos[accountPkAsString] = info
// })
// }, 60000)
// useEffect(() => {
// if (!account) return
// let previousInfo: AccountInfo<Buffer> | null = null
// const subscriptionId = connection.onAccountChange(account, (info) => {
// if (
// !previousInfo ||
// !previousInfo.data.equals(info.data) ||
// previousInfo.lamports !== info.lamports
// ) {
// previousInfo = info
// setMangoStore((state) => {
// state.accountInfos[accountPkAsString] = previousInfo
// })
// }
// })
// return () => {
// connection.removeAccountChangeListener(subscriptionId)
// }
// }, [account, connection])
// }
import { notify } from '../utils/notifications'
const marketAddressSelector = (s) => s.selectedMarket.address
const mangoGroupMarketsSelector = (s) => s.selectedMangoGroup.markets
@ -76,16 +38,13 @@ const useHydrateStore = () => {
state.accountInfos[bidAcccount.toString()] = bidInfo
})
})
.catch(
(e) => {
console.error('failed to load market', e)
}
// notify({
// message: 'Error loading market',
// description: e.message,
// type: 'error',
// }),
)
.catch((e) => {
notify({
message: 'Error loading market',
description: e.message,
type: 'error',
})
})
}, [selectedMarketAddress])
// load all markets for mangoGroup

View File

@ -2,6 +2,7 @@ import { useEffect } from 'react'
import Wallet from '@project-serum/sol-wallet-adapter'
import useLocalStorageState from './useLocalStorageState'
import useMangoStore from '../stores/useMangoStore'
import { notify } from '../utils/notifications'
export const WALLET_PROVIDERS = [
{ name: 'sollet.io', url: 'https://www.sollet.io' },
@ -41,7 +42,14 @@ export default function useWallet() {
setMangoStore((state) => {
state.wallet.connected = true
})
console.log('connected!')
notify({
message: 'Wallet connected',
description:
'Connected to wallet ' +
wallet.publicKey.toString().substr(0, 5) +
'...' +
wallet.publicKey.toString().substr(-5),
})
})
wallet.on('disconnect', () => {
setMangoStore((state) => {
@ -49,7 +57,10 @@ export default function useWallet() {
state.marginAccounts = []
state.selectedMarginAccount.current = null
})
console.log('wallet disconnected')
notify({
type: 'info',
message: 'Disconnected from wallet',
})
})
return () => {
wallet.disconnect()

View File

@ -15,12 +15,7 @@ const Index = () => {
<MarketSelect />
<TradePageGrid />
</div>
<Notifications
notifications={[
{ title: 'test', message: 'ok' },
{ title: 'test2', message: 'ok2' },
]}
/>
<Notifications />
</div>
)
}

View File

@ -39,6 +39,12 @@ interface AccountInfoList {
}
interface MangoStore extends State {
notifications: Array<{
type: string
message: string
description?: string
txid?: string
}>
accountInfos: AccountInfoList
connection: {
cluster: string
@ -85,6 +91,7 @@ interface MangoStore extends State {
const useMangoStore = create<MangoStore>(
devtools((set, get) => ({
notifications: [],
accountInfos: {},
connection: {
cluster: CLUSTER,

View File

@ -1,3 +1,17 @@
export function notify(args) {
console.log(`-=-notify:`, args)
import useMangoStore from '../stores/useMangoStore'
export function notify(newNotification: {
type?: string
message: string
description?: string
txid?: string
}) {
const setMangoStore = useMangoStore.getState().set
setMangoStore((state) => {
state.notifications = [
...state.notifications,
{ type: 'success', ...newNotification },
]
})
}