Improve mobile navigation through history (#686)

* History back and forward commands
* Conditionally display actionButtons on mobile devices
pull/690/head
Marek S. Łukasiewicz 2024-02-07 09:33:47 +01:00 committed by GitHub
parent bfd8ef9cd2
commit 257c7a3e4a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 47 additions and 4 deletions

View File

@ -73,6 +73,15 @@ export function openUrl(url: string, existingWindow = false): Promise<void> {
return syscall("editor.openUrl", url, existingWindow);
}
/**
* This is calling the `go()` method from the History Web API.
* @param delta Position in history to move to relative to the current page,
* where a negative value moves backwards, and positive forwards
*/
export function goHistory(delta: number): Promise<void> {
return syscall("editor.goHistory", delta);
}
// Force the client to download the file in dataUrl with filename as file name
export function downloadFile(filename: string, dataUrl: string): Promise<void> {
return syscall("editor.downloadFile", filename, dataUrl);

View File

@ -89,6 +89,14 @@ functions:
command:
name: "Navigate: To URL"
hide: true
navigateBack:
path: "./navigate.ts:navigateBack"
command:
name: "Navigate: Back in History"
navigateForward:
path: "./navigate.ts:navigateForward"
command:
name: "Navigate: Forward in History"
# Text editing commands
quoteSelectionCommand:
@ -185,7 +193,6 @@ functions:
path: ./embed.ts:embedWidget
codeWidget: embed
# Vim
toggleVimMode:
path: "./vim.ts:toggleVimMode"
@ -302,4 +309,4 @@ functions:
name: "Flash: Custom Message"
hide: true
contexts:
- internal
- internal

View File

@ -140,3 +140,11 @@ export async function navigateToPage(_cmdDef: any, pageName: string) {
export async function navigateToURL(_cmdDef: any, url: string) {
await editor.openUrl(url, false);
}
export async function navigateBack() {
await editor.goHistory(-1);
}
export async function navigateForward() {
await editor.goHistory(1);
}

View File

@ -10,6 +10,7 @@ export type ActionButton = {
class?: string;
callback: () => void;
href?: string;
mobile?: boolean;
};
export function TopBar({
@ -17,6 +18,7 @@ export function TopBar({
unsavedChanges,
syncFailures,
isLoading,
isMobile,
notifications,
onRename,
actionButtons,
@ -32,6 +34,7 @@ export function TopBar({
unsavedChanges: boolean;
syncFailures: number;
isLoading: boolean;
isMobile: boolean;
notifications: Notification[];
darkMode: boolean;
vimMode: boolean;

View File

@ -192,6 +192,7 @@ export class MainUI {
syncFailures={viewState.syncFailures}
unsavedChanges={viewState.unsavedChanges}
isLoading={viewState.isLoading}
isMobile={viewState.isMobile}
vimMode={viewState.uiOptions.vimMode}
darkMode={viewState.uiOptions.darkMode}
progressPerc={viewState.progressPerc}
@ -248,7 +249,9 @@ export class MainUI {
},
}]
: [],
...viewState.settings.actionButtons.map((button) => {
...viewState.settings.actionButtons
.filter((button) => (typeof button.mobile === "undefined") || (button.mobile === viewState.isMobile))
.map((button) => {
const parsedCommand = parseCommand(button.command);
let featherIcon =
(featherIcons as any)[kebabToCamel(button.icon)];

View File

@ -18,10 +18,12 @@ export default function reducer(
bottom: {},
},
};
case "page-loaded":
case "page-loaded": {
const mouseDetected = window.matchMedia("(any-pointer:fine)").matches;
return {
...state,
isLoading: false,
isMobile: !mouseDetected,
allPages: state.allPages.map((pageMeta) =>
pageMeta.name === action.meta.name
? { ...pageMeta, lastOpened: Date.now() }
@ -30,6 +32,7 @@ export default function reducer(
currentPage: action.meta.name,
currentPageMeta: action.meta,
};
}
case "page-changed":
return {
...state,

View File

@ -73,6 +73,9 @@ export function editorSyscalls(client: Client): SysCallMapping {
location.href = url;
}
},
"editor.goHistory": (_ctx, delta: number) => {
window.history.go(delta);
},
"editor.downloadFile": (_ctx, filename: string, dataUrl: string) => {
const link = document.createElement("a");
link.href = dataUrl;

View File

@ -32,6 +32,7 @@ export type ActionButton = {
description?: string;
command: string;
args?: any[];
mobile?: boolean;
};
export type EmojiConfig = {
@ -62,6 +63,7 @@ export type AppViewState = {
allPages: PageMeta[];
isLoading: boolean;
isMobile: boolean;
showPageNavigator: boolean;
showCommandPalette: boolean;
showCommandPaletteContext?: string;
@ -116,6 +118,7 @@ export const initialViewState: AppViewState = {
darkMode: false,
forcedROMode: false,
},
isMobile: false,
panels: {
lhs: {},
rhs: {},

View File

@ -27,6 +27,10 @@ actionButtons:
- icon: terminal
command: "{[Open Command Palette]}"
description: Run command
- icon: arrow-left
command: "{[Navigate: Back in History]}"
description: "Go to the previous page"
mobile: true # Only show on mobile devices, set to false to show only on desktop
# Override keyboard shortcuts and command priority
shortcuts: