diff --git a/wallets/client/components/logger.js b/wallets/client/components/logger.js
index 881a593d..a67a2ae8 100644
--- a/wallets/client/components/logger.js
+++ b/wallets/client/components/logger.js
@@ -5,6 +5,7 @@ import { useCallback, useEffect, useState, Fragment } from 'react'
import { timeSince } from '@/lib/time'
import classNames from 'classnames'
import { ModalClosedError } from '@/components/modal'
+import { isTemplate } from '@/wallets/lib/util'
// TODO(wallet-v2):
// when we delete logs for a protocol, the cache is not updated
@@ -28,40 +29,105 @@ export function WalletLogs ({ protocol, className, debug }) {
const embedded = !!protocol
+ // avoid unnecessary clutter when attaching new wallet
+ const hideLogs = logs.length === 0 && protocol && isTemplate(protocol)
+ if (hideLogs) return null
+
+ // showing delete button and logs footer for temporary template logs is unnecessary clutter
+ const template = protocol && isTemplate(protocol)
+
return (
- <>
-
- clear logs
-
-
+
+ {!template && (
+
+ clear logs
+
+
+ )}
{logs.map((log, i) => (
))}
- {loading
- ?
loading...
- : logs.length === 0 &&
empty
}
- {hasMore
- ?
- :
------ start of logs ------
}
+ {!template &&
}
+
+ )
+}
+
+function WalletLogsFooter ({ empty, loading, hasMore, loadMore }) {
+ return (
+ <>
+ {loading
+ ? loading...
+ : empty && empty
}
+ {hasMore
+ ?
+ : ------ start of logs ------
}
>
)
}
export function LogMessage ({ tag, level, message, context, ts }) {
- const [show, setShow] = useState(false)
+ const [showContext, setShowContext] = useState(false)
+ const filtered = context
+ ? Object.keys(context)
+ .filter(key => !['send', 'recv', 'status'].includes(key))
+ .reduce((obj, key) => {
+ obj[key] = context[key]
+ return obj
+ }, {})
+ : {}
+
+ const hasContext = context && Object.keys(filtered).length > 0
+ const handleClick = () => {
+ if (hasContext) { setShowContext(show => !show) }
+ }
+ const style = hasContext ? { cursor: 'pointer' } : { cursor: 'inherit' }
+
+ return (
+ <>
+
+
+ {tag !== null && }
+
+
+ {hasContext && }
+
+ {hasContext && showContext && }
+ >
+ )
+}
+
+function TimeSince ({ timestamp }) {
+ const [time, setTime] = useState(timeSince(new Date(timestamp)))
+
+ useEffect(() => {
+ const timer = setInterval(() => {
+ setTime(timeSince(new Date(timestamp)))
+ }, 1000)
+
+ return () => clearInterval(timer)
+ }, [timestamp])
+
+ return {time}
+}
+
+function Tag ({ tag }) {
+ return {`[${tag}]`}
+}
+
+function Level ({ level }) {
let className
switch (level.toLowerCase()) {
case 'ok':
@@ -80,69 +146,29 @@ export function LogMessage ({ tag, level, message, context, ts }) {
className = 'text-muted'; break
}
- const filtered = context
- ? Object.keys(context)
- .filter(key => !['send', 'recv', 'status'].includes(key))
- .reduce((obj, key) => {
- obj[key] = context[key]
- return obj
- }, {})
- : {}
+ return {level}
+}
- const hasContext = context && Object.keys(filtered).length > 0
+function Message ({ message }) {
+ return {message}
+}
- const handleClick = () => {
- if (hasContext) { setShow(show => !show) }
- }
-
- const style = hasContext ? { cursor: 'pointer' } : { cursor: 'inherit' }
- const indicator = hasContext ? (show ? '-' : '+') : <>>
-
- // TODO(wallet-v2): show invoice context
+function Indicator ({ show }) {
+ return {show ? '-' : '+'}
+}
+function Context ({ context }) {
return (
- <>
-
-
-
{`[${nameToTag(tag)}]`}
-
{level}
-
{message}
-
{indicator}
-
- {show && hasContext && (
-
- {Object.entries(filtered)
- .map(([key, value], i) => {
- return (
-
- {key}:
- {value}
-
- )
- })}
-
- )}
- >
+
+ {Object.entries(context)
+ .map(([key, value], i) => {
+ return (
+
+ {key}:
+ {value}
+
+ )
+ })}
+
)
}
-
-function nameToTag (name) {
- switch (name) {
- case undefined: return 'system'
- default: return name.toLowerCase()
- }
-}
-
-function TimeSince ({ timestamp }) {
- const [time, setTime] = useState(timeSince(new Date(timestamp)))
-
- useEffect(() => {
- const timer = setInterval(() => {
- setTime(timeSince(new Date(timestamp)))
- }, 1000)
-
- return () => clearInterval(timer)
- }, [timestamp])
-
- return {time}
-}
diff --git a/wallets/client/hooks/logger.js b/wallets/client/hooks/logger.js
index 58db41da..27279022 100644
--- a/wallets/client/hooks/logger.js
+++ b/wallets/client/hooks/logger.js
@@ -88,21 +88,21 @@ export function useWalletLogs (protocol, debug) {
const { templateLogs, clearTemplateLogs } = useContext(TemplateLogsContext)
const [cursor, setCursor] = useState(null)
- // if we're configuring a protocol template, there are no logs to fetch
- const skip = protocol && isTemplate(protocol)
- const [logs, setLogs] = useState(skip ? templateLogs : [])
+ const [logs, setLogs] = useState([])
// if no protocol was given, we want to fetch all logs
const protocolId = protocol ? Number(protocol.id) : undefined
+ // if we're configuring a protocol template, there are no logs to fetch
+ const noFetch = protocol && isTemplate(protocol)
const [fetchLogs, { called, loading, error }] = useLazyQuery(WALLET_LOGS, {
variables: { protocolId, debug },
- skip,
+ skip: noFetch,
fetchPolicy: 'network-only'
})
useEffect(() => {
- if (skip) return
+ if (noFetch) return
const interval = setInterval(async () => {
const { data, error } = await fetchLogs({ variables: { protocolId, debug } })
@@ -118,7 +118,7 @@ export function useWalletLogs (protocol, debug) {
}, FAST_POLL_INTERVAL)
return () => clearInterval(interval)
- }, [fetchLogs, called, skip, debug])
+ }, [fetchLogs, called, noFetch, debug])
const loadMore = useCallback(async () => {
const { data } = await fetchLogs({ variables: { protocolId, cursor, debug } })
@@ -135,14 +135,14 @@ export function useWalletLogs (protocol, debug) {
return useMemo(() => {
return {
- loading: skip ? false : (!called ? true : loading),
- logs: skip ? templateLogs : logs,
+ loading: noFetch ? false : (!called ? true : loading),
+ logs: noFetch ? templateLogs : logs,
error,
loadMore,
hasMore: cursor !== null,
clearLogs
}
- }, [loading, skip, called, templateLogs, logs, error, loadMore, clearLogs])
+ }, [loading, noFetch, called, templateLogs, logs, error, loadMore, clearLogs])
}
function mapLevelToConsole (level) {