forked from microsoft/FluidFramework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTodoItem.ts
113 lines (95 loc) · 3.42 KB
/
TodoItem.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*!
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
* Licensed under the MIT License.
*/
import { DataObject, DataObjectFactory } from "@fluidframework/aqueduct/internal";
import { IFluidHandle } from "@fluidframework/core-interfaces";
import { IValueChanged } from "@fluidframework/map/internal";
import { SharedString } from "@fluidframework/sequence/internal";
export interface ITodoItemInitialState {
startingText: string;
}
const textKey = "text";
const detailedTextKey = "detailedText";
const checkedKey = "checked";
/**
* Todo Item is a singular todo entry consisting of:
* - SharedString for the item's text
* - SharedString for the item's detailed text
* - Boolean stored in the root SharedDirectory for the checkbox
*/
export class TodoItem extends DataObject<{ InitialState: ITodoItemInitialState }> {
private _text: SharedString | undefined;
private get text(): SharedString {
if (this._text === undefined) {
throw new Error("Attempted to access text before initialized");
}
return this._text;
}
private _detailedText: SharedString | undefined;
private get detailedText(): SharedString {
if (this._detailedText === undefined) {
throw new Error("Attempted to access detailedText before initialized");
}
return this._detailedText;
}
protected async initializingFirstTime(initialState?: ITodoItemInitialState) {
// The text of the todo item, with initial value if it was provided
const newItemText = initialState?.startingText ?? "New Item";
const text = SharedString.create(this.runtime);
text.insertText(0, newItemText);
this.root.set(textKey, text.handle);
// The detailed text of the todo item
const detailedText = SharedString.create(this.runtime);
this.root.set(detailedTextKey, detailedText.handle);
// The state of the checkbox
this.root.set(checkedKey, false);
}
protected async hasInitialized() {
const textHandle = this.root.get<IFluidHandle<SharedString>>(textKey);
if (textHandle === undefined) {
throw new Error("Text SharedString missing");
}
const textP = textHandle.get();
const detailedTextHandle = this.root.get<IFluidHandle<SharedString>>(detailedTextKey);
if (detailedTextHandle === undefined) {
throw new Error("Detailed text SharedString missing");
}
const detailedTextP = detailedTextHandle.get();
[this._text, this._detailedText] = await Promise.all([textP, detailedTextP]);
this.root.on("valueChanged", (changed: IValueChanged, local: boolean) => {
if (!local) {
if (changed.key === checkedKey) {
this.emit("checkedStateChanged");
}
}
});
}
// start public API surface for the TodoItem model, used by the view
// Would prefer not to hand this out, and instead give back an object?
public getText() {
return this.text;
}
// Would prefer not to hand this out, and instead give back an object?
public getDetailedText(): SharedString {
return this.detailedText;
}
public getCheckedState(): boolean {
const checkedState: boolean | undefined = this.root.get(checkedKey);
if (checkedState === undefined) {
throw new Error("Checked state missing");
}
return checkedState;
}
public setCheckedState(newState: boolean): void {
this.root.set(checkedKey, newState);
this.emit("checkedStateChanged");
}
// end public API surface for the TodoItem model, used by the view
}
export const TodoItemFactory = new DataObjectFactory(
"@fluid-example/todo-item",
TodoItem,
[SharedString.getFactory()],
{},
);