diff --git a/src/client/components/ActivityDetail.tsx b/src/client/components/ActivityDetail.tsx
index ab626a66..f9c39b08 100644
--- a/src/client/components/ActivityDetail.tsx
+++ b/src/client/components/ActivityDetail.tsx
@@ -28,7 +28,6 @@ export const ActivityDetails = (props: ActivityDetailProps) => {
}
} = props;
- debugger;
const [collapsibleOpen, setCollapsibleOpen] = useState(undefined);
return (
@@ -62,7 +61,7 @@ export const ActivityDetails = (props: ActivityDetailProps) => {
- {scrobble !== undefined ? : null}
+
diff --git a/src/client/components/ActivityTimeline.tsx b/src/client/components/ActivityTimeline.tsx
index e5f3257e..6d446ae9 100644
--- a/src/client/components/ActivityTimeline.tsx
+++ b/src/client/components/ActivityTimeline.tsx
@@ -51,8 +51,6 @@ export const ActivityTimeline = (props: ActivityDetailProps) => {
} = {}
} = play;
- const [scrobbleCollapsibleOpen, setScrobbleCollapsibleOpen] = useState(false);
-
return (
diff --git a/src/client/components/JsonDiff.tsx b/src/client/components/JsonDiff.tsx
index e893d332..e3e7b5cd 100644
--- a/src/client/components/JsonDiff.tsx
+++ b/src/client/components/JsonDiff.tsx
@@ -24,18 +24,20 @@ export type JsonDiffPatchProps = MarkOptional & {
export const JsonDiffPatch = (props: JsonDiffPatchProps) => {
const {
right,
+ left,
diff,
...rest
} = props;
+ const detachedLeft = JSON.parse(JSON.stringify(left));
let realRight: DiffableVal;
if (right !== undefined) {
- realRight = right;
+ realRight = JSON.parse(JSON.stringify(right));
} else if (diff !== undefined) {
- realRight = jdiff.patch(props.left, diff as Delta) as DiffableVal;
+ realRight = jdiff.patch(JSON.parse(JSON.stringify(left)), diff as Delta) as DiffableVal;
} else {
throw new Error(`must provide either 'right' or 'diff'`);
}
return
-
+
};
\ No newline at end of file
diff --git a/src/client/components/ScrobbleActionResult.tsx b/src/client/components/ScrobbleActionResult.tsx
index d1dac7ed..0221a585 100644
--- a/src/client/components/ScrobbleActionResult.tsx
+++ b/src/client/components/ScrobbleActionResult.tsx
@@ -15,7 +15,7 @@ import { MSCollapsible, MSCollapsibleExternalProps } from "./MSCollapsible";
import { TimelineErrorIcon } from "./timeline/TimelineIcon";
export interface ScrobbleActionResultProps extends MSCollapsibleExternalProps {
- result: ScrobbleResult,
+ result: ScrobbleResult,
scrobbler?: string,
}
diff --git a/src/client/components/TransformSteps.tsx b/src/client/components/TransformSteps.tsx
index 03c6cb32..c2f43695 100644
--- a/src/client/components/TransformSteps.tsx
+++ b/src/client/components/TransformSteps.tsx
@@ -1,5 +1,5 @@
import { ComponentProps, Fragment } from "react"
-import { Timeline, Icon, Span, Stack, Heading, Box } from '@chakra-ui/react';
+import { Timeline, Icon, Span, Stack, Heading, Box, Text } from '@chakra-ui/react';
import { JsonPlayObject, LifecycleStep } from "../../core/Atomic";
import { PlayData } from "./PlayData";
import { ErrorAlert } from "./ErrorAlert";
@@ -22,12 +22,8 @@ export const TransformSteps = (props: LifeycleStepsTimelineProps) => {
collapsibleOpen
} = props;
- let currentPlay: JsonPlayObject | false = JSON.parse(JSON.stringify(original));
- if(currentPlay !== false) {
- currentPlay.data.meta = {
- ...(currentPlay.data.meta ?? {}),
- }
- }
+ let currentPlay: JsonPlayObject = JSON.parse(JSON.stringify(original)),
+ patchFailed = false;
return (
@@ -39,27 +35,48 @@ export const TransformSteps = (props: LifeycleStepsTimelineProps) => {
name
} = x;
let err: Error;
- const left = currentPlay !== false ? JSON.parse(JSON.stringify(currentPlay)) : false;
- if (currentPlay !== false && patch !== undefined) {
+
+ let left: JsonPlayObject;
+ if(!patchFailed) {
+ left = JSON.parse(JSON.stringify(currentPlay));
+ left.data.meta = {
+ ...(left.data.meta ?? {}),
+ brainz: {
+ ...(left.data.meta?.brainz ?? {})
+ }
+ }
+ currentPlay.data.meta = {
+ ...(currentPlay.data.meta ?? {}),
+ brainz: {
+ ...(currentPlay.data.meta?.brainz ?? {})
+ }
+ }
+ }
+
+ if (!patchFailed && patch !== undefined) {
try {
currentPlay = jdiff.patch(currentPlay, patch) as JsonPlayObject;
} catch (e) {
err = new Error('Could not patch Play object', { cause: e });
- currentPlay = false;
+ patchFailed = true;
}
- } else {
- currentPlay = false;
}
let diffElm: JSX.Element;
- if(left !== false && currentPlay !== false) {
- diffElm =
-
- ;
- } else if(patch !== undefined) {
- diffElm = ;
+
+ if(err) {
+ diffElm =
+ } else if(patch === undefined) {
+ diffElm = Play was identical after Transform.
+ } else if(patchFailed) {
+ diffElm =
+ } else {
+ diffElm =
+
+ ;
}
+
const showAnyDetails = inputs !== undefined || diffElm !== undefined || err !== undefined;
- return
+ return
@@ -75,14 +92,14 @@ export const TransformSteps = (props: LifeycleStepsTimelineProps) => {
{showAnyDetails ?
- {err !== undefined ? : null}
- {diffElm !== undefined ? Diff{diffElm} : null }
+ Diff
+ {diffElm}
{inputs !== undefined ? (
Inputs
- {x.inputs.map((y) => {
- return
+ {x.inputs.map((y, inputsIndex) => {
+ return
})}
) : null}
@@ -91,7 +108,7 @@ export const TransformSteps = (props: LifeycleStepsTimelineProps) => {
})}
{currentPlay !== false ? (
-
+
diff --git a/src/core/Atomic.ts b/src/core/Atomic.ts
index 7dd123be..61789966 100644
--- a/src/core/Atomic.ts
+++ b/src/core/Atomic.ts
@@ -288,20 +288,20 @@ export interface PlayObjectLifecycleless {
export type ErrorLike = Error | ErrorObject;
-export interface ScrobbleResult {
- match?: PlayMatchResult
+export interface ScrobbleResult {
+ match?: PlayMatchResult
payload?: ScrobblePayload
warnings?: string[]
error?: Error | ErrorObject
response?: ScrobbleResponse
- mergedScrobble?: PlayObjectLifecycleless
+ mergedScrobble?: PlayObjectLifecycleless
}
export interface PlayLifecycle {
input?: object
original: PlayObjectLifecycleless
steps: LifecycleStep[]
- scrobble?: ScrobbleResult
+ scrobble?: ScrobbleResult
}
export interface LifecycleStep {
@@ -314,10 +314,10 @@ export interface LifecycleStep {
export type ScrobblePayload = object | string;
export type ScrobbleResponse = object | string;
-export interface ScrobbleActionResult {
+export interface ScrobbleActionResult {
payload: ScrobblePayload,
response?: ScrobbleResponse,
- mergedScrobble?: PlayObject
+ mergedScrobble?: AmbPlayObject
warnings?: string[]
}
diff --git a/src/core/tests/utils/fixtures.ts b/src/core/tests/utils/fixtures.ts
index 4f781b2e..9ce1bbfa 100644
--- a/src/core/tests/utils/fixtures.ts
+++ b/src/core/tests/utils/fixtures.ts
@@ -98,6 +98,10 @@ export interface GeneratePlayWithLifecycleOptions {
data?: ObjectPlayData,
meta?: MarkOptional
opts?: GeneratePlayOpts
+ },
+ lifecycleSteps?: {
+ preCompare?: boolean | number
+ postCompare?: boolean | number
}
}
@@ -105,6 +109,10 @@ export const generatePlayWithLifecycle = (opts: GeneratePlayWithLifecycleOptions
const {
original: originalOpts = {},
+ lifecycleSteps: {
+ preCompare = true,
+ postCompare = true
+ } = {}
} = opts;
const original = generatePlay(originalOpts.data, originalOpts.meta, originalOpts.opts);
@@ -120,25 +128,42 @@ export const generatePlayWithLifecycle = (opts: GeneratePlayWithLifecycleOptions
let steps: LifecycleStep[] = [];
let transformedPlay = clone(original);
- const firstStep = faker.datatype.boolean(0.7) ? generateLifecycleStep(transformedPlay, {name: 'preCompare'}) : undefined;
- if(firstStep !== undefined) {
- transformedPlay = firstStep[1];
- steps.push(firstStep[0]);
- while(faker.datatype.boolean(0.2)) {
- const [pc, modified] = generateLifecycleStep(transformedPlay, {name: 'preCompare'});
- steps.push(pc);
- transformedPlay = modified;
+
+ if(typeof preCompare === 'number') {
+ for(let i = 0; i < preCompare; i++) {
+ const step = generateLifecycleStep(transformedPlay, {name: 'preCompare'});
+ steps.push(step[0]);
+ transformedPlay = step[1];
+ }
+ } else if(preCompare === true) {
+ const firstStep = faker.datatype.boolean(0.7) ? generateLifecycleStep(transformedPlay, {name: 'preCompare'}) : undefined;
+ if(firstStep !== undefined) {
+ transformedPlay = firstStep[1];
+ steps.push(firstStep[0]);
+ while(faker.datatype.boolean(0.2)) {
+ const [pc, modified] = generateLifecycleStep(transformedPlay, {name: 'preCompare'});
+ steps.push(pc);
+ transformedPlay = modified;
+ }
}
}
- const lastStep = faker.datatype.boolean(0.5) ? generateLifecycleStep(transformedPlay, {name: 'postCompare'}) : undefined;
- if(lastStep !== undefined) {
- transformedPlay = lastStep[1];
- steps.push(lastStep[0]);
- while(faker.datatype.boolean(0.1)) {
- const [pc, modified] = generateLifecycleStep(transformedPlay, {name: 'postCompare'});
- steps.push(pc);
- transformedPlay = modified;
+ if(typeof postCompare === 'number') {
+ for(let i = 0; i < postCompare; i++) {
+ const step = generateLifecycleStep(transformedPlay, {name: 'postCompare'});
+ steps.push(step[0]);
+ transformedPlay = step[1];
+ }
+ } else if(postCompare === true) {
+ const lastStep = faker.datatype.boolean(0.5) ? generateLifecycleStep(transformedPlay, {name: 'postCompare'}) : undefined;
+ if(lastStep !== undefined) {
+ transformedPlay = lastStep[1];
+ steps.push(lastStep[0]);
+ while(faker.datatype.boolean(0.1)) {
+ const [pc, modified] = generateLifecycleStep(transformedPlay, {name: 'postCompare'});
+ steps.push(pc);
+ transformedPlay = modified;
+ }
}
}
diff --git a/src/stories/TransformSteps.stories.tsx b/src/stories/TransformSteps.stories.tsx
new file mode 100644
index 00000000..460cf295
--- /dev/null
+++ b/src/stories/TransformSteps.stories.tsx
@@ -0,0 +1,39 @@
+import preview from "../../.storybook/preview.js";
+import React from 'react';
+
+import { fn } from 'storybook/test';
+import { Container } from '@chakra-ui/react';
+import { TransformSteps } from "../client/components/TransformSteps.js";
+import {Provider} from "../client/components/Provider";
+import { generateJsonPlays } from "../core/PlayTestUtils.js";
+import { ErrorLike, JsonPlayObject, PlayLifecycle } from "../core/Atomic.js";
+import { examplePlay, lastfmErrorExample } from "./storyUtils.js";
+import {generatePlayWithLifecycle} from '../core/tests/utils/fixtures'
+
+// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
+const meta = preview.meta({
+ title: 'Examples/TransformSteps',
+ component: TransformSteps,
+ parameters: {
+ // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
+ layout: 'padded',
+ },
+ // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
+ tags: ['autodocs'],
+ // More on argTypes: https://storybook.js.org/docs/api/argtypes
+decorators: [
+ (Story) => (),
+ ]
+ // Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#story-args
+});
+
+const multiPlay = generatePlayWithLifecycle({lifecycleSteps: { preCompare: 2}});
+// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
+export const Multiple = meta.story({
+ args: {
+ steps: multiPlay.meta.lifecycle.steps,
+ original: multiPlay.meta.lifecycle.original,
+ collapsibleOpen: true
+ }
+ //render: function Render(args) { return () }
+});