fix: fix ui updates

This commit is contained in:
Thomas Nordquist
2024-05-22 15:06:58 +02:00
parent b3a37e4794
commit c88978f0dd
12 changed files with 67 additions and 77 deletions

View File

@@ -28,10 +28,10 @@ interface Props {
} }
function useUpdateNodeWhenNodeReceivesUpdates(node?: q.TreeNode<any>) { function useUpdateNodeWhenNodeReceivesUpdates(node?: q.TreeNode<any>) {
const [lastUpdate, setLastUpdate] = useState(0) const [, setLastUpdate] = useState(0)
const updateNode = useCallback( const updateNode = useCallback(
throttle(() => { throttle(() => {
setLastUpdate(Date.now()) setLastUpdate(node ? node.lastUpdate : 0)
}, 300), }, 300),
[node] [node]
) )
@@ -52,7 +52,6 @@ function Sidebar(props: Props) {
const { classes, tree, nodePath } = props const { classes, tree, nodePath } = props
const node = usePollingToFetchTreeNode(tree, nodePath || '') const node = usePollingToFetchTreeNode(tree, nodePath || '')
useUpdateNodeWhenNodeReceivesUpdates(node) useUpdateNodeWhenNodeReceivesUpdates(node)
// console.log(node && node.path(), tree, nodePath)
return ( return (
<div id="Sidebar" className={classes.drawer}> <div id="Sidebar" className={classes.drawer}>

View File

@@ -8,7 +8,7 @@ import Popper from '@material-ui/core/Popper'
import MenuItem from '@material-ui/core/MenuItem' import MenuItem from '@material-ui/core/MenuItem'
import MenuList from '@material-ui/core/MenuList' import MenuList from '@material-ui/core/MenuList'
import WarningRounded from '@material-ui/icons/WarningRounded' import WarningRounded from '@material-ui/icons/WarningRounded'
import { IDecoder, decoders } from '../../../../../backend/src/Model/sparkplugb' import { MessageDecoder, decoders } from '../../../decoders'
import { Tooltip } from '@material-ui/core' import { Tooltip } from '@material-ui/core'
export const TopicTypeButton = (props: { node?: q.TreeNode<any> }) => { export const TopicTypeButton = (props: { node?: q.TreeNode<any> }) => {
@@ -23,7 +23,7 @@ export const TopicTypeButton = (props: { node?: q.TreeNode<any> }) => {
const [open, setOpen] = React.useState(false) const [open, setOpen] = React.useState(false)
const selectOption = useCallback( const selectOption = useCallback(
(decoder: IDecoder, format: string) => { (decoder: MessageDecoder, format: string) => {
if (!node) { if (!node) {
return return
} }
@@ -86,7 +86,7 @@ export const TopicTypeButton = (props: { node?: q.TreeNode<any> }) => {
) )
} }
function DecoderStatus({ node, decoder, format }: { node: q.TreeNode<any>; decoder: IDecoder; format: string }) { function DecoderStatus({ node, decoder, format }: { node: q.TreeNode<any>; decoder: MessageDecoder; format: string }) {
const decoded = useMemo(() => { const decoded = useMemo(() => {
return node.message?.payload && decoder.decode(node.message?.payload, format) return node.message?.payload && decoder.decode(node.message?.payload, format)
}, [node.message, decoder, format]) }, [node.message, decoder, format])

View File

@@ -1,48 +1,5 @@
import { Base64Message } from './Base64Message' import { Base64Message } from '../../../backend/src/Model/Base64Message'
import { Decoder } from './Decoder' import { MessageDecoder } from './MessageDecoder'
import { get } from 'sparkplug-payload'
var sparkplug = get('spBv1.0')
export interface IDecoder<T = string> {
/**
* Can be used to
* @param topic
*/
formats: T[]
canDecodeTopic?(topic: string): boolean
canDecodeData?(data: Base64Message): boolean
decode(input: Base64Message, format: T | string | undefined): Base64Message
}
export const SparkplugDecoder: IDecoder = {
formats: ['Sparkplug'],
canDecodeTopic(topic: string) {
return !!topic.match(/^spBv1\.0\/[^/]+\/[ND](DATA|CMD|DEATH|BIRTH)\/[^/]+(\/[^/]+)?$/u)
},
decode(input: Base64Message): Base64Message {
try {
const message = Base64Message.fromString(
JSON.stringify(
// @ts-ignore
sparkplug.decodePayload(new Uint8Array(input.toBuffer()))
)
)
message.decoder = Decoder.SPARKPLUG
return message
} catch {
const message = new Base64Message(undefined, 'Failed to decode sparkplugb payload')
message.decoder = Decoder.NONE
return message
}
},
}
export const StringDecoder: IDecoder = {
formats: ['string'],
decode(input: Base64Message): Base64Message {
return input
},
}
type BinaryFormats = type BinaryFormats =
| 'int8' | 'int8'
@@ -59,7 +16,7 @@ type BinaryFormats =
/** /**
* Binary decode primitive binary data type and arrays of these * Binary decode primitive binary data type and arrays of these
*/ */
export const BinaryDecoder: IDecoder<BinaryFormats> = { export const BinaryDecoder: MessageDecoder<BinaryFormats> = {
formats: ['int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32', 'uint64', 'float', 'double'], formats: ['int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32', 'uint64', 'float', 'double'],
decode(input: Base64Message, format: BinaryFormats): Base64Message { decode(input: Base64Message, format: BinaryFormats): Base64Message {
const decodingOption = { const decodingOption = {
@@ -89,5 +46,3 @@ export const BinaryDecoder: IDecoder<BinaryFormats> = {
return Base64Message.fromString(JSON.stringify(str.length === 1 ? str[0] : str)) return Base64Message.fromString(JSON.stringify(str.length === 1 ? str[0] : str))
}, },
} }
export const decoders = [SparkplugDecoder, BinaryDecoder, StringDecoder] as const

View File

@@ -0,0 +1,12 @@
import { Base64Message } from '../../../backend/src/Model/Base64Message'
export interface MessageDecoder<T = string> {
/**
* Can be used to
* @param topic
*/
formats: T[]
canDecodeTopic?(topic: string): boolean
canDecodeData?(data: Base64Message): boolean
decode(input: Base64Message, format: T | string | undefined): Base64Message
}

View File

@@ -0,0 +1,28 @@
import { Base64Message } from '../../../backend/src/Model/Base64Message'
import { Decoder } from '../../../backend/src/Model/Decoder'
import { get } from 'sparkplug-payload'
import { MessageDecoder } from './MessageDecoder'
var sparkplug = get('spBv1.0')
export const SparkplugDecoder: MessageDecoder = {
formats: ['Sparkplug'],
canDecodeTopic(topic: string) {
return !!topic.match(/^spBv1\.0\/[^/]+\/[ND](DATA|CMD|DEATH|BIRTH)\/[^/]+(\/[^/]+)?$/u)
},
decode(input: Base64Message): Base64Message {
try {
const message = Base64Message.fromString(
JSON.stringify(
// @ts-ignore
sparkplug.decodePayload(new Uint8Array(input.toBuffer()))
)
)
message.decoder = Decoder.SPARKPLUG
return message
} catch {
const message = new Base64Message(undefined, 'Failed to decode sparkplugb payload')
message.decoder = Decoder.NONE
return message
}
},
}

View File

@@ -0,0 +1,9 @@
import { Base64Message } from '../../../backend/src/Model/Base64Message'
import { MessageDecoder } from './MessageDecoder'
export const StringDecoder: MessageDecoder = {
formats: ['string'],
decode(input: Base64Message): Base64Message {
return input
},
}

View File

@@ -0,0 +1,6 @@
import { StringDecoder } from './StringDecoder'
import { BinaryDecoder } from './BinaryDecoder'
import { SparkplugDecoder } from './SparkplugBDecoder'
export * from './MessageDecoder'
export const decoders = [SparkplugDecoder, BinaryDecoder, StringDecoder] as const

View File

@@ -1,6 +1,6 @@
import * as q from '../../../backend/src/Model' import * as q from '../../../backend/src/Model'
import { Destroyable } from '../../../backend/src/Model/Destroyable' import { Destroyable } from '../../../backend/src/Model/Destroyable'
import { IDecoder, decoders } from '../../../backend/src/Model/sparkplugb' import { MessageDecoder, decoders } from '../decoders'
import { EventDispatcher } from '../../../events' import { EventDispatcher } from '../../../events'
function findDecoder<T extends Destroyable>(node: q.TreeNode<T>): TopicDecoder | undefined { function findDecoder<T extends Destroyable>(node: q.TreeNode<T>): TopicDecoder | undefined {
@@ -17,7 +17,7 @@ function findDecoder<T extends Destroyable>(node: q.TreeNode<T>): TopicDecoder |
: undefined : undefined
} }
type TopicDecoder = { decoder: IDecoder; format: string | undefined } type TopicDecoder = { decoder: MessageDecoder; format: string | undefined }
export class TopicViewModel implements Destroyable { export class TopicViewModel implements Destroyable {
private selected: boolean private selected: boolean

View File

@@ -33,7 +33,6 @@ export class Base64Message {
return new Base64Message(Base64.encode(str)) return new Base64Message(Base64.encode(str))
} }
/* Raw message conversions ('uint8' | 'uint16' | 'uint32' | 'uint64' | 'int8' | 'int16' | 'int32' | 'int64' | 'float' | 'double') */
public format(type: TopicDataType = 'string'): [string, 'json' | undefined] { public format(type: TopicDataType = 'string'): [string, 'json' | undefined] {
try { try {
switch (type) { switch (type) {

View File

@@ -1,24 +1,8 @@
import { Destroyable } from './Destroyable' import { Destroyable } from './Destroyable'
import { Edge, Message, RingBuffer, MessageHistory } from './' import { Edge, Message, RingBuffer, MessageHistory } from './'
import { EventDispatcher } from '../../../events' import { EventDispatcher } from '../../../events'
import { IDecoder, decoders } from './sparkplugb'
import { Base64Message } from './Base64Message'
// export type TopicDataType = 'json' | 'string' | 'hex' | 'integer' | 'unsigned int' | 'floating point' export type TopicDataType = 'string' | 'json' | 'hex'
export type TopicDataType =
| 'json'
| 'string'
| 'hex'
| 'uint8'
| 'uint16'
| 'uint32'
| 'uint64'
| 'int8'
| 'int16'
| 'int32'
| 'int64'
| 'float'
| 'double'
export class TreeNode<ViewModel extends Destroyable> { export class TreeNode<ViewModel extends Destroyable> {
public sourceEdge?: Edge<ViewModel> public sourceEdge?: Edge<ViewModel>

View File

@@ -10,7 +10,6 @@ import {
makePublishEvent, makePublishEvent,
removeConnection, removeConnection,
} from '../../events' } from '../../events'
import { SparkplugDecoder } from './Model/sparkplugb'
export class ConnectionManager { export class ConnectionManager {
private connections: { [s: string]: DataSource<any> } = {} private connections: { [s: string]: DataSource<any> } = {}

View File

@@ -19,6 +19,7 @@ registerCrashReporter()
// const electronTelemetry = electronTelemetryFactory('9b0c8ca04a361eb8160d98c5', buildOptions) // const electronTelemetry = electronTelemetryFactory('9b0c8ca04a361eb8160d98c5', buildOptions)
// } // }
// disable-dev-shm-usage is required to run the debug console
app.commandLine.appendSwitch('--no-sandbox --disable-dev-shm-usage') app.commandLine.appendSwitch('--no-sandbox --disable-dev-shm-usage')
app.whenReady().then(() => { app.whenReady().then(() => {
backendRpc.on(makeOpenDialogRpc(), async request => { backendRpc.on(makeOpenDialogRpc(), async request => {
@@ -69,8 +70,6 @@ async function createWindow() {
} }
}) })
console.log('icon path', iconPath)
mainWindow.webContents.openDevTools({ mode: 'detach' })
// Load the index.html of the app. // Load the index.html of the app.
if (isDev()) { if (isDev()) {
mainWindow.loadURL('http://localhost:8080') mainWindow.loadURL('http://localhost:8080')