mirror of
https://github.com/zadam/trilium.git
synced 2025-02-20 21:13:11 +08:00
tabs WIP
This commit is contained in:
parent
7f0c92c56b
commit
b1d0cef33b
4 changed files with 66 additions and 27 deletions
|
@ -50,8 +50,7 @@
|
|||
`
|
||||
|
||||
const defaultTapProperties = {
|
||||
title: 'New tab',
|
||||
favicon: false
|
||||
title: 'New tab'
|
||||
}
|
||||
|
||||
let instanceId = 0
|
||||
|
|
|
@ -17,10 +17,6 @@ import noteDetailRelationMap from "./note_detail_relation_map.js";
|
|||
|
||||
const $noteTabContentsContainer = $("#note-tab-container");
|
||||
|
||||
const el = $('.chrome-tabs')[0];
|
||||
const chromeTabs = new ChromeTabs();
|
||||
chromeTabs.init(el);
|
||||
|
||||
const componentClasses = {
|
||||
'code': noteDetailCode,
|
||||
'text': noteDetailText,
|
||||
|
@ -31,12 +27,25 @@ const componentClasses = {
|
|||
'relation-map': noteDetailRelationMap
|
||||
};
|
||||
|
||||
let tabIdCounter = 1;
|
||||
|
||||
class NoteContext {
|
||||
constructor(note, openOnBackground) {
|
||||
constructor(chromeTabs, note, openOnBackground) {
|
||||
this.tabId = tabIdCounter++;
|
||||
this.chromeTabs = chromeTabs;
|
||||
/** @type {NoteFull} */
|
||||
this.note = note;
|
||||
this.noteId = note.noteId;
|
||||
this.$noteTabContent = $noteTabContentsContainer.find(`[data-note-id="${this.noteId}"]`);
|
||||
|
||||
this.$noteTabContent = $(".note-tab-content-template").clone();
|
||||
this.$noteTabContent.removeClass('note-tab-content-template');
|
||||
this.$noteTabContent.attr('data-note-id', this.noteId);
|
||||
this.$noteTabContent.attr('data-tab-id', this.tabId);
|
||||
|
||||
$noteTabContentsContainer.append(this.$noteTabContent);
|
||||
|
||||
console.log(`Creating note tab ${this.tabId} for ${this.noteId}`);
|
||||
|
||||
this.$noteTitle = this.$noteTabContent.find(".note-title");
|
||||
this.$noteDetailComponents = this.$noteTabContent.find(".note-detail-component");
|
||||
this.$protectButton = this.$noteTabContent.find(".protect-button");
|
||||
|
@ -58,9 +67,9 @@ class NoteContext {
|
|||
treeService.setNoteTitle(this.noteId, title);
|
||||
});
|
||||
|
||||
this.tab = chromeTabs.addTab({
|
||||
this.tab = this.chromeTabs.addTab({
|
||||
title: note.title,
|
||||
favicon: false
|
||||
id: this.tabId
|
||||
}, {
|
||||
background: openOnBackground
|
||||
});
|
||||
|
@ -73,9 +82,11 @@ class NoteContext {
|
|||
this.note = note;
|
||||
this.$noteTabContent.attr('data-note-id', note.noteId);
|
||||
|
||||
chromeTabs.updateTab(this.tab, {title: note.title});
|
||||
this.chromeTabs.updateTab(this.tab, {title: note.title});
|
||||
|
||||
this.attributes.invalidateAttributes();
|
||||
|
||||
console.log(`Switched tab ${this.tabId} to ${this.noteId}`);
|
||||
}
|
||||
|
||||
getComponent(type) {
|
||||
|
|
|
@ -12,6 +12,10 @@ import bundleService from "./bundle.js";
|
|||
import utils from "./utils.js";
|
||||
import importDialog from "../dialogs/import.js";
|
||||
|
||||
const chromeTabsEl = document.querySelector('.chrome-tabs');
|
||||
const chromeTabs = new ChromeTabs();
|
||||
chromeTabs.init(chromeTabsEl);
|
||||
|
||||
const $noteTabContentsContainer = $("#note-tab-container");
|
||||
const $savedIndicator = $(".saved-indicator");
|
||||
|
||||
|
@ -84,7 +88,7 @@ async function handleProtectedSession() {
|
|||
}
|
||||
|
||||
/** @type {NoteContext[]} */
|
||||
const noteContexts = [];
|
||||
let noteContexts = [];
|
||||
|
||||
/** @returns {NoteContext} */
|
||||
function getContext(noteId) {
|
||||
|
@ -107,9 +111,11 @@ function getActiveContext() {
|
|||
}
|
||||
}
|
||||
|
||||
function showTab(noteId) {
|
||||
function showTab(tabId) {
|
||||
tabId = parseInt(tabId);
|
||||
|
||||
for (const ctx of noteContexts) {
|
||||
ctx.$noteTabContent.toggle(ctx.noteId === noteId);
|
||||
ctx.$noteTabContent.toggle(ctx.tabId === tabId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,19 +124,12 @@ async function loadNoteDetail(noteId, newTab = false) {
|
|||
let ctx;
|
||||
|
||||
if (noteContexts.length === 0 || newTab) {
|
||||
const $tabContent = $(".note-tab-content-template").clone();
|
||||
|
||||
$tabContent.removeClass('note-tab-content-template');
|
||||
$tabContent.attr('data-note-id', noteId);
|
||||
|
||||
$noteTabContentsContainer.append($tabContent);
|
||||
|
||||
// if it's a new tab explicitly by user then it's in background
|
||||
ctx = new NoteContext(loadedNote, newTab);
|
||||
ctx = new NoteContext(chromeTabs, loadedNote, newTab);
|
||||
noteContexts.push(ctx);
|
||||
|
||||
if (!newTab) {
|
||||
showTab(noteId);
|
||||
showTab(ctx.tabId);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -270,8 +269,32 @@ $noteTabContentsContainer.on("drop", e => {
|
|||
});
|
||||
});
|
||||
|
||||
document.querySelector('.chrome-tabs')
|
||||
.addEventListener('activeTabChange', ({ detail }) => showTab(detail.tabEl.getAttribute('data-note-id')));
|
||||
chromeTabsEl.addEventListener('activeTabChange', ({ detail }) => {
|
||||
const tabId = detail.tabEl.getAttribute('data-tab-id');
|
||||
|
||||
showTab(tabId);
|
||||
|
||||
console.log(`Activated tab ${tabId}`);
|
||||
});
|
||||
|
||||
chromeTabsEl.addEventListener('tabRemove', ({ detail }) => {
|
||||
const tabId = parseInt(detail.tabEl.getAttribute('data-tab-id'));
|
||||
|
||||
noteContexts = noteContexts.filter(nc => nc.tabId !== tabId);
|
||||
|
||||
console.log(`Removed tab ${tabId}`);
|
||||
});
|
||||
|
||||
if (utils.isElectron()) {
|
||||
utils.bindShortcut('ctrl+w', () => {
|
||||
if (noteContexts.length === 1) {
|
||||
// at least one tab must be present
|
||||
return;
|
||||
}
|
||||
|
||||
chromeTabs.removeTab(chromeTabs.activeTabEl);
|
||||
});
|
||||
}
|
||||
|
||||
// this makes sure that when user e.g. reloads the page or navigates away from the page, the note's content is saved
|
||||
// this sends the request asynchronously and doesn't wait for result
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import utils from './utils.js';
|
||||
import infoService from "./info.js";
|
||||
|
||||
const REQUEST_LOGGING_ENABLED = false;
|
||||
|
||||
function getHeaders() {
|
||||
// headers need to be lowercase because node.js automatically converts them to lower case
|
||||
// so hypothetical protectedSessionId becomes protectedsessionid on the backend
|
||||
|
@ -45,7 +47,9 @@ async function call(method, url, data) {
|
|||
return new Promise((resolve, reject) => {
|
||||
reqResolves[requestId] = resolve;
|
||||
|
||||
console.log(utils.now(), "Request #" + requestId + " to " + method + " " + url);
|
||||
if (REQUEST_LOGGING_ENABLED) {
|
||||
console.log(utils.now(), "Request #" + requestId + " to " + method + " " + url);
|
||||
}
|
||||
|
||||
ipc.send('server-request', {
|
||||
requestId: requestId,
|
||||
|
@ -89,7 +93,9 @@ if (utils.isElectron()) {
|
|||
const ipc = require('electron').ipcRenderer;
|
||||
|
||||
ipc.on('server-response', (event, arg) => {
|
||||
console.log(utils.now(), "Response #" + arg.requestId + ": " + arg.statusCode);
|
||||
if (REQUEST_LOGGING_ENABLED) {
|
||||
console.log(utils.now(), "Response #" + arg.requestId + ": " + arg.statusCode);
|
||||
}
|
||||
|
||||
reqResolves[arg.requestId](arg.body);
|
||||
|
||||
|
|
Loading…
Reference in a new issue