If you want to track the timestamp (and other data of immutability) then your best option is to store the "raw" form instead of html (or keep alongside the html). You can use the convertToRaw to get the raw content, here's an example of foo inserted with timestamp as epoch.
{
"entityMap": {
"0": {
"type": "TOKEN",
"mutability": "SEGMENTED",
"data": {
"time": 1657116932641
}
}
},
"blocks": [
{
"key": "ekpc6",
"text": "aaa",
"type": "unstyled",
"depth": 0,
"inlineStyleRanges": [],
"entityRanges": [],
"data": {}
},
{
"key": "dmkkr",
"text": "foo",
"type": "unstyled",
"depth": 0,
"inlineStyleRanges": [
{
"offset": 0,
"length": 3,
"style": "INSERT"
}
],
"entityRanges": [
{
"offset": 0,
"length": 3,
"key": 0
}
],
"data": {}
}
]
};
I've taken your codepen code & added an explicit button to get raw content. Once you get the raw JSON, you can extract any meta data out.
const { Editor, EditorState, Modifier, convertToRaw, convertFromRaw } = Draft;
const { OrderedSet } = Immutable;
const sample_saved_state = {
"entityMap": {
"0": {
"type": "TOKEN",
"mutability": "SEGMENTED",
"data": {
"time": 1657116932641
}
}
},
"blocks": [
{
"key": "ekpc6",
"text": "aaa",
"type": "unstyled",
"depth": 0,
"inlineStyleRanges": [],
"entityRanges": [],
"data": {}
},
{
"key": "dmkkr",
"text": "foo",
"type": "unstyled",
"depth": 0,
"inlineStyleRanges": [
{
"offset": 0,
"length": 3,
"style": "INSERT"
}
],
"entityRanges": [
{
"offset": 0,
"length": 3,
"key": 0
}
],
"data": {}
}
]
};
class EditorComponent extends React.Component {
constructor(props) {
super(props);
// In case you store the sample_saved_state as string in server side, you might have to do JSON.parse
console.log("Converting from saved state");
const saved_state = sample_saved_state != null ? EditorState.createWithContent(convertFromRaw(sample_saved_state))
: EditorState.createEmpty();
console.log("Assining to state ");
this.state = {
value : saved_state
};
this.saveContent = this.saveContent.bind(this);
//this.state = { value: EditorState.createEmpty() };
this.onChange = (value) => this.setState({value});
this.focus = () => this.refs.editor.focus();
this.insert = this.insert.bind( this );
}
insert () {
const text = "foo";
const editorState = this.state.value;
const selectionState = editorState.getSelection();
const contentState = editorState.getCurrentContent();
const contentStateWithEntity = contentState.createEntity("TOKEN", "SEGMENTED", { time: new Date().getTime() });
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const modifiedContent = Modifier.insertText(contentState, selectionState, text, OrderedSet([ "INSERT" ]), entityKey);
const nextState = EditorState.push( editorState, modifiedContent, editorState.getLastChangeType() );
this.setState({value: nextState}, this.focus );
}
saveContent () {
console.log("inside saveContent");
const content = convertToRaw(this.state.value.getCurrentContent());
// you can save the content as json in server side
console.log("Raw Content: ",content)
}
render () {
return (
<div>
<div onClick={ this.focus } className="editor">
<Editor
ref="editor"
onChange={ this.onChange }
editorState={ this.state.value }
customStyleMap={{ "INSERT": { backgroundColor: "yellow", padding: "0 2px" } }}
/>
</div>
<button onClick={ this.insert }>Insert</button>
<button onClick={this.saveContent}>Save</button>
</div>
);
}
}
ReactDOM.render(
<EditorComponent />,
document.getElementById('app')
);