Add conflict resolution diff UI and app branding
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
(function () {
|
||||
const DB_NAME = "md-hub-cache";
|
||||
const DB_VERSION = 1;
|
||||
const DB_VERSION = 3;
|
||||
const STORE_DOCUMENTS = "documents";
|
||||
const STORE_CONTENT = "content";
|
||||
const STORE_PAGES = "pages";
|
||||
const STORE_PENDING_EDITS = "pending_edits";
|
||||
|
||||
function openDB() {
|
||||
return new Promise(function (resolve, reject) {
|
||||
@@ -21,10 +23,22 @@
|
||||
if (!db.objectStoreNames.contains(STORE_CONTENT)) {
|
||||
db.createObjectStore(STORE_CONTENT, { keyPath: "path" });
|
||||
}
|
||||
if (!db.objectStoreNames.contains(STORE_PAGES)) {
|
||||
db.createObjectStore(STORE_PAGES, { keyPath: "path" });
|
||||
}
|
||||
if (!db.objectStoreNames.contains(STORE_PENDING_EDITS)) {
|
||||
db.createObjectStore(STORE_PENDING_EDITS, { keyPath: "path" });
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function normalizePath(path) {
|
||||
if (!path) return "/";
|
||||
if (path === "/") return path;
|
||||
return path.replace(/\/$/, "") || "/";
|
||||
}
|
||||
|
||||
function cacheDocuments(documents) {
|
||||
return openDB().then(function (db) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
@@ -91,10 +105,158 @@
|
||||
});
|
||||
}
|
||||
|
||||
function cachePage(path, html, title) {
|
||||
const normalizedPath = normalizePath(path);
|
||||
return openDB().then(function (db) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const tx = db.transaction(STORE_PAGES, "readwrite");
|
||||
const store = tx.objectStore(STORE_PAGES);
|
||||
store.put({
|
||||
path: normalizedPath,
|
||||
html: html,
|
||||
title: title,
|
||||
cachedAt: Date.now(),
|
||||
});
|
||||
tx.oncomplete = function () {
|
||||
resolve();
|
||||
};
|
||||
tx.onerror = function () {
|
||||
reject(tx.error);
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getCachedPage(path) {
|
||||
const normalizedPath = normalizePath(path);
|
||||
return openDB().then(function (db) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const tx = db.transaction(STORE_PAGES, "readonly");
|
||||
const store = tx.objectStore(STORE_PAGES);
|
||||
const request = store.get(normalizedPath);
|
||||
request.onsuccess = function () {
|
||||
resolve(request.result);
|
||||
};
|
||||
request.onerror = function () {
|
||||
reject(request.error);
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function putPendingEdit(path, content, baseHash) {
|
||||
const normalizedPath = normalizePath(path);
|
||||
return openDB().then(function (db) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const tx = db.transaction(STORE_PENDING_EDITS, "readwrite");
|
||||
const store = tx.objectStore(STORE_PENDING_EDITS);
|
||||
store.put({
|
||||
path: normalizedPath,
|
||||
content: content,
|
||||
baseHash: baseHash || "",
|
||||
conflict: null,
|
||||
retries: 0,
|
||||
updatedAt: Date.now(),
|
||||
});
|
||||
tx.oncomplete = function () {
|
||||
resolve();
|
||||
};
|
||||
tx.onerror = function () {
|
||||
reject(tx.error);
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function markPendingEditConflict(path, conflict) {
|
||||
const normalizedPath = normalizePath(path);
|
||||
return openDB().then(function (db) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const tx = db.transaction(STORE_PENDING_EDITS, "readwrite");
|
||||
const store = tx.objectStore(STORE_PENDING_EDITS);
|
||||
const request = store.get(normalizedPath);
|
||||
request.onsuccess = function () {
|
||||
const record = request.result;
|
||||
if (!record) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
record.conflict = conflict;
|
||||
record.updatedAt = Date.now();
|
||||
store.put(record);
|
||||
};
|
||||
tx.oncomplete = function () {
|
||||
resolve();
|
||||
};
|
||||
tx.onerror = function () {
|
||||
reject(tx.error);
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getPendingEdits() {
|
||||
return openDB().then(function (db) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const tx = db.transaction(STORE_PENDING_EDITS, "readonly");
|
||||
const store = tx.objectStore(STORE_PENDING_EDITS);
|
||||
const request = store.getAll();
|
||||
request.onsuccess = function () {
|
||||
resolve(request.result || []);
|
||||
};
|
||||
request.onerror = function () {
|
||||
reject(request.error);
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getPendingEdit(path) {
|
||||
const normalizedPath = normalizePath(path);
|
||||
return openDB().then(function (db) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const tx = db.transaction(STORE_PENDING_EDITS, "readonly");
|
||||
const store = tx.objectStore(STORE_PENDING_EDITS);
|
||||
const request = store.get(normalizedPath);
|
||||
request.onsuccess = function () {
|
||||
resolve(request.result);
|
||||
};
|
||||
request.onerror = function () {
|
||||
reject(request.error);
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function deletePendingEdit(path) {
|
||||
const normalizedPath = normalizePath(path);
|
||||
return openDB().then(function (db) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const tx = db.transaction(STORE_PENDING_EDITS, "readwrite");
|
||||
const store = tx.objectStore(STORE_PENDING_EDITS);
|
||||
store.delete(normalizedPath);
|
||||
tx.oncomplete = function () {
|
||||
resolve();
|
||||
};
|
||||
tx.onerror = function () {
|
||||
reject(tx.error);
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
window.MDHubCache = {
|
||||
cacheDocuments: cacheDocuments,
|
||||
cacheContent: cacheContent,
|
||||
cachePage: cachePage,
|
||||
putPendingEdit: putPendingEdit,
|
||||
markPendingEditConflict: markPendingEditConflict,
|
||||
getPendingEdits: getPendingEdits,
|
||||
getPendingEdit: getPendingEdit,
|
||||
deletePendingEdit: deletePendingEdit,
|
||||
getCachedDocuments: getCachedDocuments,
|
||||
getCachedContent: getCachedContent,
|
||||
getCachedPage: getCachedPage,
|
||||
normalizePath: normalizePath,
|
||||
};
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user