mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) Storing last position for doc and user
Summary: Last position should be stored for document and user. Test Plan: Updated tests Reviewers: georgegevoian Reviewed By: georgegevoian Differential Revision: https://phab.getgrist.com/D3143
This commit is contained in:
parent
c6aa9b65d4
commit
fc50079e03
@ -18,8 +18,8 @@ export class CursorMonitor extends Disposable {
|
|||||||
|
|
||||||
// abstraction to work with local storage
|
// abstraction to work with local storage
|
||||||
private _store: StorageWrapper;
|
private _store: StorageWrapper;
|
||||||
// document id that this monitor is attached
|
// key for storing position in the memory (docId + userId)
|
||||||
private _docId: string;
|
private _key: string;
|
||||||
// flag that tells if the position was already restored
|
// flag that tells if the position was already restored
|
||||||
// we track document's view change event, so we only want
|
// we track document's view change event, so we only want
|
||||||
// to react to that event once
|
// to react to that event once
|
||||||
@ -31,7 +31,10 @@ export class CursorMonitor extends Disposable {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
this._store = new StorageWrapper(store);
|
this._store = new StorageWrapper(store);
|
||||||
this._docId = doc.docId();
|
|
||||||
|
// Use document id and user id as a key for storage.
|
||||||
|
const userId = doc.app.topAppModel.appObs.get()?.currentUser?.id ?? null;
|
||||||
|
this._key = doc.docId() + userId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When document loads last cursor position should be restored from local storage.
|
* When document loads last cursor position should be restored from local storage.
|
||||||
@ -77,12 +80,12 @@ export class CursorMonitor extends Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _storePosition(pos: ViewCursorPos) {
|
private _storePosition(pos: ViewCursorPos) {
|
||||||
this._store.update(this._docId, pos);
|
this._store.update(this._key, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _restoreLastPosition(view: IDocPage) {
|
private _restoreLastPosition(view: IDocPage) {
|
||||||
const lastPosition = this._store.read(this._docId);
|
const lastPosition = this._store.read(this._key);
|
||||||
this._store.clear(this._docId);
|
this._store.clear(this._key);
|
||||||
if (lastPosition && lastPosition.position.viewId == view) {
|
if (lastPosition && lastPosition.position.viewId == view) {
|
||||||
return lastPosition.position;
|
return lastPosition.position;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,10 @@ export class EditorMonitor extends Disposable {
|
|||||||
super();
|
super();
|
||||||
|
|
||||||
// create store
|
// create store
|
||||||
this._store = new EditMemoryStorage(doc.docId(), store);
|
const userId = doc.app.topAppModel.appObs.get()?.currentUser?.id ?? null;
|
||||||
|
// use document id and user id as a key for storage
|
||||||
|
const key = doc.docId() + userId;
|
||||||
|
this._store = new EditMemoryStorage(key, store);
|
||||||
|
|
||||||
// listen to document events to handle view load event
|
// listen to document events to handle view load event
|
||||||
this._listenToReload(doc);
|
this._listenToReload(doc);
|
||||||
@ -58,8 +61,8 @@ export class EditorMonitor extends Disposable {
|
|||||||
// will be invoked only once
|
// will be invoked only once
|
||||||
let executed = false;
|
let executed = false;
|
||||||
|
|
||||||
// don't restore on readonly mode
|
// don't restore on readonly mode or when there is custom nav
|
||||||
if (doc.isReadonly.get()) { return; }
|
if (doc.isReadonly.get() || doc.hasCustomNav.get()) { return; }
|
||||||
|
|
||||||
// on view shown
|
// on view shown
|
||||||
this._currentViewListener.autoDispose(doc.currentView.addListener(async view => {
|
this._currentViewListener.autoDispose(doc.currentView.addListener(async view => {
|
||||||
@ -114,7 +117,7 @@ class EditMemoryStorage {
|
|||||||
private _entry: LastEditData | null = null;
|
private _entry: LastEditData | null = null;
|
||||||
private _timestamp = 0;
|
private _timestamp = 0;
|
||||||
|
|
||||||
constructor(private _docId: string, private _storage = getStorage()) {
|
constructor(private _key: string, private _storage = getStorage()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateValue(pos: CellPosition, value: EditorState): void {
|
public updateValue(pos: CellPosition, value: EditorState): void {
|
||||||
@ -136,13 +139,13 @@ class EditMemoryStorage {
|
|||||||
return this._timestamp;
|
return this._timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _key() {
|
protected _storageKey() {
|
||||||
return `grist-last-edit-${this._docId}`;
|
return `grist-last-edit-${this._key}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected load() {
|
protected load() {
|
||||||
const storage = this._storage;
|
const storage = this._storage;
|
||||||
const data = storage.getItem(this._key());
|
const data = storage.getItem(this._storageKey());
|
||||||
this._entry = null;
|
this._entry = null;
|
||||||
this._timestamp = 0;
|
this._timestamp = 0;
|
||||||
|
|
||||||
@ -166,14 +169,14 @@ class EditMemoryStorage {
|
|||||||
|
|
||||||
// if entry was removed - clear the storage
|
// if entry was removed - clear the storage
|
||||||
if (!this._entry) {
|
if (!this._entry) {
|
||||||
storage.removeItem(this._key());
|
storage.removeItem(this._storageKey());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this._timestamp = Date.now();
|
this._timestamp = Date.now();
|
||||||
const data = { timestamp: this._timestamp, entry: this._entry };
|
const data = { timestamp: this._timestamp, entry: this._entry };
|
||||||
storage.setItem(this._key(), JSON.stringify(data));
|
storage.setItem(this._storageKey(), JSON.stringify(data));
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
console.error("Can't save current edited cell state. Error message: " + ex?.message);
|
console.error("Can't save current edited cell state. Error message: " + ex?.message);
|
||||||
}
|
}
|
||||||
|
@ -1838,6 +1838,20 @@ export async function getEnabledOptions(): Promise<SortOption[]> {
|
|||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs action in a separate tab, closing the tab after.
|
||||||
|
* In case of an error tab is not closed, consider using cleanupExtraWindows
|
||||||
|
* on whole test suit if needed.
|
||||||
|
*/
|
||||||
|
export async function onNewTab(action: () => Promise<void>) {
|
||||||
|
await driver.executeScript("return window.open('about:blank', '_blank')");
|
||||||
|
const tabs = await driver.getAllWindowHandles();
|
||||||
|
await driver.switchTo().window(tabs[tabs.length - 1]);
|
||||||
|
await action();
|
||||||
|
await driver.close();
|
||||||
|
await driver.switchTo().window(tabs[tabs.length - 2]);
|
||||||
|
}
|
||||||
|
|
||||||
} // end of namespace gristUtils
|
} // end of namespace gristUtils
|
||||||
|
|
||||||
stackWrapOwnMethods(gristUtils);
|
stackWrapOwnMethods(gristUtils);
|
||||||
|
Loading…
Reference in New Issue
Block a user