feat: matrix

This commit is contained in:
2024-09-13 21:35:52 +02:00
parent 26c43b1966
commit d1fefb88a1
24 changed files with 1386 additions and 59 deletions

View File

@@ -11,11 +11,13 @@
cursor = false,
keys = false,
children,
ondone,
}: {
replay: ReplayPlayer | Replay;
cursor?: boolean;
keys?: boolean;
children?: Snippet;
ondone?: () => void;
} = $props();
let replayPlayer: ReplayPlayer | undefined = $state();
@@ -61,6 +63,7 @@
const unsubscribePlayer = player.subscribe(apply);
textRenderer = renderer;
player.onDone = ondone;
player.start();
apply();
setTimeout(() => {

View File

@@ -18,6 +18,8 @@ export class ReplayPlayer {
private subscribers = new Set<(value: TextToken | undefined) => void>();
onDone?: () => void;
constructor(
readonly replay: Replay,
plugins: ReplayPlugin[] = [],
@@ -37,8 +39,13 @@ export class ReplayPlayer {
if (
this.replayCursor >= this.replay.keys.length &&
this.releaseAt.size === 0
)
) {
if (this.onDone) {
this.onDone();
}
return;
}
const now = performance.now() - this.startTime;
while (
@@ -118,7 +125,12 @@ export class ReplayPlayer {
start(delay = 200): this {
this.replayCursor = 0;
this.stepper = new ReplayStepper([], this.replay.challenge);
if (this.replay.keys.length === 0) return this;
if (this.replay.keys.length === 0) {
if (this.onDone) {
this.onDone();
}
return this;
}
setTimeout(() => {
this.startTime = performance.now();
this.animationFrameId = requestAnimationFrame(this.updateLoop.bind(this));

View File

@@ -1,6 +1,10 @@
import { ReplayPlayer } from "./player.js";
import type { Replay, ReplayEvent, TransmittableKeyEvent } from "./types.js";
function maybeRound<T>(value: T, round: boolean): T {
return typeof value === "number" && round ? (Math.round(value) as T) : value;
}
export class ReplayRecorder {
private held = new Map<string, [string, number]>();
@@ -39,7 +43,7 @@ export class ReplayRecorder {
this.player.playLiveEvent(event.key, event.code),
);
} else {
const [key, start] = this.held.get(event.code)!;
const [key, start] = this.held.get(event.code) ?? ["", 0];
const delta = event.timeStamp - start;
this.held.delete(event.code);
@@ -50,16 +54,24 @@ export class ReplayRecorder {
}
}
finish(trim = true) {
finish(trim = true, round = true) {
return {
start: trim ? this.replay[0]?.[2] : this.start,
finish: trim
? Math.max(...this.replay.map((it) => it[2] + it[3]))
: performance.now(),
start: maybeRound(trim ? this.replay[0]?.[2] : this.start, round),
finish: maybeRound(
trim
? Math.max(...this.replay.map((it) => it[2] + it[3]))
: performance.now(),
round,
),
keys: this.replay
.map(
([key, code, at, duration]) =>
[key, code, Math.round(at), Math.round(duration)] as const,
[
key,
code,
maybeRound(at, round),
maybeRound(duration, round),
] as const,
)
.sort((a, b) => a[2] - b[2]),
};