mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-27 18:12:29 +08:00
Merge pull request #391 from SiriusXT/revisions_number_limit
Revisions number limit
This commit is contained in:
commit
8faa26b663
@ -3,6 +3,8 @@
|
|||||||
import protectedSessionService from "../../services/protected_session.js";
|
import protectedSessionService from "../../services/protected_session.js";
|
||||||
import log from "../../services/log.js";
|
import log from "../../services/log.js";
|
||||||
import sql from "../../services/sql.js";
|
import sql from "../../services/sql.js";
|
||||||
|
import optionService from "../../services/options.js";
|
||||||
|
import eraseService from "../../services/erase.js";
|
||||||
import utils from "../../services/utils.js";
|
import utils from "../../services/utils.js";
|
||||||
import dateUtils from "../../services/date_utils.js";
|
import dateUtils from "../../services/date_utils.js";
|
||||||
import AbstractBeccaEntity from "./abstract_becca_entity.js";
|
import AbstractBeccaEntity from "./abstract_becca_entity.js";
|
||||||
@ -68,7 +70,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
|
|||||||
/** set during the deletion operation, before it is completed (removed from becca completely). */
|
/** set during the deletion operation, before it is completed (removed from becca completely). */
|
||||||
isBeingDeleted!: boolean;
|
isBeingDeleted!: boolean;
|
||||||
isDecrypted!: boolean;
|
isDecrypted!: boolean;
|
||||||
|
|
||||||
ownedAttributes!: BAttribute[];
|
ownedAttributes!: BAttribute[];
|
||||||
parentBranches!: BBranch[];
|
parentBranches!: BBranch[];
|
||||||
parents!: BNote[];
|
parents!: BNote[];
|
||||||
@ -455,8 +457,8 @@ class BNote extends AbstractBeccaEntity<BNote> {
|
|||||||
|
|
||||||
return this.getAttributes().find(
|
return this.getAttributes().find(
|
||||||
attr => attr.name.toLowerCase() === name
|
attr => attr.name.toLowerCase() === name
|
||||||
&& (!value || attr.value.toLowerCase() === value)
|
&& (!value || attr.value.toLowerCase() === value)
|
||||||
&& attr.type === type);
|
&& attr.type === type);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRelationTarget(name: string) {
|
getRelationTarget(name: string) {
|
||||||
@ -1107,7 +1109,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getRevisions(): BRevision[] {
|
getRevisions(): BRevision[] {
|
||||||
return sql.getRows<RevisionRow>("SELECT * FROM revisions WHERE noteId = ?", [this.noteId])
|
return sql.getRows<RevisionRow>("SELECT * FROM revisions WHERE noteId = ? ORDER BY revisions.utcDateCreated ASC", [this.noteId])
|
||||||
.map(row => new BRevision(row));
|
.map(row => new BRevision(row));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1612,10 +1614,31 @@ class BNote extends AbstractBeccaEntity<BNote> {
|
|||||||
|
|
||||||
revision.setContent(noteContent);
|
revision.setContent(noteContent);
|
||||||
|
|
||||||
|
this.eraseExcessRevisionSnapshots()
|
||||||
return revision;
|
return revision;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Limit the number of Snapshots to revisionSnapshotNumberLimit
|
||||||
|
// Delete older Snapshots that exceed the limit
|
||||||
|
eraseExcessRevisionSnapshots() {
|
||||||
|
// lable has a higher priority
|
||||||
|
let revisionSnapshotNumberLimit = parseInt(this.getLabelValue("versioningLimit") ?? "");
|
||||||
|
if (!Number.isInteger(revisionSnapshotNumberLimit)) {
|
||||||
|
revisionSnapshotNumberLimit = parseInt(optionService.getOption('revisionSnapshotNumberLimit'));
|
||||||
|
}
|
||||||
|
if (revisionSnapshotNumberLimit >= 0) {
|
||||||
|
const revisions = this.getRevisions();
|
||||||
|
if (revisions.length - revisionSnapshotNumberLimit > 0) {
|
||||||
|
const revisionIds = revisions
|
||||||
|
.slice(0, revisions.length - revisionSnapshotNumberLimit)
|
||||||
|
.map(revision => revision.revisionId)
|
||||||
|
.filter((id): id is string => id !== undefined);
|
||||||
|
eraseService.eraseRevisions(revisionIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param matchBy - choose by which property we detect if to update an existing attachment.
|
* @param matchBy - choose by which property we detect if to update an existing attachment.
|
||||||
* Supported values are either 'attachmentId' (default) or 'title'
|
* Supported values are either 'attachmentId' (default) or 'title'
|
||||||
|
@ -8,6 +8,7 @@ import openService from "../../services/open.js";
|
|||||||
import protectedSessionHolder from "../../services/protected_session_holder.js";
|
import protectedSessionHolder from "../../services/protected_session_holder.js";
|
||||||
import BasicWidget from "../basic_widget.js";
|
import BasicWidget from "../basic_widget.js";
|
||||||
import dialogService from "../../services/dialog.js";
|
import dialogService from "../../services/dialog.js";
|
||||||
|
import options from "../../services/options.js";
|
||||||
|
|
||||||
const TPL = `
|
const TPL = `
|
||||||
<div class="revisions-dialog modal fade mx-auto" tabindex="-1" role="dialog">
|
<div class="revisions-dialog modal fade mx-auto" tabindex="-1" role="dialog">
|
||||||
@ -66,6 +67,11 @@ const TPL = `
|
|||||||
<div class="revision-content"></div>
|
<div class="revision-content"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal-footer py-0">
|
||||||
|
<span class="revisions-snapshot-interval flex-grow-1 my-0 py-0"></span>
|
||||||
|
<span class="maximum-revisions-for-current-note flex-grow-1 my-0 py-0"></span>
|
||||||
|
<button class="revision-settings-button icon-action bx bx-cog my-0 py-0" title="${t("revisions.settings")}"></button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
@ -85,20 +91,29 @@ export default class RevisionsDialog extends BasicWidget {
|
|||||||
|
|
||||||
this.$list = this.$widget.find(".revision-list");
|
this.$list = this.$widget.find(".revision-list");
|
||||||
this.$listDropdown = this.$widget.find(".revision-list-dropdown");
|
this.$listDropdown = this.$widget.find(".revision-list-dropdown");
|
||||||
|
this.listDropdown = bootstrap.Dropdown.getOrCreateInstance(this.$listDropdown);
|
||||||
this.$content = this.$widget.find(".revision-content");
|
this.$content = this.$widget.find(".revision-content");
|
||||||
this.$title = this.$widget.find(".revision-title");
|
this.$title = this.$widget.find(".revision-title");
|
||||||
this.$titleButtons = this.$widget.find(".revision-title-buttons");
|
this.$titleButtons = this.$widget.find(".revision-title-buttons");
|
||||||
this.$eraseAllRevisionsButton = this.$widget.find(".revisions-erase-all-revisions-button");
|
this.$eraseAllRevisionsButton = this.$widget.find(".revisions-erase-all-revisions-button");
|
||||||
|
this.$snapshotInterval = this.$widget.find(".revisions-snapshot-interval");
|
||||||
this.$listDropdown.dropdown();
|
this.$maximumRevisions = this.$widget.find(".maximum-revisions-for-current-note");
|
||||||
|
this.$revisionSettingsButton = this.$widget.find(".revision-settings-button")
|
||||||
|
this.listDropdown.show();
|
||||||
|
|
||||||
this.$listDropdown.parent().on('hide.bs.dropdown', e => {
|
this.$listDropdown.parent().on('hide.bs.dropdown', e => {
|
||||||
// prevent closing dropdown by clicking outside
|
// Prevent closing dropdown by pressing ESC and clicking outside
|
||||||
if (e.clickEvent) {
|
e.preventDefault();
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.addEventListener('keydown', e => {
|
||||||
|
// Close the revision dialog when revision element is focused and ESC is pressed
|
||||||
|
if (e.key === 'Escape' ||
|
||||||
|
e.target.classList.contains(['dropdown-item', 'active'])) {
|
||||||
|
this.modal.hide();
|
||||||
|
}
|
||||||
|
}, true)
|
||||||
|
|
||||||
this.$widget.on('shown.bs.modal', () => {
|
this.$widget.on('shown.bs.modal', () => {
|
||||||
this.$list.find(`[data-revision-id="${this.revisionId}"]`)
|
this.$list.find(`[data-revision-id="${this.revisionId}"]`)
|
||||||
.trigger('focus');
|
.trigger('focus');
|
||||||
@ -116,11 +131,6 @@ export default class RevisionsDialog extends BasicWidget {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$list.on('click', '.dropdown-item', e => {
|
|
||||||
e.preventDefault();
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$list.on('focus', '.dropdown-item', e => {
|
this.$list.on('focus', '.dropdown-item', e => {
|
||||||
this.$list.find('.dropdown-item').each((i, el) => {
|
this.$list.find('.dropdown-item').each((i, el) => {
|
||||||
$(el).toggleClass('active', el === e.target);
|
$(el).toggleClass('active', el === e.target);
|
||||||
@ -128,6 +138,10 @@ export default class RevisionsDialog extends BasicWidget {
|
|||||||
|
|
||||||
this.setContentPane();
|
this.setContentPane();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.$revisionSettingsButton.on('click', async () => {
|
||||||
|
appContext.tabManager.openContextWithNote('_optionsOther', { activate: true });
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async showRevisionsEvent({ noteId = appContext.tabManager.getActiveContextNoteId() }) {
|
async showRevisionsEvent({ noteId = appContext.tabManager.getActiveContextNoteId() }) {
|
||||||
@ -153,7 +167,7 @@ export default class RevisionsDialog extends BasicWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$listDropdown.dropdown('show');
|
this.listDropdown.show();
|
||||||
|
|
||||||
if (this.revisionItems.length > 0) {
|
if (this.revisionItems.length > 0) {
|
||||||
if (!this.revisionId) {
|
if (!this.revisionId) {
|
||||||
@ -165,6 +179,17 @@ export default class RevisionsDialog extends BasicWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.$eraseAllRevisionsButton.toggle(this.revisionItems.length > 0);
|
this.$eraseAllRevisionsButton.toggle(this.revisionItems.length > 0);
|
||||||
|
|
||||||
|
// Show the footer of the revisions dialog
|
||||||
|
this.$snapshotInterval.text(t("revisions.snapshot_interval", { seconds: options.getInt('revisionSnapshotTimeInterval') }))
|
||||||
|
let revisionsNumberLimit = parseInt(this.note.getLabelValue("versioningLimit") ?? "");
|
||||||
|
if (!Number.isInteger(revisionsNumberLimit)) {
|
||||||
|
revisionsNumberLimit = parseInt(options.getInt('revisionSnapshotNumberLimit'));
|
||||||
|
}
|
||||||
|
if (revisionsNumberLimit === -1) {
|
||||||
|
revisionsNumberLimit = "∞"
|
||||||
|
}
|
||||||
|
this.$maximumRevisions.text(t("revisions.maximum_revisions", { number: revisionsNumberLimit }))
|
||||||
}
|
}
|
||||||
|
|
||||||
async setContentPane() {
|
async setContentPane() {
|
||||||
@ -245,12 +270,20 @@ export default class RevisionsDialog extends BasicWidget {
|
|||||||
} else if (revisionItem.type === 'code') {
|
} else if (revisionItem.type === 'code') {
|
||||||
this.$content.html($("<pre>").text(fullRevision.content));
|
this.$content.html($("<pre>").text(fullRevision.content));
|
||||||
} else if (revisionItem.type === 'image') {
|
} else if (revisionItem.type === 'image') {
|
||||||
this.$content.html($("<img>")
|
if (fullRevision.mime === "image/svg+xml") {
|
||||||
// the reason why we put this inline as base64 is that we do not want to let user copy this
|
let encodedSVG = encodeURIComponent(fullRevision.content); //Base64 of other format images may be embedded in svg
|
||||||
// as a URL to be used in a note. Instead, if they copy and paste it into a note, it will be uploaded as a new note
|
this.$content.html($("<img>")
|
||||||
.attr("src", `data:${fullRevision.mime};base64,${fullRevision.content}`)
|
.attr("src", `data:${fullRevision.mime};utf8,${encodedSVG}`)
|
||||||
.css("max-width", "100%")
|
.css("max-width", "100%")
|
||||||
.css("max-height", "100%"));
|
.css("max-height", "100%"));
|
||||||
|
} else {
|
||||||
|
this.$content.html($("<img>")
|
||||||
|
// the reason why we put this inline as base64 is that we do not want to let user copy this
|
||||||
|
// as a URL to be used in a note. Instead, if they copy and paste it into a note, it will be uploaded as a new note
|
||||||
|
.attr("src", `data:${fullRevision.mime};base64,${fullRevision.content}`)
|
||||||
|
.css("max-width", "100%")
|
||||||
|
.css("max-height", "100%"));
|
||||||
|
}
|
||||||
} else if (revisionItem.type === 'file') {
|
} else if (revisionItem.type === 'file') {
|
||||||
const $table = $("<table cellpadding='10'>")
|
const $table = $("<table cellpadding='10'>")
|
||||||
.append($("<tr>").append(
|
.append($("<tr>").append(
|
||||||
|
@ -23,6 +23,7 @@ import SearchEngineOptions from "./options/other/search_engine.js";
|
|||||||
import TrayOptions from "./options/other/tray.js";
|
import TrayOptions from "./options/other/tray.js";
|
||||||
import NoteErasureTimeoutOptions from "./options/other/note_erasure_timeout.js";
|
import NoteErasureTimeoutOptions from "./options/other/note_erasure_timeout.js";
|
||||||
import RevisionsSnapshotIntervalOptions from "./options/other/revisions_snapshot_interval.js";
|
import RevisionsSnapshotIntervalOptions from "./options/other/revisions_snapshot_interval.js";
|
||||||
|
import RevisionSnapshotsLimitOptions from "./options/other/revision_snapshots_limit.js";
|
||||||
import NetworkConnectionsOptions from "./options/other/network_connections.js";
|
import NetworkConnectionsOptions from "./options/other/network_connections.js";
|
||||||
import AdvancedSyncOptions from "./options/advanced/sync.js";
|
import AdvancedSyncOptions from "./options/advanced/sync.js";
|
||||||
import DatabaseIntegrityCheckOptions from "./options/advanced/database_integrity_check.js";
|
import DatabaseIntegrityCheckOptions from "./options/advanced/database_integrity_check.js";
|
||||||
@ -88,6 +89,7 @@ const CONTENT_WIDGETS = {
|
|||||||
NoteErasureTimeoutOptions,
|
NoteErasureTimeoutOptions,
|
||||||
AttachmentErasureTimeoutOptions,
|
AttachmentErasureTimeoutOptions,
|
||||||
RevisionsSnapshotIntervalOptions,
|
RevisionsSnapshotIntervalOptions,
|
||||||
|
RevisionSnapshotsLimitOptions,
|
||||||
NetworkConnectionsOptions
|
NetworkConnectionsOptions
|
||||||
],
|
],
|
||||||
_optionsAdvanced: [
|
_optionsAdvanced: [
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
import OptionsWidget from "../options_widget.js";
|
||||||
|
import { t } from "../../../../services/i18n.js";
|
||||||
|
import server from "../../../../services/server.js";
|
||||||
|
import toastService from "../../../../services/toast.js";
|
||||||
|
|
||||||
|
const TPL = `
|
||||||
|
<div class="options-section">
|
||||||
|
<h4>${t("revisions_snapshot_limit.note_revisions_snapshot_limit_title")}</h4>
|
||||||
|
|
||||||
|
<p>${t("revisions_snapshot_limit.note_revisions_snapshot_limit_description")}</p>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>${t("revisions_snapshot_limit.snapshot_number_limit_label")}</label>
|
||||||
|
<input class="revision-snapshot-number-limit form-control options-number-input" type="number" min="-1">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="erase-excess-revision-snapshots-now-button btn btn-sm" style="padding: 0 10px">
|
||||||
|
${t('revisions_snapshot_limit.erase_excess_revision_snapshots')}</button>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
export default class RevisionSnapshotsLimitOptions extends OptionsWidget {
|
||||||
|
doRender() {
|
||||||
|
this.$widget = $(TPL);
|
||||||
|
this.$revisionSnapshotsNumberLimit = this.$widget.find(".revision-snapshot-number-limit");
|
||||||
|
this.$revisionSnapshotsNumberLimit.on('change', () => {
|
||||||
|
let revisionSnapshotNumberLimit = this.$revisionSnapshotsNumberLimit.val();
|
||||||
|
if (!isNaN(revisionSnapshotNumberLimit) && revisionSnapshotNumberLimit >= -1) {
|
||||||
|
this.updateOption('revisionSnapshotNumberLimit', revisionSnapshotNumberLimit)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.$eraseExcessRevisionSnapshotsButton = this.$widget.find(".erase-excess-revision-snapshots-now-button");
|
||||||
|
this.$eraseExcessRevisionSnapshotsButton.on('click', () => {
|
||||||
|
server.post('revisions/erase-all-excess-revisions').then(() => {
|
||||||
|
toastService.showMessage(t("revisions_snapshot_limit.erase_excess_revision_snapshots_prompt"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async optionsLoaded(options) {
|
||||||
|
this.$revisionSnapshotsNumberLimit.val(options.revisionSnapshotNumberLimit);
|
||||||
|
}
|
||||||
|
}
|
@ -247,6 +247,9 @@
|
|||||||
"revisions_deleted": "Note revisions has been deleted.",
|
"revisions_deleted": "Note revisions has been deleted.",
|
||||||
"revision_restored": "Note revision has been restored.",
|
"revision_restored": "Note revision has been restored.",
|
||||||
"revision_deleted": "Note revision has been deleted.",
|
"revision_deleted": "Note revision has been deleted.",
|
||||||
|
"snapshot_interval":"Note Revisions Snapshot Interval: {{seconds}}s.",
|
||||||
|
"maximum_revisions":"Maximum revisions for current note: {{number}}.",
|
||||||
|
"settings":"Settings for Note revisions.",
|
||||||
"download_button": "Download",
|
"download_button": "Download",
|
||||||
"mime": "MIME: ",
|
"mime": "MIME: ",
|
||||||
"file_size": "File size:",
|
"file_size": "File size:",
|
||||||
@ -1088,7 +1091,14 @@
|
|||||||
"revisions_snapshot_interval": {
|
"revisions_snapshot_interval": {
|
||||||
"note_revisions_snapshot_interval_title": "Note Revisions Snapshot Interval",
|
"note_revisions_snapshot_interval_title": "Note Revisions Snapshot Interval",
|
||||||
"note_revisions_snapshot_description": "Note revision snapshot time interval is time in seconds after which a new note revision will be created for the note. See <a href=\"https://triliumnext.github.io/Docs/Wiki/note-revisions.html\" class=\"external\">wiki</a> for more info.",
|
"note_revisions_snapshot_description": "Note revision snapshot time interval is time in seconds after which a new note revision will be created for the note. See <a href=\"https://triliumnext.github.io/Docs/Wiki/note-revisions.html\" class=\"external\">wiki</a> for more info.",
|
||||||
"snapshot_time_interval_label": "Note revision snapshot time interval (in seconds)"
|
"snapshot_time_interval_label": "Note revision snapshot time interval (in seconds):"
|
||||||
|
},
|
||||||
|
"revisions_snapshot_limit": {
|
||||||
|
"note_revisions_snapshot_limit_title": "Note Revision Snapshots Limit",
|
||||||
|
"note_revisions_snapshot_limit_description": "The note revision snapshot number limit refers to the maximum number of revisions that can be saved for each note. Where -1 means no limit, 0 means delete all revisions. You can set the maximum revisions for a single note through the #versioningLimit label.",
|
||||||
|
"snapshot_number_limit_label": "Note revision snapshot number limit:",
|
||||||
|
"erase_excess_revision_snapshots": "Erase excess revision snapshots now",
|
||||||
|
"erase_excess_revision_snapshots_prompt": "Excess revision snapshots have been erased."
|
||||||
},
|
},
|
||||||
"search_engine": {
|
"search_engine": {
|
||||||
"title": "Search Engine",
|
"title": "Search Engine",
|
||||||
|
@ -11,6 +11,7 @@ const ALLOWED_OPTIONS = new Set([
|
|||||||
'eraseEntitiesAfterTimeInSeconds',
|
'eraseEntitiesAfterTimeInSeconds',
|
||||||
'protectedSessionTimeout',
|
'protectedSessionTimeout',
|
||||||
'revisionSnapshotTimeInterval',
|
'revisionSnapshotTimeInterval',
|
||||||
|
'revisionSnapshotNumberLimit',
|
||||||
'zoomFactor',
|
'zoomFactor',
|
||||||
'theme',
|
'theme',
|
||||||
'syncServerHost',
|
'syncServerHost',
|
||||||
|
@ -112,6 +112,13 @@ function eraseRevision(req: Request) {
|
|||||||
eraseService.eraseRevisions([req.params.revisionId]);
|
eraseService.eraseRevisions([req.params.revisionId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function eraseAllExcessRevisions() {
|
||||||
|
let allNoteIds = sql.getRows("SELECT noteId FROM notes WHERE SUBSTRING(noteId, 1, 1) != '_'") as { noteId: string }[];
|
||||||
|
allNoteIds.forEach(row => {
|
||||||
|
becca.getNote(row.noteId)?.eraseExcessRevisionSnapshots()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function restoreRevision(req: Request) {
|
function restoreRevision(req: Request) {
|
||||||
const revision = becca.getRevision(req.params.revisionId);
|
const revision = becca.getRevision(req.params.revisionId);
|
||||||
|
|
||||||
@ -139,6 +146,8 @@ function restoreRevision(req: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
note.title = revision.title;
|
note.title = revision.title;
|
||||||
|
note.mime = revision.mime;
|
||||||
|
note.type = revision.type as any;
|
||||||
note.setContent(revisionContent, { forceSave: true });
|
note.setContent(revisionContent, { forceSave: true });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -211,6 +220,7 @@ export default {
|
|||||||
downloadRevision,
|
downloadRevision,
|
||||||
getEditedNotesOnDate,
|
getEditedNotesOnDate,
|
||||||
eraseAllRevisions,
|
eraseAllRevisions,
|
||||||
|
eraseAllExcessRevisions,
|
||||||
eraseRevision,
|
eraseRevision,
|
||||||
restoreRevision
|
restoreRevision
|
||||||
};
|
};
|
||||||
|
@ -184,6 +184,7 @@ function register(app: express.Application) {
|
|||||||
|
|
||||||
apiRoute(GET, '/api/notes/:noteId/revisions', revisionsApiRoute.getRevisions);
|
apiRoute(GET, '/api/notes/:noteId/revisions', revisionsApiRoute.getRevisions);
|
||||||
apiRoute(DEL, '/api/notes/:noteId/revisions', revisionsApiRoute.eraseAllRevisions);
|
apiRoute(DEL, '/api/notes/:noteId/revisions', revisionsApiRoute.eraseAllRevisions);
|
||||||
|
apiRoute(PST, '/api/revisions/erase-all-excess-revisions', revisionsApiRoute.eraseAllExcessRevisions);
|
||||||
apiRoute(GET, '/api/revisions/:revisionId', revisionsApiRoute.getRevision);
|
apiRoute(GET, '/api/revisions/:revisionId', revisionsApiRoute.getRevision);
|
||||||
apiRoute(GET, '/api/revisions/:revisionId/blob', revisionsApiRoute.getRevisionBlob);
|
apiRoute(GET, '/api/revisions/:revisionId/blob', revisionsApiRoute.getRevisionBlob);
|
||||||
apiRoute(DEL, '/api/revisions/:revisionId', revisionsApiRoute.eraseRevision);
|
apiRoute(DEL, '/api/revisions/:revisionId', revisionsApiRoute.eraseRevision);
|
||||||
|
@ -49,6 +49,7 @@ async function initNotSyncedOptions(initialized: boolean, theme: string, opts: N
|
|||||||
|
|
||||||
const defaultOptions: DefaultOption[] = [
|
const defaultOptions: DefaultOption[] = [
|
||||||
{ name: 'revisionSnapshotTimeInterval', value: '600', isSynced: true },
|
{ name: 'revisionSnapshotTimeInterval', value: '600', isSynced: true },
|
||||||
|
{ name: 'revisionSnapshotNumberLimit', value: '-1', isSynced: true },
|
||||||
{ name: 'protectedSessionTimeout', value: '600', isSynced: true },
|
{ name: 'protectedSessionTimeout', value: '600', isSynced: true },
|
||||||
{ name: 'zoomFactor', value: process.platform === "win32" ? '0.9' : '1.0', isSynced: false },
|
{ name: 'zoomFactor', value: process.platform === "win32" ? '0.9' : '1.0', isSynced: false },
|
||||||
{ name: 'overrideThemeFonts', value: 'false', isSynced: false },
|
{ name: 'overrideThemeFonts', value: 'false', isSynced: false },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user