Skip to content

Commit cdb6c7f

Browse files
authored
feat: implement state action items in timeline (#49)
* implement state action items in timeline * fix color * fix MST type
1 parent 43ca42b commit cdb6c7f

File tree

7 files changed

+84
-4
lines changed

7 files changed

+84
-4
lines changed

app/components/DetailPanel.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ export function DetailPanel({ selectedItem, onClose }: DetailPanelProps) {
4545

4646
const getHeaderTitle = () => {
4747
switch (selectedItem.type) {
48+
case CommandType.StateActionComplete:
49+
return "State Action Details"
4850
case CommandType.Log:
4951
return "Log Details"
5052
case CommandType.Display:
@@ -60,6 +62,8 @@ export function DetailPanel({ selectedItem, onClose }: DetailPanelProps) {
6062

6163
const renderDetailContent = () => {
6264
switch (selectedItem.type) {
65+
case CommandType.StateActionComplete:
66+
return <StateActionDetailContent item={selectedItem} />
6367
case CommandType.Log:
6468
return <LogDetailContent item={selectedItem} />
6569
case CommandType.Display:
@@ -119,6 +123,26 @@ export function DetailPanel({ selectedItem, onClose }: DetailPanelProps) {
119123
)
120124
}
121125

126+
function StateActionDetailContent({
127+
item,
128+
}: {
129+
item: TimelineItem & { type: typeof CommandType.StateActionComplete }
130+
}) {
131+
const {
132+
payload: { action, name },
133+
} = item
134+
return (
135+
<View style={$detailContent()}>
136+
<DetailSection title="Type">
137+
<Text style={$valueText()}>{name}</Text>
138+
</DetailSection>
139+
<DetailSection title="Payload">
140+
<TreeViewWithProvider data={action.payload} />
141+
</DetailSection>
142+
</View>
143+
)
144+
}
145+
122146
function DisplayDetailContent({
123147
item,
124148
}: {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { CommandType } from "reactotron-core-contract"
2+
import { TimelineItem } from "./TimelineItem"
3+
import { TimelineItemStateActionComplete } from "../types"
4+
5+
type TimelineStateActionItemProps = {
6+
item: TimelineItemStateActionComplete
7+
isSelected?: boolean
8+
onSelect?: () => void
9+
}
10+
11+
/**
12+
* A single display item in the timeline.
13+
*/
14+
export function TimelineStateActionItem({
15+
item,
16+
isSelected = false,
17+
onSelect,
18+
}: TimelineStateActionItemProps) {
19+
const { payload, date, deltaTime, important } = item
20+
21+
// Type guard to ensure this is a display item
22+
if (item.type !== CommandType.StateActionComplete) return null
23+
24+
return (
25+
<TimelineItem
26+
title={"ACTION"}
27+
date={new Date(date)}
28+
deltaTime={deltaTime}
29+
preview={payload.name}
30+
isImportant={important}
31+
isTagged={important}
32+
isSelected={isSelected}
33+
onSelect={onSelect}
34+
/>
35+
)
36+
}

app/components/TimelineToolbar.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export type FilterType =
55
| typeof CommandType.Log
66
| typeof CommandType.Display
77
| typeof CommandType.ApiResponse
8+
| typeof CommandType.StateActionComplete
89
| typeof CommandType.Benchmark
910
// export type LogLevel = "all" | "debug" | "warn" | "error"
1011
// export type SortBy = "time-newest" | "time-oldest" | "type" | "level"

app/screens/TimelineScreen.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { MenuItemId } from "app/components/Sidebar/SidebarMenu"
1818
import { useEffect } from "react"
1919
import { FilterType } from "../components/TimelineToolbar"
2020
import { ClearLogsButton } from "../components/ClearLogsButton"
21+
import { TimelineStateActionItem } from "../components/TimelineStateActionItem"
2122

2223
/**
2324
* Renders the correct component for each timeline item.
@@ -48,6 +49,11 @@ const TimelineItemRenderer = ({
4849
if (item.type === CommandType.ApiResponse) {
4950
return <TimelineNetworkItem item={item} isSelected={isSelected} onSelect={handleSelectItem} />
5051
}
52+
if (item.type === CommandType.StateActionComplete) {
53+
return (
54+
<TimelineStateActionItem item={item} isSelected={isSelected} onSelect={handleSelectItem} />
55+
)
56+
}
5157
if (item.type === CommandType.Benchmark) {
5258
return (
5359
<TimelineBenchmmarkItem item={item} isSelected={isSelected} onSelect={handleSelectItem} />
@@ -60,13 +66,19 @@ const TimelineItemRenderer = ({
6066
function getTimelineTypes(activeItem: MenuItemId): FilterType[] {
6167
switch (activeItem) {
6268
case "logs":
63-
return [CommandType.Log, CommandType.Display]
69+
return [CommandType.Log, CommandType.Display, CommandType.StateActionComplete]
6470
case "network":
6571
return [CommandType.ApiResponse]
6672
case "performance":
6773
return [CommandType.Benchmark]
6874
default:
69-
return [CommandType.Log, CommandType.Display, CommandType.ApiResponse, CommandType.Benchmark]
75+
return [
76+
CommandType.Log,
77+
CommandType.Display,
78+
CommandType.ApiResponse,
79+
CommandType.Benchmark,
80+
CommandType.StateActionComplete,
81+
]
7082
}
7183
}
7284

app/state/connectToServer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,11 @@ export function connectToServer(props: { port: number } = { port: 9292 }): Unsub
9595

9696
if (data.type === "command" && data.cmd) {
9797
if (data.cmd.type === CommandType.Clear) setTimelineItems([])
98-
9998
if (
10099
data.cmd.type === CommandType.Log ||
101100
data.cmd.type === CommandType.ApiResponse ||
102101
data.cmd.type === CommandType.Display ||
102+
data.cmd.type === CommandType.StateActionComplete ||
103103
data.cmd.type === CommandType.Benchmark
104104
) {
105105
// Add a unique ID to the timeline item

app/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type {
1111
StateBackupRequestPayload,
1212
StateRestoreRequestPayload,
1313
Command,
14+
StateActionCompletePayload,
1415
} from "reactotron-core-contract"
1516

1617
/**
@@ -144,10 +145,16 @@ export type TimelineItemDisplay = TimelineItemBase & {
144145
payload: DisplayPayload
145146
}
146147

148+
export type TimelineItemStateActionComplete = TimelineItemBase & {
149+
type: typeof CommandType.StateActionComplete
150+
payload: StateActionCompletePayload
151+
}
152+
147153
export type TimelineItem =
148154
| TimelineItemLog
149155
| TimelineItemNetwork
150156
| TimelineItemDisplay
157+
| TimelineItemStateActionComplete
151158
| TimelineItemBenchmark
152159

153160
// StateSubscription represents a single state path/value pair tracked by the app

macos/Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1779,7 +1779,7 @@ SPEC CHECKSUMS:
17791779
glog: b7594b792ee4e02ed1f44b01d046ca25fa713e3d
17801780
hermes-engine: b5c9cfbe6415f1b0b24759f2942c8f33e9af6347
17811781
IRNativeModules: 2fa316ab0ca91ec3e7bd4ba7ab2fc1f642fb5542
1782-
RCT-Folly: abec2d7f4af402b4957c44e86ceff8725b23c1b4
1782+
RCT-Folly: e8b53d8c0d2d9df4a6a8b0a368a1a91fc62a88cb
17831783
RCTDeprecation: 9da6c2d8a3b1802142718283260fb06d702ddb07
17841784
RCTRequired: 574f9d55bda1d50676530b6c36bab4605612dfb6
17851785
RCTTypeSafety: 7de929c405e619c023116e7747118a2c5d5b2320

0 commit comments

Comments
 (0)