Skip to content

Commit 364049c

Browse files
committed
timetravel + git -- working on it
1 parent c5ad7c5 commit 364049c

File tree

4 files changed

+152
-150
lines changed

4 files changed

+152
-150
lines changed

src/packages/frontend/frame-editors/time-travel-editor/actions.ts

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,12 @@ const EXTENSION = ".time-travel";
4848

4949
export interface TimeTravelState extends CodeEditorState {
5050
versions: List<Date>;
51+
git_versions: List<Date>;
5152
loading: boolean;
5253
has_full_history: boolean;
5354
docpath: string;
5455
docext: string;
56+
// true if in a git repo
5557
git?: boolean;
5658
//frame_states: Map<string, any>; // todo: really map from frame_id to FrameState as immutable map.
5759
}
@@ -115,31 +117,54 @@ export class TimeTravelActions extends CodeEditorActions<TimeTravelState> {
115117
});
116118
}
117119

118-
public init_frame_tree(versions?: List<Date>): void {
120+
init_frame_tree = () => {
121+
this.ensureSelectedVersionsAreConsistent();
122+
};
123+
124+
ensureSelectedVersionsAreConsistent = ({
125+
versions,
126+
git_versions,
127+
}: {
128+
versions?;
129+
git_versions?;
130+
} = {}): void => {
119131
if (versions == null) {
120132
if (this.syncdoc == null || this.syncdoc.get_state() != "ready") return;
121-
versions = List<Date>(this.syncdoc.all_versions());
133+
versions =
134+
this.store.get("versions") ?? List<Date>(this.syncdoc.all_versions());
135+
}
136+
if (git_versions == null) {
137+
git_versions = this.store.get("git_versions");
122138
}
123139
// make sure all the version and version ranges are valid...
124140
const max = versions.size - 1;
141+
const max_git = git_versions != null ? git_versions.size - 1 : Infinity;
125142
for (const actions of [this.ambient_actions, this]) {
126143
if (actions == null) continue;
127144
for (const id in actions._get_leaf_ids()) {
128145
const node = actions._get_frame_node(id);
129-
if (node == null || node.get("type") != "time_travel") continue;
146+
if (node?.get("type") != "time_travel") {
147+
continue;
148+
}
149+
const m = node.get("git_mode") ? max_git : max;
130150
for (const x of ["version", "version0", "version1"]) {
131151
let n: number | undefined = node.get(x);
132-
if (n == null || n > max || n < 0) {
133-
// make it max except in the case of "version0"
152+
if (n == null || n > m || n < 0) {
153+
// make it m except in the case of "version0"
134154
// when we want it to be one less than version1, which
135-
// will be max.
136-
n = x == "version0" ? Math.max(0, max - 1) : max;
155+
// will be m.
156+
// Also for git mode when m=Infinity, use 0 since there is no other option.
157+
if (m == Infinity) {
158+
n = 0;
159+
} else {
160+
n = x == "version0" ? Math.max(0, m - 1) : m;
161+
}
137162
actions.set_frame_tree({ id, [x]: n });
138163
}
139164
}
140165
}
141166
}
142-
}
167+
};
143168

144169
public async load_full_history(): Promise<void> {
145170
if (
@@ -170,7 +195,7 @@ export class TimeTravelActions extends CodeEditorActions<TimeTravelState> {
170195
this.setState({ versions });
171196
if (this.first_load) {
172197
this.first_load = false;
173-
this.init_frame_tree(versions);
198+
this.ensureSelectedVersionsAreConsistent({ versions });
174199
}
175200
}
176201

@@ -220,14 +245,20 @@ export class TimeTravelActions extends CodeEditorActions<TimeTravelState> {
220245
throw Error(`BUG -- no node with id ${id}`);
221246
}
222247

223-
public set_version(id: string, version: number): void {
248+
set_version = (id: string, version: number): void => {
224249
for (const actions of [this, this.ambient_actions]) {
225250
if (actions == null || actions._get_frame_node(id) == null) continue;
226251
if (typeof version != "number") {
227252
// be extra careful
228253
throw Error("version must be a number");
229254
}
230-
const versions = this.store.get("versions");
255+
const node = actions._get_frame_node(id);
256+
if (node == null) {
257+
return;
258+
}
259+
const versions = node.get("git_mode")
260+
? this.store.get("git_versions")
261+
: this.store.get("versions");
231262
if (versions == null || versions.size == 0) return;
232263
if (version == -1 || version >= versions.size) {
233264
version = versions.size - 1;
@@ -237,7 +268,7 @@ export class TimeTravelActions extends CodeEditorActions<TimeTravelState> {
237268
actions.set_frame_tree({ id, version });
238269
return;
239270
}
240-
}
271+
};
241272

242273
public step(id: string, delta: number): void {
243274
const node = this.get_frame_node_global(id);
@@ -367,13 +398,6 @@ export class TimeTravelActions extends CodeEditorActions<TimeTravelState> {
367398

368399
private gitCommand = async (args: string[], commit?: string) => {
369400
const { head, tail } = path_split(this.docpath);
370-
console.log({
371-
command: "git",
372-
args: args.concat([`${commit ? commit + ":./" : ""}${tail}`]),
373-
path: head,
374-
project_id: this.project_id,
375-
err_on_exit: true,
376-
});
377401
return await exec({
378402
command: "git",
379403
args: args.concat([`${commit ? commit + ":./" : ""}${tail}`]),
@@ -403,10 +427,12 @@ export class TimeTravelActions extends CodeEditorActions<TimeTravelState> {
403427
versions.push(new Date(t));
404428
}
405429
versions.reverse();
430+
const git_versions = List<Date>(versions);
406431
this.setState({
407432
git: versions.length > 0,
408-
versions: List<Date>(versions),
433+
git_versions,
409434
});
435+
this.ensureSelectedVersionsAreConsistent({ git_versions });
410436
} catch (err) {
411437
this.set_error(`${err}`);
412438
this.setState({ git: false });

src/packages/frontend/frame-editors/time-travel-editor/navigation-slider.tsx

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,24 @@ interface Props {
1212
id: string;
1313
actions: TimeTravelActions;
1414
version?: number;
15-
versions;
16-
max: number;
15+
versions?;
1716
}
1817

19-
export function NavigationSlider({
20-
id,
21-
actions,
22-
version,
23-
versions,
24-
max,
25-
}: Props) {
18+
export function NavigationSlider({ id, actions, version, versions }: Props) {
2619
const { isVisible } = useFrameContext();
27-
if (version == null || !isVisible) {
20+
if (versions == null || version == null || !isVisible) {
2821
return <div />;
2922
}
3023
const renderTooltip = (index) => {
3124
const date = versions.get(index);
3225
if (date == null) return; // shouldn't happen
3326
return <TimeAgo date={date} />;
3427
};
35-
3628
return (
3729
<Slider
3830
style={{ margin: "10px 15px" }}
3931
min={0}
40-
max={max}
32+
max={versions.size - 1}
4133
value={version}
4234
onChange={(value) => {
4335
actions.set_version(id, value);

src/packages/frontend/frame-editors/time-travel-editor/range-slider.tsx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ import { useFrameContext } from "@cocalc/frontend/frame-editors/frame-tree/frame
1818
interface Props {
1919
id: string;
2020
actions: TimeTravelActions;
21-
versions: List<Date>;
21+
versions?: List<Date>;
2222
version0?: number;
2323
version1?: number;
24-
max: number;
2524
}
2625

2726
export function RangeSlider({
@@ -30,10 +29,22 @@ export function RangeSlider({
3029
versions,
3130
version0,
3231
version1,
33-
max,
3432
}: Props) {
3533
const { isVisible } = useFrameContext();
3634

35+
// Have to hide when isVisible because tooltip stays ALWAYS visible otherwise.
36+
if (
37+
versions == null ||
38+
!isVisible ||
39+
version0 == null ||
40+
version1 == null ||
41+
versions.size == 0 ||
42+
version0 < 0 ||
43+
version1 > versions.size - 1
44+
) {
45+
return <div />;
46+
}
47+
3748
const handleChange = (values: number[]): void => {
3849
if (values[0] == null || values[1] == null) {
3950
throw Error("invalid values");
@@ -42,22 +53,11 @@ export function RangeSlider({
4253
};
4354

4455
const renderTooltip = (index) => {
45-
const date = versions.get(index);
56+
const date = versions?.get(index);
4657
if (date == null) return; // shouldn't happen
4758
return <TimeAgo date={date} />;
4859
};
4960

50-
// Have to hide when isVisible because tooltip stays ALWAYS visible otherwise!
51-
if (
52-
!isVisible ||
53-
version0 == null ||
54-
version1 == null ||
55-
max < 0 ||
56-
version0 < 0 ||
57-
version1 > max
58-
) {
59-
return <div />;
60-
}
6161
return (
6262
<div
6363
style={{
@@ -71,7 +71,7 @@ export function RangeSlider({
7171
<Slider
7272
range
7373
min={0}
74-
max={max}
74+
max={versions.size - 1}
7575
value={[version0, version1]}
7676
onChange={handleChange}
7777
tooltip={{ open: true, formatter: renderTooltip }}

0 commit comments

Comments
 (0)