forked from mystiq/hydrogen-web
more fixes, timeline is showing again
This commit is contained in:
parent
a1e527ccbc
commit
e339cb7321
15 changed files with 46 additions and 17 deletions
|
@ -45,6 +45,10 @@
|
|||
flex: 1;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.RoomView_error {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
@ -16,8 +16,9 @@ export default class RoomViewModel extends EventEmitter {
|
|||
try {
|
||||
this._timeline = await this._room.openTimeline();
|
||||
this._timelineVM = new TimelineViewModel(this._timeline);
|
||||
this.emit("change", "timelineEntries");
|
||||
this.emit("change", "timelineViewModel");
|
||||
} catch (err) {
|
||||
console.error(`room.openTimeline(): ${err.message}:\n${err.stack}`);
|
||||
this._timelineError = err;
|
||||
this.emit("change", "error");
|
||||
}
|
||||
|
|
|
@ -22,10 +22,11 @@ export default class TilesCollection extends BaseObservableList {
|
|||
for (let entry of this._entries) {
|
||||
if (!currentTile || !currentTile.tryIncludeEntry(entry)) {
|
||||
currentTile = this._tileCreator(entry);
|
||||
// if (currentTile) here?
|
||||
if (currentTile) {
|
||||
this._tiles.push(currentTile);
|
||||
}
|
||||
}
|
||||
}
|
||||
let prevTile = null;
|
||||
for (let tile of this._tiles) {
|
||||
if (prevTile) {
|
||||
|
@ -145,4 +146,8 @@ export default class TilesCollection extends BaseObservableList {
|
|||
[Symbol.iterator]() {
|
||||
return this._tiles.values();
|
||||
}
|
||||
|
||||
get length() {
|
||||
return this._tiles.length;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,11 @@ export default class TextTile extends MessageTile {
|
|||
get label() {
|
||||
const content = this._getContent();
|
||||
const body = content && content.body;
|
||||
if (this._entry.type() === "m.emote") {
|
||||
return `* ${this._entry.event.sender} ${body}`;
|
||||
const sender = this._entry.event.sender;
|
||||
if (this._entry.type === "m.emote") {
|
||||
return `* ${sender} ${body}`;
|
||||
} else {
|
||||
return body;
|
||||
return `${sender}: ${body}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,6 +88,6 @@ export default async function main(label, button, container) {
|
|||
label.innerText = "sync stopped";
|
||||
});
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
console.error(`${err.message}:\n${err.stack}`);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ export default class Timeline {
|
|||
|
||||
/** @package */
|
||||
async load() {
|
||||
const entries = this._timelineReader.readFromEnd(100);
|
||||
const entries = await this._timelineReader.readFromEnd(100);
|
||||
this._entriesList.setManySorted(entries);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//entries can be sorted, first by fragment, then by entry index.
|
||||
import EventKey from "../EventKey.js";
|
||||
|
||||
export default class BaseEntry {
|
||||
constructor(fragmentIdComparer) {
|
||||
|
@ -21,4 +22,8 @@ export default class BaseEntry {
|
|||
return this._fragmentIdComparer.compare(this.fragmentId, otherEntry.fragmentId);
|
||||
}
|
||||
}
|
||||
|
||||
asEventKey() {
|
||||
return new EventKey(this.fragmentId, this.entryIndex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ export default class SyncWriter {
|
|||
this._roomId = roomId;
|
||||
this._storage = storage;
|
||||
this._fragmentIdComparer = fragmentIdComparer;
|
||||
this._lastLiveKey = null;
|
||||
}
|
||||
|
||||
async load(txn) {
|
||||
|
@ -98,7 +99,6 @@ export default class SyncWriter {
|
|||
// right thing to do? if the txn fails, not sure we'll continue anyways ...
|
||||
// only advance the key once the transaction has succeeded
|
||||
txn.complete().then(() => {
|
||||
console.log("txn complete, setting key");
|
||||
this._lastLiveKey = currentKey;
|
||||
})
|
||||
|
||||
|
|
|
@ -32,9 +32,9 @@ export default class TimelineReader {
|
|||
while (entries.length < amount && eventKey) {
|
||||
let eventsWithinFragment;
|
||||
if (direction.isForward) {
|
||||
eventsWithinFragment = timelineStore.eventsAfter(eventKey, amount);
|
||||
eventsWithinFragment = await timelineStore.eventsAfter(this._roomId, eventKey, amount);
|
||||
} else {
|
||||
eventsWithinFragment = timelineStore.eventsBefore(eventKey, amount);
|
||||
eventsWithinFragment = await timelineStore.eventsBefore(this._roomId, eventKey, amount);
|
||||
}
|
||||
const eventEntries = eventsWithinFragment.map(e => new EventEntry(e, this._fragmentIdComparer));
|
||||
entries = directionalConcat(entries, eventEntries, direction);
|
||||
|
@ -52,7 +52,7 @@ export default class TimelineReader {
|
|||
this._fragmentIdComparer.add(nextFragment);
|
||||
const nextFragmentEntry = new FragmentBoundaryEntry(nextFragment, direction.isForward, this._fragmentIdComparer);
|
||||
directionalAppend(entries, nextFragmentEntry, direction);
|
||||
eventKey = new EventKey(nextFragmentEntry.fragmentId, nextFragmentEntry.eventIndex);
|
||||
eventKey = nextFragmentEntry.asEventKey();
|
||||
} else {
|
||||
eventKey = null;
|
||||
}
|
||||
|
@ -71,8 +71,8 @@ export default class TimelineReader {
|
|||
}
|
||||
this._fragmentIdComparer.add(liveFragment);
|
||||
const liveFragmentEntry = FragmentBoundaryEntry.end(liveFragment, this._fragmentIdComparer);
|
||||
const eventKey = new EventKey(liveFragmentEntry.fragmentId, liveFragmentEntry.eventIndex);
|
||||
const entries = this._readFrom(eventKey, Direction.Backward, amount, txn);
|
||||
const eventKey = liveFragmentEntry.asEventKey();
|
||||
const entries = await this._readFrom(eventKey, Direction.Backward, amount, txn);
|
||||
entries.unshift(liveFragmentEntry);
|
||||
return entries;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ function createStores(db) {
|
|||
db.createObjectStore("timelineFragments", {keyPath: ["roomId", "id"]});
|
||||
const timelineEvents = db.createObjectStore("timelineEvents", {keyPath: ["roomId", "fragmentId", "eventIndex"]});
|
||||
timelineEvents.createIndex("byEventId", [
|
||||
"event.room_id",
|
||||
"roomId",
|
||||
"event.event_id"
|
||||
], {unique: true});
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ export default class Sync extends EventEmitter {
|
|||
await Promise.all(promises);
|
||||
}
|
||||
} catch(err) {
|
||||
console.warn("aborting syncTxn because of error", err.stack);
|
||||
console.warn("aborting syncTxn because of error");
|
||||
// avoid corrupting state by only
|
||||
// storing the sync up till the point
|
||||
// the exception occurred
|
||||
|
|
|
@ -34,4 +34,11 @@ export default class BaseObservableList extends BaseObservableCollection {
|
|||
}
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
throw new Error("unimplemented");
|
||||
}
|
||||
|
||||
get length() {
|
||||
throw new Error("unimplemented");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,11 +14,14 @@ export default class RoomView {
|
|||
mount() {
|
||||
this._viewModel.on("change", this._onViewModelUpdate);
|
||||
this._nameLabel = html.h2(null, this._viewModel.name);
|
||||
this._errorLabel = html.div({className: "RoomView_error"});
|
||||
|
||||
this._timelineList = new ListView({}, entry => new TimelineTile(entry));
|
||||
this._timelineList.mount();
|
||||
|
||||
this._root = html.div({className: "RoomView"}, [
|
||||
this._nameLabel,
|
||||
this._errorLabel,
|
||||
this._timelineList.root()
|
||||
]);
|
||||
|
||||
|
@ -40,6 +43,8 @@ export default class RoomView {
|
|||
}
|
||||
else if (prop === "timelineViewModel") {
|
||||
this._timelineList.update({list: this._viewModel.timelineViewModel.tiles});
|
||||
} else if (prop === "error") {
|
||||
this._errorLabel.innerText = this._viewModel.error;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ export default class TimelineTile {
|
|||
function renderTile(tile) {
|
||||
switch (tile.shape) {
|
||||
case "message":
|
||||
return html.li(null, [html.strong(tile.sender), `: ${tile.label}`]);
|
||||
return html.li(null, tile.label);
|
||||
case "gap": {
|
||||
const button = html.button(null, (tile.isUp ? "🠝" : "🠟") + " fill gap");
|
||||
const handler = () => {
|
||||
|
|
|
@ -51,3 +51,4 @@ export function main(... params) { return el("main", ... params); }
|
|||
export function article(... params) { return el("article", ... params); }
|
||||
export function aside(... params) { return el("aside", ... params); }
|
||||
export function pre(... params) { return el("pre", ... params); }
|
||||
export function button(... params) { return el("button", ... params); }
|
||||
|
|
Loading…
Reference in a new issue