mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-29 19:12:27 +08:00
feat(mobile): add very basic support for tabs
This commit is contained in:
parent
42e4c7800a
commit
027b52e785
@ -237,7 +237,7 @@ class NoteContext extends Component
|
|||||||
|
|
||||||
this.hoistedNoteId = noteIdToHoist;
|
this.hoistedNoteId = noteIdToHoist;
|
||||||
|
|
||||||
if (!this.notePathArray?.includes(noteIdToHoist) && !utils.isMobile()) {
|
if (!this.notePathArray?.includes(noteIdToHoist)) {
|
||||||
await this.setNote(noteIdToHoist);
|
await this.setNote(noteIdToHoist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,10 +62,6 @@ export default class TabManager extends Component {
|
|||||||
], true);
|
], true);
|
||||||
|
|
||||||
const filteredNoteContexts = noteContextsToOpen.filter(openTab => {
|
const filteredNoteContexts = noteContextsToOpen.filter(openTab => {
|
||||||
if (utils.isMobile()) { // mobile frontend doesn't have tabs so show only the active tab
|
|
||||||
return !!openTab.active;
|
|
||||||
}
|
|
||||||
|
|
||||||
const noteId = treeService.getNoteIdFromUrl(openTab.notePath);
|
const noteId = treeService.getNoteIdFromUrl(openTab.notePath);
|
||||||
if (!(noteId in froca.notes)) {
|
if (!(noteId in froca.notes)) {
|
||||||
// note doesn't exist so don't try to open tab for it
|
// note doesn't exist so don't try to open tab for it
|
||||||
@ -272,15 +268,7 @@ export default class TabManager extends Component {
|
|||||||
async openEmptyTab(ntxId = null, hoistedNoteId = 'root', mainNtxId = null) {
|
async openEmptyTab(ntxId = null, hoistedNoteId = 'root', mainNtxId = null) {
|
||||||
const noteContext = new NoteContext(ntxId, hoistedNoteId, mainNtxId);
|
const noteContext = new NoteContext(ntxId, hoistedNoteId, mainNtxId);
|
||||||
|
|
||||||
let existingNoteContext;
|
const existingNoteContext = this.children.find(nc => nc.ntxId === noteContext.ntxId);
|
||||||
|
|
||||||
if (utils.isMobile()) {
|
|
||||||
// kind of hacky way to enforce a single tab on mobile interface - all requests to create a new one
|
|
||||||
// are forced to reuse the existing ab instead
|
|
||||||
existingNoteContext = this.getActiveContext();
|
|
||||||
} else {
|
|
||||||
existingNoteContext = this.children.find(nc => nc.ntxId === noteContext.ntxId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existingNoteContext) {
|
if (existingNoteContext) {
|
||||||
await existingNoteContext.setHoistedNoteId(hoistedNoteId);
|
await existingNoteContext.setHoistedNoteId(hoistedNoteId);
|
||||||
@ -421,7 +409,10 @@ export default class TabManager extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// close dangling autocompletes after closing the tab
|
// close dangling autocompletes after closing the tab
|
||||||
$(".aa-input").autocomplete("close");
|
const $autocompleteEl = $(".aa-input");
|
||||||
|
if ("autocomplete" in $autocompleteEl) {
|
||||||
|
$autocompleteEl.autocomplete("close");
|
||||||
|
}
|
||||||
|
|
||||||
const noteContextsToRemove = noteContextToRemove.getSubContexts();
|
const noteContextsToRemove = noteContextToRemove.getSubContexts();
|
||||||
const ntxIdsToRemove = noteContextsToRemove.map(nc => nc.ntxId);
|
const ntxIdsToRemove = noteContextsToRemove.map(nc => nc.ntxId);
|
||||||
@ -551,7 +542,7 @@ export default class TabManager extends Component {
|
|||||||
await this.removeNoteContext(ntxIdToRemove);
|
await this.removeNoteContext(ntxIdToRemove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async closeOtherTabsCommand({ntxId}) {
|
async closeOtherTabsCommand({ntxId}) {
|
||||||
for (const ntxIdToRemove of this.mainNoteContexts.map(nc => nc.ntxId)) {
|
for (const ntxIdToRemove of this.mainNoteContexts.map(nc => nc.ntxId)) {
|
||||||
if (ntxIdToRemove !== ntxId) {
|
if (ntxIdToRemove !== ntxId) {
|
||||||
@ -589,7 +580,7 @@ export default class TabManager extends Component {
|
|||||||
async copyTabToNewWindowCommand({ntxId}) {
|
async copyTabToNewWindowCommand({ntxId}) {
|
||||||
const {notePath, hoistedNoteId} = this.getNoteContextById(ntxId);
|
const {notePath, hoistedNoteId} = this.getNoteContextById(ntxId);
|
||||||
this.triggerCommand('openInWindow', {notePath, hoistedNoteId});
|
this.triggerCommand('openInWindow', {notePath, hoistedNoteId});
|
||||||
}
|
}
|
||||||
|
|
||||||
async reopenLastTabCommand() {
|
async reopenLastTabCommand() {
|
||||||
let closeLastEmptyTab = null;
|
let closeLastEmptyTab = null;
|
||||||
|
@ -28,6 +28,7 @@ import SidebarContainer from "../widgets/mobile_widgets/sidebar_container.js";
|
|||||||
import AboutDialog from "../widgets/dialogs/about.js";
|
import AboutDialog from "../widgets/dialogs/about.js";
|
||||||
import HelpDialog from "../widgets/dialogs/help.js";
|
import HelpDialog from "../widgets/dialogs/help.js";
|
||||||
import AppContext from "../components/app_context.js";
|
import AppContext from "../components/app_context.js";
|
||||||
|
import TabRowWidget from "../widgets/tab_row.js";
|
||||||
|
|
||||||
const MOBILE_CSS = `
|
const MOBILE_CSS = `
|
||||||
<style>
|
<style>
|
||||||
@ -183,6 +184,7 @@ export default class MobileLayout {
|
|||||||
.child(new ProtectedSessionPasswordDialog())
|
.child(new ProtectedSessionPasswordDialog())
|
||||||
.child(new ConfirmDialog())
|
.child(new ConfirmDialog())
|
||||||
)
|
)
|
||||||
|
.child(new TabRowWidget().css('height', '40px'))
|
||||||
.child(new FlexContainer("row")
|
.child(new FlexContainer("row")
|
||||||
.class("horizontal")
|
.class("horizontal")
|
||||||
.css("height", "53px")
|
.css("height", "53px")
|
||||||
|
@ -49,10 +49,10 @@ class NoteContextAwareWidget extends BasicWidget {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if the widget is enabled. Widgets are enabled by default. Generally setting this to `false` will cause the widget not to be displayed, however it will still be available on the DOM but hidden.
|
* Indicates if the widget is enabled. Widgets are enabled by default. Generally setting this to `false` will cause the widget not to be displayed, however it will still be available on the DOM but hidden.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* If the widget is not enabled, it will not receive `refreshWithNote` updates.
|
* If the widget is not enabled, it will not receive `refreshWithNote` updates.
|
||||||
*
|
*
|
||||||
* @returns {boolean} true when an active note exists
|
* @returns {boolean} true when an active note exists
|
||||||
*/
|
*/
|
||||||
isEnabled() {
|
isEnabled() {
|
||||||
@ -88,6 +88,7 @@ class NoteContextAwareWidget extends BasicWidget {
|
|||||||
async refreshWithNote(note) {}
|
async refreshWithNote(note) {}
|
||||||
|
|
||||||
async noteSwitchedEvent({noteContext, notePath}) {
|
async noteSwitchedEvent({noteContext, notePath}) {
|
||||||
|
this.noteContext = noteContext;
|
||||||
// if notePath does not match, then the noteContext has been switched to another note in the meantime
|
// if notePath does not match, then the noteContext has been switched to another note in the meantime
|
||||||
if (noteContext.notePath === notePath) {
|
if (noteContext.notePath === notePath) {
|
||||||
await this.noteSwitched();
|
await this.noteSwitched();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user