web: added support for saving events

This commit is contained in:
Thomas Mathews 2022-12-20 18:47:33 -08:00
parent ca7abdd0b6
commit a5415906e9
5 changed files with 93 additions and 25 deletions

View file

@ -43,7 +43,7 @@ async function contacts_save(contacts) {
window.alert("An error occured saving contacts. Check console."); window.alert("An error occured saving contacts. Check console.");
reject(ev); reject(ev);
}; };
}; }
return dbcall(_contacts_save); return dbcall(_contacts_save);
} }
@ -76,10 +76,13 @@ async function contacts_load(model) {
async function dbcall(fn) { async function dbcall(fn) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var open = indexedDB.open("damus", 2); var open = indexedDB.open("damus", 4);
open.onupgradeneeded = (ev) => { open.onupgradeneeded = (ev) => {
const db = ev.target.result; const db = ev.target.result;
const os = db.createObjectStore("friends", {keyPath: "pubkey"}); if (!db.objectStoreNames.contains("friends"))
db.createObjectStore("friends", {keyPath: "pubkey"});
if (!db.objectStoreNames.contains("events"))
db.createObjectStore("events", {keyPath: "id"});
}; };
open.onsuccess = (ev) => { open.onsuccess = (ev) => {
fn(ev, resolve, reject); fn(ev, resolve, reject);

View file

@ -1,7 +1,6 @@
let DAMUS let DAMUS
const BOOTSTRAP_RELAYS = [ const BOOTSTRAP_RELAYS = [
"wss://nostr.rdfriedl.com",
"wss://relay.damus.io", "wss://relay.damus.io",
"wss://nostr-relay.wlvs.space", "wss://nostr-relay.wlvs.space",
"wss://nostr-pub.wellorder.net" "wss://nostr-pub.wellorder.net"
@ -50,6 +49,8 @@ async function damus_web_init_ready() {
unknowns: "unknowns", unknowns: "unknowns",
dms: "dms", dms: "dms",
} }
model.ids = ids
model.pool = pool
let err; let err;
err = await contacts_load(model); err = await contacts_load(model);
@ -57,10 +58,9 @@ async function damus_web_init_ready() {
window.alert("Unable to load contacts."); window.alert("Unable to load contacts.");
} }
model.ids = ids await model_load_events(model, (ev)=> {
model.pool = pool model_process_event(model, ev);
model.view_el = document.querySelector("#view") });
//load_cache(model)
view_timeline_apply_mode(model, VM_FRIENDS); view_timeline_apply_mode(model, VM_FRIENDS);
document.addEventListener('visibilitychange', () => { document.addEventListener('visibilitychange', () => {
@ -107,6 +107,7 @@ function on_pool_notice(relay, notice) {
// on_pool_eose occurs when all storage from a relay has been sent to the // on_pool_eose occurs when all storage from a relay has been sent to the
// client for a labeled (sub_id) REQ. // client for a labeled (sub_id) REQ.
async function on_pool_eose(relay, sub_id) { async function on_pool_eose(relay, sub_id) {
log_info(`EOSE(${relay.url}): ${sub_id}`);
const model = DAMUS; const model = DAMUS;
const { ids, pool } = model; const { ids, pool } = model;
switch (sub_id) { switch (sub_id) {
@ -115,6 +116,9 @@ async function on_pool_eose(relay, sub_id) {
// TODO filter out events to friends of friends // TODO filter out events to friends of friends
on_eose_comments(ids, model, events, relay) on_eose_comments(ids, model, events, relay)
pool.unsubscribe(ids.home, relay); pool.unsubscribe(ids.home, relay);
if (!model.inited) {
model.inited = true;
}
break; break;
case ids.profiles: case ids.profiles:
model.pool.unsubscribe(ids.profiles, relay); model.pool.unsubscribe(ids.profiles, relay);
@ -137,18 +141,12 @@ function on_pool_ok(relay) {
function on_pool_event(relay, sub_id, ev) { function on_pool_event(relay, sub_id, ev) {
const model = DAMUS; const model = DAMUS;
const { ids, pool } = model;
// Simply ignore any events that happened in the future.
if (new Date(ev.created_at * 1000) > new Date()) { if (new Date(ev.created_at * 1000) > new Date()) {
// Simply ignore any events that happened in the future.
return; return;
} }
model_process_event(model, ev);
// Process event and apply side effects
if (!model.all_events[ev.id]) {
model.all_events[ev.id] = ev;
model_process_event(model, ev);
}
} }
function on_eose_profiles(ids, model, relay) { function on_eose_profiles(ids, model, relay) {

View file

@ -121,3 +121,51 @@ function event_parse_reaction(ev) {
} }
} }
async function model_save_events(model) {
function _events_save(ev, resolve, reject) {
const db = ev.target.result;
let tx = db.transaction("events", "readwrite");
let store = tx.objectStore("events");
for (const evid in model.all_events) {
store.put(model.all_events[evid]);
}
tx.oncomplete = (ev) => {
db.close();
resolve();
log_debug("saved events!");
};
tx.onerror = (ev) => {
db.close();
log_error("failed to save events");
reject(ev);
};
}
return dbcall(_events_save);
}
async function model_load_events(model, fn) {
function _events_load(ev, resolve, reject) {
const db = ev.target.result;
const tx = db.transaction("events", "readonly");
const store = tx.objectStore("events");
const cursor = store.openCursor();
cursor.onsuccess = (ev) => {
var cursor = ev.target.result;
if (cursor) {
fn(cursor.value);
cursor.continue();
} else {
db.close();
resolve();
log_debug("Successfully loaded events");
}
}
cursor.onerror = (ev) => {
db.close();
reject(ev);
log_error("Could not load events.");
};
}
return dbcall(_events_load);
}

View file

@ -3,6 +3,11 @@
* and fetching of unknown pubkey profiles. * and fetching of unknown pubkey profiles.
*/ */
function model_process_event(model, ev) { function model_process_event(model, ev) {
if (model.all_events[ev.id]) {
return;
}
model.all_events[ev.id] = ev;
ev.refs = event_get_tag_refs(ev.tags); ev.refs = event_get_tag_refs(ev.tags);
ev.pow = event_calculate_pow(ev); ev.pow = event_calculate_pow(ev);

View file

@ -96,16 +96,11 @@ function view_timeline_update(model) {
continue; continue;
} }
const html = render_event(model, ev, {});
// Put it back on the stack to re-render if it's not ready. // Put it back on the stack to re-render if it's not ready.
if (html == "") { if (!view_render_event(model, ev)) {
left_overs.push(evid); left_overs.push(evid);
continue; continue;
} }
const div = document.createElement("div");
div.innerHTML = html;
ev_el = div.firstChild;
model.elements[evid] = ev_el;
// If the new element is newer than the latest & is viewable then // If the new element is newer than the latest & is viewable then
// we want to increase the count of how many to add to view // we want to increase the count of how many to add to view
@ -116,18 +111,23 @@ function view_timeline_update(model) {
model.invalidated = model.invalidated.concat(left_overs); model.invalidated = model.invalidated.concat(left_overs);
if (count > 0) { if (count > 0) {
view_set_show_count(count, true); // If we have things to show and we have initted and we don't have
// anything update the current view
if (!latest_ev && model.inited) {
view_timeline_show_new(model);
}
view_set_show_count(count, true, !model.inited);
} }
} }
function view_set_show_count(count, add) { function view_set_show_count(count, add=false, hide=false) {
const show_el = find_node("#show-new") const show_el = find_node("#show-new")
const num_el = find_node("#show-new span", show_el); const num_el = find_node("#show-new span", show_el);
if (add) { if (add) {
count += parseInt(num_el.innerText || 0) count += parseInt(num_el.innerText || 0)
} }
num_el.innerText = count; num_el.innerText = count;
show_el.classList.toggle("hide", count <= 0); show_el.classList.toggle("hide", hide || count <= 0);
} }
function view_timeline_show_new(model) { function view_timeline_show_new(model) {
@ -163,6 +163,20 @@ function view_timeline_show_new(model) {
view_timeline_update_timestamps(); view_timeline_update_timestamps();
} }
function view_render_event(model, ev, force=false) {
if (model.elements[ev.id] && !force)
return model.elements[ev.id];
const html = render_event(model, ev, {});
if (html == "") {
return;
}
const div = document.createElement("div");
div.innerHTML = html;
const el = div.firstChild;
model.elements[ev.id] = el;
return el;
}
function view_timeline_update_profiles(model, ev) { function view_timeline_update_profiles(model, ev) {
let xs, html; let xs, html;
const el = view_get_timeline_el(); const el = view_get_timeline_el();