mirror of
https://github.com/photoprism/photoprism.git
synced 2026-07-17 16:49:04 +00:00
Settings: Add UI OpenOnHover setting for hover menus #5650
This commit is contained in:
parent
14edf40abd
commit
6cb38abb43
9 changed files with 60 additions and 15 deletions
|
|
@ -470,6 +470,12 @@ export default class $util {
|
|||
return navigator.maxTouchPoints > 0;
|
||||
}
|
||||
|
||||
// shouldOpenOnHover reports whether menus should open on hover: the user's UI
|
||||
// preference (default on) gated by the device having no touch input.
|
||||
static shouldOpenOnHover() {
|
||||
return ($config.getSettings()?.ui?.openOnHover ?? true) && !$util.hasTouch();
|
||||
}
|
||||
|
||||
// isMobile returns true when the current user agent or touch capability indicates a mobile device.
|
||||
// The `> 2` touch check covers iPads in desktop mode, where the user agent omits the mobile hint.
|
||||
static isMobile() {
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ export default {
|
|||
return {
|
||||
visible: false,
|
||||
actions: [],
|
||||
openOnHover: !this.$util.hasTouch(),
|
||||
openOnHover: this.$util.shouldOpenOnHover(),
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
open: false,
|
||||
openOnHover: !this.$util.hasTouch(),
|
||||
openOnHover: this.$util.shouldOpenOnHover(),
|
||||
instances: [],
|
||||
};
|
||||
},
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export default {
|
|||
return {
|
||||
visible: false,
|
||||
actions: [],
|
||||
openOnHover: !this.$util.hasTouch(),
|
||||
openOnHover: this.$util.shouldOpenOnHover(),
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { describe, it, expect, afterEach } from "vitest";
|
|||
import "../fixtures";
|
||||
import $util from "common/util";
|
||||
import { tokenRegexp, tokenLength } from "common/util";
|
||||
import { $config } from "app/session";
|
||||
import * as can from "common/can";
|
||||
import { ContentTypeMp4AvcMain, ContentTypeMp4HvcMain } from "common/media";
|
||||
|
||||
|
|
@ -369,4 +370,36 @@ describe("common/util", () => {
|
|||
expect($util.isMobile()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("shouldOpenOnHover", () => {
|
||||
const maxTouchPoints = navigator.maxTouchPoints;
|
||||
const settings = $config.getSettings();
|
||||
const openOnHover = settings.ui.openOnHover;
|
||||
const stubTouch = (touch) => Object.defineProperty(navigator, "maxTouchPoints", { value: touch, configurable: true });
|
||||
afterEach(() => {
|
||||
stubTouch(maxTouchPoints);
|
||||
settings.ui.openOnHover = openOnHover;
|
||||
});
|
||||
|
||||
it("returns true when enabled and the device has no touch", () => {
|
||||
stubTouch(0);
|
||||
settings.ui.openOnHover = true;
|
||||
expect($util.shouldOpenOnHover()).toBe(true);
|
||||
});
|
||||
it("returns false when the setting is disabled", () => {
|
||||
stubTouch(0);
|
||||
settings.ui.openOnHover = false;
|
||||
expect($util.shouldOpenOnHover()).toBe(false);
|
||||
});
|
||||
it("defaults to true when the setting is absent", () => {
|
||||
stubTouch(0);
|
||||
delete settings.ui.openOnHover;
|
||||
expect($util.shouldOpenOnHover()).toBe(true);
|
||||
});
|
||||
it("returns false on a touch device regardless of the setting", () => {
|
||||
stubTouch(5);
|
||||
settings.ui.openOnHover = true;
|
||||
expect($util.shouldOpenOnHover()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1102,6 +1102,9 @@
|
|||
"language": {
|
||||
"type": "string"
|
||||
},
|
||||
"openOnHover": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"scrollbar": {
|
||||
"type": "boolean"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -53,12 +53,13 @@ func NewSettings(theme, language, timeZone string) *Settings {
|
|||
|
||||
return &Settings{
|
||||
UI: UISettings{
|
||||
Scrollbar: true,
|
||||
Zoom: false,
|
||||
Theme: theme,
|
||||
Language: language,
|
||||
TimeZone: timeZone,
|
||||
StartPage: DefaultStartPage,
|
||||
Scrollbar: true,
|
||||
Zoom: false,
|
||||
OpenOnHover: true,
|
||||
Theme: theme,
|
||||
Language: language,
|
||||
TimeZone: timeZone,
|
||||
StartPage: DefaultStartPage,
|
||||
},
|
||||
Search: SearchSettings{
|
||||
BatchSize: -1,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
UI:
|
||||
Scrollbar: true
|
||||
Zoom: false
|
||||
OpenOnHover: true
|
||||
Theme: onyx
|
||||
Language: de
|
||||
TimeZone: Local
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ package customize
|
|||
|
||||
// UISettings represents user interface settings.
|
||||
type UISettings struct {
|
||||
Scrollbar bool `json:"scrollbar" yaml:"Scrollbar"`
|
||||
Zoom bool `json:"zoom" yaml:"Zoom"`
|
||||
Theme string `json:"theme" yaml:"Theme"`
|
||||
Language string `json:"language" yaml:"Language"`
|
||||
TimeZone string `json:"timeZone" yaml:"TimeZone"`
|
||||
StartPage string `json:"startPage" yaml:"StartPage"`
|
||||
Scrollbar bool `json:"scrollbar" yaml:"Scrollbar"`
|
||||
Zoom bool `json:"zoom" yaml:"Zoom"`
|
||||
OpenOnHover bool `json:"openOnHover" yaml:"OpenOnHover"`
|
||||
Theme string `json:"theme" yaml:"Theme"`
|
||||
Language string `json:"language" yaml:"Language"`
|
||||
TimeZone string `json:"timeZone" yaml:"TimeZone"`
|
||||
StartPage string `json:"startPage" yaml:"StartPage"`
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue