[Mobile] Make the reading mode toggle button more reachable (overrides the ribbon menu button)

I wanted to make the (reading/preview)/editing mode button on mobile more reachable. I also don’t use the menu for ribbon items on the mobile navigation toolbar[1].

So, I used CodeScript Toolkit to do it.

It probably could be improved, but this .js file:

  1. Hides the reading mode toggle in the Obsidian app header
    • But shows it when the app is in tablet mode (so if you have a foldable you don’t get stuck without the button)
  2. Replaces the menu for ribbon items in the mobile navigation toolbar with a button that works similar to the “real” reading mode toggle button
    • You actually can still go into the ribbon menu by long-pressing the button

Point CodeScript Toolkit to it as your “Startup script path.”

import { setIcon } from 'obsidian';

exports.invoke = async (app) => {
	function setreadingicon(button) {
		setTimeout(() => {
			const mode = app.workspace.activeLeaf.view.currentMode?.type;
			if (!mode) {
				setIcon(button, 'flame');
				return;
			}
		
			const iconName = mode === 'preview' ? 'edit-3' : 'book-open';
			setIcon(button, iconName);
		}, 10);
	}

	const button = app?.mobileNavbar?.ribbonMenuItemEl;
	if (button) {
		setreadingicon(button);

		['click', 'mousedown', 'mouseup'].forEach(type => {
			button.addEventListener(type, (event) => {
				event.preventDefault();
				event.stopImmediatePropagation();

				if (type === 'click') {
					app.commands.executeCommandById('markdown:toggle-preview');
				}
			}, true);
		});

		app.workspace.on('active-leaf-change', () => {
			setreadingicon(button);
		});
		
		app.workspace.on('layout-change', () => {
			setreadingicon(button);
		});
		
		function hidetopreadingviewtoggleifphone() {
			const isPhone = document.body.classList.contains('is-phone');
			document
			.querySelectorAll('.clickable-icon.view-action')
			.forEach(el => {
				const label = el.getAttribute('aria-label') || '';
				if (label.startsWith("Current view")) {
					el.style.display = isPhone ? 'none' : '';
				}
			});
		}
		hidetopreadingviewtoggleifphone()
		
		app.workspace.on('resize', () => {
			setTimeout(() => {
				hidetopreadingviewtoggleifphone()
			}, 200);
		});
	}
}

  1. Since I use custom Vim bindings with the Obsidian Vimrc Support Plugin plus an Android softkeyboard that can do hotkeys (FlickBoard). ↩︎

A possible alternate approach is to add the reading view toggle to the ribbon (probably using the Commander plugin), then set Settings > Appearance > Ribbon menu configuration > “Quick access ribbon item” to the toggle. This gives the same behavior, replacing the ribbon button with the toggle and opening the ribbon on long press. A possible hitch is that I don’t know for sure if items added to the ribbon by Commander are selectable in that quick access setting.

My way changes the icon based on if in reading mode or not.
Record_2025-06-03-17-40-57_51606159b24eff83e24a54116878fe3e2-ezgif.com-video-to-gif-converter

Ah, nice. I don’t know if the Commander way would do that but I’m guessing not.