forked from mystiq/hydrogen-web
Merge pull request #34 from bwindels/bwindels/updateprevfragwhenappending
Fix: update previous fragment in comparer when appending a new live fragment
This commit is contained in:
commit
a0dd4ee159
3 changed files with 51 additions and 16 deletions
|
@ -78,6 +78,14 @@ function createIslands(fragments) {
|
||||||
return islands.map(a => new Island(a));
|
return islands.map(a => new Island(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Fragment {
|
||||||
|
constructor(id, previousId, nextId) {
|
||||||
|
this.id = id;
|
||||||
|
this.previousId = previousId;
|
||||||
|
this.nextId = nextId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Island {
|
class Island {
|
||||||
constructor(sortedFragments) {
|
constructor(sortedFragments) {
|
||||||
this._idToSortIndex = new Map();
|
this._idToSortIndex = new Map();
|
||||||
|
@ -134,13 +142,6 @@ export default class FragmentIdComparer {
|
||||||
|
|
||||||
rebuild(fragments) {
|
rebuild(fragments) {
|
||||||
const islands = createIslands(fragments);
|
const islands = createIslands(fragments);
|
||||||
const fragmentJson = JSON.stringify(islands.map(i => {
|
|
||||||
return Array.from(i._idToSortIndex.entries())
|
|
||||||
.map(([id, idx]) => {return {id, idx};})
|
|
||||||
.sort((a, b) => a.idx - b.idx);
|
|
||||||
}));
|
|
||||||
const firstFragment = this._fragmentsById.values().next().value;
|
|
||||||
console.log("rebuilt fragment index", firstFragment && firstFragment.roomId, fragmentJson);
|
|
||||||
this._idToIsland = new Map();
|
this._idToIsland = new Map();
|
||||||
for(let island of islands) {
|
for(let island of islands) {
|
||||||
for(let id of island.fragmentIds) {
|
for(let id of island.fragmentIds) {
|
||||||
|
@ -149,8 +150,32 @@ export default class FragmentIdComparer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** use for fragments coming out of persistence, not newly created ones, or also fragments for a new island (like for a permalink) */
|
||||||
add(fragment) {
|
add(fragment) {
|
||||||
this._fragmentsById.set(fragment.id, fragment);
|
const copy = new Fragment(fragment.id, fragment.previousId, fragment.nextId);
|
||||||
|
this._fragmentsById.set(fragment.id, copy);
|
||||||
|
this.rebuild(this._fragmentsById.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** use for appending newly created fragments */
|
||||||
|
append(id, previousId) {
|
||||||
|
const fragment = new Fragment(id, previousId, null);
|
||||||
|
const prevFragment = this._fragmentsById.get(previousId);
|
||||||
|
if (prevFragment) {
|
||||||
|
prevFragment.nextId = id;
|
||||||
|
}
|
||||||
|
this._fragmentsById.set(id, fragment);
|
||||||
|
this.rebuild(this._fragmentsById.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** use for prepending newly created fragments */
|
||||||
|
prepend(id, nextId) {
|
||||||
|
const fragment = new Fragment(id, null, nextId);
|
||||||
|
const nextFragment = this._fragmentsById.get(nextId);
|
||||||
|
if (nextFragment) {
|
||||||
|
nextFragment.previousId = id;
|
||||||
|
}
|
||||||
|
this._fragmentsById.set(id, fragment);
|
||||||
this.rebuild(this._fragmentsById.values());
|
this.rebuild(this._fragmentsById.values());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,6 +279,22 @@ export function tests() {
|
||||||
assert.throws(() => index.compare(1, 2));
|
assert.throws(() => index.compare(1, 2));
|
||||||
assert(index.compare(11, 12) < 0);
|
assert(index.compare(11, 12) < 0);
|
||||||
},
|
},
|
||||||
|
test_append(assert) {
|
||||||
|
const index = new FragmentIdComparer([]);
|
||||||
|
// add livefragment when opening timeline,
|
||||||
|
// note that there is no nextId as the sync
|
||||||
|
// hasn't come in yet
|
||||||
|
index.add({id: 1});
|
||||||
|
// now sync comes in and replaces the live fragment
|
||||||
|
index.append(2, 1);
|
||||||
|
assert(index.compare(1, 2) < 0);
|
||||||
|
},
|
||||||
|
test_prepend(assert) {
|
||||||
|
const index = new FragmentIdComparer([]);
|
||||||
|
index.add({id: 2});
|
||||||
|
index.prepend(1, 2);
|
||||||
|
assert(index.compare(1, 2) < 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
|
|
|
@ -33,13 +33,7 @@ export default class Timeline {
|
||||||
|
|
||||||
/** @package */
|
/** @package */
|
||||||
appendLiveEntries(newEntries) {
|
appendLiveEntries(newEntries) {
|
||||||
try {
|
|
||||||
this._remoteEntries.setManySorted(newEntries);
|
this._remoteEntries.setManySorted(newEntries);
|
||||||
} catch (err) {
|
|
||||||
console.error("error while appending live entries in roomId", this._roomId);
|
|
||||||
console.error(err.stack);
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
|
|
|
@ -77,7 +77,7 @@ export default class SyncWriter {
|
||||||
nextToken: null
|
nextToken: null
|
||||||
};
|
};
|
||||||
txn.timelineFragments.add(newFragment);
|
txn.timelineFragments.add(newFragment);
|
||||||
this._fragmentIdComparer.add(newFragment);
|
this._fragmentIdComparer.append(newFragmentId, oldFragmentId);
|
||||||
return {oldFragment, newFragment};
|
return {oldFragment, newFragment};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue