From 540638001673141f80e73d8e8377a3d4f1fa5cd5 Mon Sep 17 00:00:00 2001 From: Justice Vellacott Date: Thu, 4 Jun 2026 05:48:53 -0400 Subject: [PATCH] Release 1.9.2 --- CHANGELOG.md | 12 ++++++++++++ eslint.config.mjs | 4 ++-- manifest.json | 2 +- package-lock.json | 8 ++++---- package.json | 2 +- src/features/fab.ts | 2 ++ src/settings.ts | 19 +++++++++++++++++++ src/utils/gesture-handler.ts | 8 +++++++- styles.css | 35 +++++++++++++++++++++++++++++++---- 9 files changed, 79 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d093cd..3c8464b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to the Mobile UX plugin will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.9.2] - 2026-06-04 + +### Added + +- **Gestures**: Added an advanced setting to control the minimum drag length required for gesture recognition. +- **FAB**: Added top-middle and bottom-middle floating action button position options, plus distance-from-edge controls through the Style Settings plugin. (Fixes #37) + +### Fixed + +- **FAB**: Fixed floating action button gesture recognition to respect the configured minimum gesture length instead of using a hardcoded threshold, making shorter gestures easier to trigger. (Fixes #38) +- **FAB**: Fixed floating action button positioning variables so Style Settings-based FAB placement works more consistently with raised and hidden navigation states. + ## [1.9.1] - 2026-06-02 ### Changed diff --git a/eslint.config.mjs b/eslint.config.mjs index c557cd0..3be9545 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -21,11 +21,11 @@ export default defineConfig([ }, }, rules: { - "arrow-body-style": ["error", "as-needed"], + 'arrow-body-style': ['error', 'as-needed'], 'obsidianmd/ui/sentence-case': [ 'error', { - acronyms: ['OK', 'FAB'], + acronyms: ['OK', 'FAB', 'UX'], enforceCamelCaseLower: true, }, ], diff --git a/manifest.json b/manifest.json index 40bb453..945a444 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "mobile", "name": "Mobile UX", - "version": "1.9.1", + "version": "1.9.2", "minAppVersion": "1.11.4", "description": "UX enhancements with floating action button, context-aware toolbars, and gestures.", "author": "Justice Vellacott", diff --git a/package-lock.json b/package-lock.json index ee8434e..584f2b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,19 @@ { "name": "obsidian-mobile-plugin", - "version": "1.9.1", + "version": "1.9.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "obsidian-mobile-plugin", - "version": "1.9.1", + "version": "1.9.2", "license": "MIT", "dependencies": { "apocalypse-throttle": "^0.0.0" }, "devDependencies": { - "@codemirror/language": "latest", - "@codemirror/view": "latest", + "@codemirror/language": "^6.11.3", + "@codemirror/view": "^6.38.6", "@eslint/js": "^10.0.1", "@eslint/json": "^2.0.0", "@types/node": "^25.9.1", diff --git a/package.json b/package.json index 89abeff..cf3df3f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-mobile-plugin", - "version": "1.9.1", + "version": "1.9.2", "description": "UX enhancements with floating action button, context-aware toolbars, and gestures.", "main": "main.js", "scripts": { diff --git a/src/features/fab.ts b/src/features/fab.ts index fa31b30..010f157 100644 --- a/src/features/fab.ts +++ b/src/features/fab.ts @@ -160,6 +160,8 @@ class MobileFAB extends ButtonComponent { : g.openCommandSelection(), ); }, + false, + this.plugin, ); }); this.setMode(this.plugin.fabManager?.getMode() || 'default'); diff --git a/src/settings.ts b/src/settings.ts index 0677eb7..021186f 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -101,6 +101,7 @@ export interface MobilePluginSettings { showTabsInSearchView: boolean; hideFABWhenKeyboardOpen: boolean; hideNativeNav: boolean; + minGestureLength: number; } export const DEFAULT_SETTINGS: MobilePluginSettings = { @@ -116,6 +117,7 @@ export const DEFAULT_SETTINGS: MobilePluginSettings = { showToolbars: true, showFAB: true, gestureCommands: [], + minGestureLength: 20, toolbars: [ { id: 'formatting', @@ -785,6 +787,22 @@ export class MobileSettingsView { this.renderToolbars(); this.renderContextBindings(); + new SettingGroup(this.containerEl).setHeading('Advanced').addSetting( + setting => + void setting + .setName('Minimum gesture length') + .setDesc( + 'Minimum length (in pixels) for a gesture to be recognized; adjust if you find gestures are triggering accidentally or not being recognized', + ) + .addSlider(slider => + slider + .setLimits(10, 200, 10) + .setValue(this.plugin.settings.minGestureLength) + .onChange(value => { + this.sett('minGestureLength', value); + }), + ), + ); new SettingGroup(this.containerEl) .setHeading('Danger Zone') .addSetting( @@ -1008,6 +1026,7 @@ export class EditGestureDrawingModal extends Modal { this.close(); }, true, + this.plugin, ); } diff --git a/src/utils/gesture-handler.ts b/src/utils/gesture-handler.ts index 32571a0..2466ce8 100644 --- a/src/utils/gesture-handler.ts +++ b/src/utils/gesture-handler.ts @@ -1,4 +1,5 @@ import { App, addIcon } from 'obsidian'; +import MobilePlugin from 'src/main'; /** * Represents a command that can be triggered by a gesture. @@ -90,6 +91,7 @@ export class GestureHandler { gestureCommand: GestureCommand | null, ) => void, private dryRun: boolean = false, + private plugin: MobilePlugin, ) { this.element.addEventListener('touchstart', this.startDrag); this.element.addEventListener('mousedown', this.startDrag); @@ -211,7 +213,11 @@ export class GestureHandler { detectGesture(): void { if (this.line.length < 2) return; - if (GestureHandler.getLength(this.line) < 100) return; + if ( + GestureHandler.getLength(this.line) < + this.plugin.settings.minGestureLength + ) + return; const normalizedInput = GestureHandler.normalizeLine(this.line); const bestMatch = this.findGesture(this.line); diff --git a/styles.css b/styles.css index 5089f55..07819f7 100644 --- a/styles.css +++ b/styles.css @@ -18,8 +18,10 @@ settings: options: - mobile-fab-bottom-right - mobile-fab-bottom-left + - mobile-fab-bottom-middle - mobile-fab-top-right - mobile-fab-top-left + - mobile-fab-top-middle - id: mobile-fab-dragline-hidden title: Hide FAB Dragline @@ -37,7 +39,14 @@ settings: step: 5 */ -body:has(.mobile-navbar.mod-raised).is-phone { +body { + --fab-bottom: var(--mobile-fab-distance-from-edge, 20px); + --fab-top: calc( + var(--view-header-top-offset) + var(--mobile-fab-distance-from-edge, 20px) + ); +} + +body:has(.mobile-navbar.mod-raised) { --fab-bottom: calc( var(--navbar-height) + 34px + var(--mobile-fab-distance-from-edge, 20px) ); @@ -47,8 +56,8 @@ body:has(.mobile-navbar.mod-raised).is-phone { ); } -body:has(.mobile-navbar.mod-raised).is-hidden-nav.is-phone, -.is-hidden-nav.is-phone { +body:has(.mobile-navbar.mod-raised).is-hidden-nav, +.is-hidden-nav { --fab-bottom: var(--mobile-fab-distance-from-edge, 20px); --fab-top: calc( var(--view-header-top-offset) + var(--mobile-fab-distance-from-edge, 20px) @@ -91,6 +100,14 @@ body:has(.mobile-navbar.mod-raised).is-hidden-nav.is-phone, right: auto; } +.mobile-fab-bottom-middle .mobile-fab { + top: auto; + bottom: var(--fab-bottom, 20px); + left: 50%; + transform: translateX(-50%); + right: auto; +} + .mobile-fab-top-right .mobile-fab { top: var(--fab-top, 20px); bottom: auto; @@ -105,6 +122,14 @@ body:has(.mobile-navbar.mod-raised).is-hidden-nav.is-phone, right: auto; } +.mobile-fab-top-middle .mobile-fab { + top: var(--fab-top, 20px); + bottom: auto; + left: 50%; + transform: translateX(-50%); + right: auto; +} + .mobile-fab:hover { transform: scale(1.05); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.4); @@ -154,7 +179,9 @@ body:has(.mobile-navbar.mod-raised).is-hidden-nav.is-phone, } .mobile-fab-top-right .mobile-plugin-toolbar, -.mobile-fab-top-left .mobile-plugin-toolbar { +.mobile-fab-top-left .mobile-plugin-toolbar, +.mobile-fab-top-middle .mobile-plugin-toolbar, +.mobile-fab-bottom-middle .mobile-plugin-toolbar { padding-right: 8px; }