mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-08-07 05:52:31 -04:00
feat(cli+tauri): Send logs from host to guest (#90)
* feat(tauri): send logs from cli to tauri --------- Co-authored-by: binarybaron <binarybaron@unstoppableswap.net> Co-authored-by: binarybaron <86064887+binarybaron@users.noreply.github.com>
This commit is contained in:
parent
21608ce4f7
commit
7b79ad6abe
14 changed files with 206 additions and 136 deletions
|
@ -37,7 +37,7 @@ export function parseCliLogString(log: string): CliLog | string {
|
|||
} else {
|
||||
return log;
|
||||
}
|
||||
} catch (err) {
|
||||
} catch {
|
||||
return log;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
CircularProgress,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
|
@ -15,14 +14,9 @@ import {
|
|||
import AddIcon from "@material-ui/icons/Add";
|
||||
import SearchIcon from "@material-ui/icons/Search";
|
||||
import { ExtendedProviderStatus } from "models/apiModel";
|
||||
import { RpcMethod } from "models/rpcModel";
|
||||
import { useState } from "react";
|
||||
import { setSelectedProvider } from "store/features/providersSlice";
|
||||
import {
|
||||
useAllProviders,
|
||||
useAppDispatch,
|
||||
useIsRpcEndpointBusy,
|
||||
} from "store/hooks";
|
||||
import { useAllProviders, useAppDispatch } from "store/hooks";
|
||||
import ListSellersDialog from "../listSellers/ListSellersDialog";
|
||||
import ProviderInfo from "./ProviderInfo";
|
||||
import ProviderSubmitDialog from "./ProviderSubmitDialog";
|
||||
|
@ -65,13 +59,11 @@ export function ProviderSubmitDialogOpenButton() {
|
|||
|
||||
export function ListSellersDialogOpenButton() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const running = useIsRpcEndpointBusy(RpcMethod.LIST_SELLERS);
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
autoFocus
|
||||
button
|
||||
disabled={running}
|
||||
onClick={() => {
|
||||
// Prevents background from being clicked and reopening dialog
|
||||
if (!open) {
|
||||
|
@ -81,7 +73,9 @@ export function ListSellersDialogOpenButton() {
|
|||
>
|
||||
<ListSellersDialog open={open} onClose={() => setOpen(false)} />
|
||||
<ListItemAvatar>
|
||||
<Avatar>{running ? <CircularProgress /> : <SearchIcon />}</Avatar>
|
||||
<Avatar>
|
||||
<SearchIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary="Discover providers by connecting to a rendezvous point" />
|
||||
</ListItem>
|
||||
|
|
|
@ -3,7 +3,7 @@ import FolderOpenIcon from "@material-ui/icons/FolderOpen";
|
|||
import PlayArrowIcon from "@material-ui/icons/PlayArrow";
|
||||
import StopIcon from "@material-ui/icons/Stop";
|
||||
import PromiseInvokeButton from "renderer/components/PromiseInvokeButton";
|
||||
import { useIsContextAvailable } from "store/hooks";
|
||||
import { useAppSelector, useIsContextAvailable } from "store/hooks";
|
||||
import InfoBox from "../../modal/swap/InfoBox";
|
||||
import CliLogsBox from "../../other/RenderedCliLog";
|
||||
|
||||
|
@ -18,17 +18,16 @@ const useStyles = makeStyles((theme) => ({
|
|||
export default function RpcControlBox() {
|
||||
const isRunning = useIsContextAvailable();
|
||||
const classes = useStyles();
|
||||
const logs = useAppSelector((s) => s.rpc.logs);
|
||||
|
||||
return (
|
||||
<InfoBox
|
||||
title={`Daemon Controller`}
|
||||
mainContent={
|
||||
isRunning ? (
|
||||
<CliLogsBox
|
||||
label="Swap Daemon Logs (current session only)"
|
||||
logs={[]}
|
||||
/>
|
||||
) : null
|
||||
<CliLogsBox
|
||||
label="Swap Daemon Logs (current session only)"
|
||||
logs={logs}
|
||||
/>
|
||||
}
|
||||
additionalContent={
|
||||
<Box className={classes.actionsOuter}>
|
||||
|
|
|
@ -3,7 +3,7 @@ import SendIcon from "@material-ui/icons/Send";
|
|||
import { RpcMethod } from "models/rpcModel";
|
||||
import { useState } from "react";
|
||||
import { SatsAmount } from "renderer/components/other/Units";
|
||||
import { useAppSelector, useIsRpcEndpointBusy } from "store/hooks";
|
||||
import { useAppSelector } from "store/hooks";
|
||||
import BitcoinIcon from "../../icons/BitcoinIcon";
|
||||
import InfoBox from "../../modal/swap/InfoBox";
|
||||
import WithdrawDialog from "../../modal/wallet/WithdrawDialog";
|
||||
|
@ -20,7 +20,6 @@ const useStyles = makeStyles((theme) => ({
|
|||
export default function WithdrawWidget() {
|
||||
const classes = useStyles();
|
||||
const walletBalance = useAppSelector((state) => state.rpc.state.balance);
|
||||
const checkingBalance = useIsRpcEndpointBusy(RpcMethod.GET_BTC_BALANCE);
|
||||
const [showDialog, setShowDialog] = useState(false);
|
||||
|
||||
function onShowDialog() {
|
||||
|
@ -50,7 +49,7 @@ export default function WithdrawWidget() {
|
|||
size="large"
|
||||
onClick={onShowDialog}
|
||||
disabled={
|
||||
walletBalance === null || checkingBalance || walletBalance <= 0
|
||||
walletBalance === null || walletBalance <= 0
|
||||
}
|
||||
>
|
||||
Withdraw
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
BalanceResponse,
|
||||
BuyXmrArgs,
|
||||
BuyXmrResponse,
|
||||
CliLogEmittedEvent,
|
||||
GetLogsArgs,
|
||||
GetLogsResponse,
|
||||
GetSwapInfoResponse,
|
||||
|
@ -20,6 +21,7 @@ import {
|
|||
} from "models/tauriModel";
|
||||
import {
|
||||
contextStatusEventReceived,
|
||||
receivedCliLog,
|
||||
rpcSetBalance,
|
||||
rpcSetSwapInfo,
|
||||
} from "store/features/rpcSlice";
|
||||
|
@ -47,6 +49,11 @@ export async function initEventListeners() {
|
|||
console.log("Received context init progress event", event.payload);
|
||||
store.dispatch(contextStatusEventReceived(event.payload));
|
||||
});
|
||||
|
||||
listen<CliLogEmittedEvent>("cli-log-emitted", (event) => {
|
||||
console.log("Received cli log event", event.payload);
|
||||
store.dispatch(receivedCliLog(event.payload))
|
||||
})
|
||||
}
|
||||
|
||||
async function invoke<ARGS, RESPONSE>(
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import { ExtendedProviderStatus, ProviderStatus } from "models/apiModel";
|
||||
import {
|
||||
CliLogEmittedEvent,
|
||||
GetSwapInfoResponse,
|
||||
TauriContextStatusEvent,
|
||||
} from "models/tauriModel";
|
||||
import { MoneroRecoveryResponse } from "../../models/rpcModel";
|
||||
import { GetSwapInfoResponseExt } from "models/tauriModelExt";
|
||||
import { getLogsAndStringsFromRawFileString } from "utils/parseUtils";
|
||||
import { CliLog } from "models/cliModel";
|
||||
|
||||
interface State {
|
||||
balance: number | null;
|
||||
|
@ -27,7 +30,7 @@ interface State {
|
|||
export interface RPCSlice {
|
||||
status: TauriContextStatusEvent | null;
|
||||
state: State;
|
||||
busyEndpoints: string[];
|
||||
logs: (CliLog | string)[];
|
||||
}
|
||||
|
||||
const initialState: RPCSlice = {
|
||||
|
@ -42,13 +45,18 @@ const initialState: RPCSlice = {
|
|||
updateState: false,
|
||||
},
|
||||
},
|
||||
busyEndpoints: [],
|
||||
logs: [],
|
||||
};
|
||||
|
||||
export const rpcSlice = createSlice({
|
||||
name: "rpc",
|
||||
initialState,
|
||||
reducers: {
|
||||
receivedCliLog(slice, action: PayloadAction<CliLogEmittedEvent>) {
|
||||
const buffer = action.payload.buffer;
|
||||
const logs = getLogsAndStringsFromRawFileString(buffer);
|
||||
slice.logs = slice.logs.concat(logs);
|
||||
},
|
||||
contextStatusEventReceived(
|
||||
slice,
|
||||
action: PayloadAction<TauriContextStatusEvent>,
|
||||
|
@ -74,17 +82,6 @@ export const rpcSlice = createSlice({
|
|||
slice.state.swapInfos[action.payload.swap_id] =
|
||||
action.payload as GetSwapInfoResponseExt;
|
||||
},
|
||||
rpcSetEndpointBusy(slice, action: PayloadAction<string>) {
|
||||
if (!slice.busyEndpoints.includes(action.payload)) {
|
||||
slice.busyEndpoints.push(action.payload);
|
||||
}
|
||||
},
|
||||
rpcSetEndpointFree(slice, action: PayloadAction<string>) {
|
||||
const index = slice.busyEndpoints.indexOf(action.payload);
|
||||
if (index >= 0) {
|
||||
slice.busyEndpoints.splice(index);
|
||||
}
|
||||
},
|
||||
rpcSetMoneroRecoveryKeys(
|
||||
slice,
|
||||
action: PayloadAction<[string, MoneroRecoveryResponse]>,
|
||||
|
@ -105,11 +102,10 @@ export const rpcSlice = createSlice({
|
|||
|
||||
export const {
|
||||
contextStatusEventReceived,
|
||||
receivedCliLog,
|
||||
rpcSetBalance,
|
||||
rpcSetWithdrawTxId,
|
||||
rpcResetWithdrawTxId,
|
||||
rpcSetEndpointBusy,
|
||||
rpcSetEndpointFree,
|
||||
rpcSetRendezvousDiscoveredProviders,
|
||||
rpcSetSwapInfo,
|
||||
rpcSetMoneroRecoveryKeys,
|
||||
|
|
|
@ -42,10 +42,6 @@ export function useActiveSwapInfo() {
|
|||
return useSwapInfo(swapId);
|
||||
}
|
||||
|
||||
export function useIsRpcEndpointBusy(method: string) {
|
||||
return useAppSelector((state) => state.rpc.busyEndpoints.includes(method));
|
||||
}
|
||||
|
||||
export function useAllProviders() {
|
||||
return useAppSelector((state) => {
|
||||
const registryProviders = state.providers.registry.providers || [];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { CliLog } from "models/cliModel";
|
||||
import { CliLog, parseCliLogString } from "models/cliModel";
|
||||
import { Multiaddr } from "multiaddr";
|
||||
|
||||
/*
|
||||
|
@ -55,19 +55,7 @@ export function getLinesOfString(data: string): string[] {
|
|||
export function getLogsAndStringsFromRawFileString(
|
||||
rawFileData: string,
|
||||
): (CliLog | string)[] {
|
||||
return getLinesOfString(rawFileData).map((line) => {
|
||||
try {
|
||||
return JSON.parse(line);
|
||||
} catch {
|
||||
return line;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function getLogsFromRawFileString(rawFileData: string): CliLog[] {
|
||||
// TODO: Reimplement this using Tauri
|
||||
return [];
|
||||
return getLogsAndStringsFromRawFileString(rawFileData).filter(isCliLog);
|
||||
return getLinesOfString(rawFileData).map(parseCliLogString);
|
||||
}
|
||||
|
||||
export function logsToRawString(logs: (CliLog | string)[]): string {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue