openvibers/openvibe.network Commits
Motion follows the account: display 'motion' takes auto, full, reduced or off (#747)
Changes
@@@ -161,7 +161,8 @@ One mark for every site, tinted per site (`SITES`): `svg({ site, maskable })`, `## 10. Display preferences (in `theme-loader.js`)--`OpenVibeThemeLoader.display.get()` / `.set({ motion: 'auto'|'reduced', text: '100'|'112'|'125' })`.++`OpenVibeThemeLoader.display.get()` / `.set({ motion: 'auto'|'full'|'reduced'|'off', text: '100'|'112'|'125' })`++(motion's four choices, openvibe-shared 4.183.0).Applied before first paint as `<html data-ov-motion>` and `--ov-text-scale` / `data-ov-text`; storedin `localStorage.ov_display`, synced across tabs, saved to the account through`PUT /api/themes/me/display` and returned by `GET /api/themes/me/active` (`display`). Emits@@@ -180,7 +180,9 @@ router.get('/me/active', (req, res, next) => {// oled: use pure black backgrounds on OLED displays.// icons: the person's icon style (openvibe-shared 4.71.0, plan L56): auto (line; solid when small or for the tab you are// on), line or solid, on every OpenVibe site.--const DISPLAY = { motion: ['auto', 'reduced'], text: ['100', '112', '125'], seasonal: ['on', 'off'], scheme: ['manual', 'auto'], contrast: ['normal', 'more'], font: ['default', 'readable'], colors: ['default', 'cb-safe'], oled: ['off', 'on'], icons: ['auto', 'line', 'solid'] };++// motion: auto, full, reduced or off (openvibe-shared 4.183.0): full plays everything even when the device asks for++// less, reduced is calm, and only off stops motion. The account keeps the choice; the shared theme loader applies it.++const DISPLAY = { motion: ['auto', 'full', 'reduced', 'off'], text: ['100', '112', '125'], seasonal: ['on', 'off'], scheme: ['manual', 'auto'], contrast: ['normal', 'more'], font: ['default', 'readable'], colors: ['default', 'cb-safe'], oled: ['off', 'on'], icons: ['auto', 'line', 'solid'] };function cleanDisplay(d) {if (!d || typeof d !== 'object') return null;const out = {};@@@ -119,6 +119,13 @@ const token = async (id) => signToken(await db.prepare('SELECT * FROM users WHERassert.strictEqual(r.body.display.icons, 'solid', 'a person who prefers solid icons keeps that on every site');assert.strictEqual((await call('GET', '/api/themes/me/active', { as: 2 })).body.display.icons, 'solid');assert.strictEqual((await call('PUT', '/api/themes/me/display', { as: 2, body: { icons: 'outline' } })).body.display.icons, undefined, 'only auto, line or solid');++ // Motion (openvibe-shared 4.183.0): auto, full, reduced or off follows the account, and each one reads back.++ for (const motion of ['auto', 'full', 'reduced', 'off']) {++ r = await call('PUT', '/api/themes/me/display', { as: 2, body: { motion } });++ assert.strictEqual(r.body.display.motion, motion, `motion ${motion} is kept`);++ assert.strictEqual((await call('GET', '/api/themes/me/active', { as: 2 })).body.display.motion, motion, `motion ${motion} reads back`);++ }++ assert.strictEqual((await call('PUT', '/api/themes/me/display', { as: 2, body: { motion: 'calm' } })).body.display.motion, undefined, 'only auto, full, reduced or off');// ── The site switcher's pinned and recent sites follow the account (migration 0029) ──r = await call('GET', '/api/themes/me/sites', { as: 2 });
@@ -161,7 +161,8 @@ One mark for every site, tinted per site (`SITES`): `svg({ site, maskable })`, `
@@ -161,7 +161,8 @@ One mark for every site, tinted per site (`SITES`): `svg({ site, maskable })`, `
## 10. Display preferences (in `theme-loader.js`)
## 10. Display preferences (in `theme-loader.js`)
-`OpenVibeThemeLoader.display.get()` / `.set({ motion: 'auto'|'reduced', text: '100'|'112'|'125' })`.
+`OpenVibeThemeLoader.display.get()` / `.set({ motion: 'auto'|'full'|'reduced'|'off', text: '100'|'112'|'125' })`
+(motion's four choices, openvibe-shared 4.183.0).
Applied before first paint as `<html data-ov-motion>` and `--ov-text-scale` / `data-ov-text`; stored
Applied before first paint as `<html data-ov-motion>` and `--ov-text-scale` / `data-ov-text`; stored
in `localStorage.ov_display`, synced across tabs, saved to the account through
in `localStorage.ov_display`, synced across tabs, saved to the account through
`PUT /api/themes/me/display` and returned by `GET /api/themes/me/active` (`display`). Emits
`PUT /api/themes/me/display` and returned by `GET /api/themes/me/active` (`display`). Emits
@@ -180,7 +180,9 @@ router.get('/me/active', (req, res, next) => {
@@ -180,7 +180,9 @@ router.get('/me/active', (req, res, next) => {
// oled: use pure black backgrounds on OLED displays.
// oled: use pure black backgrounds on OLED displays.
// icons: the person's icon style (openvibe-shared 4.71.0, plan L56): auto (line; solid when small or for the tab you are
// icons: the person's icon style (openvibe-shared 4.71.0, plan L56): auto (line; solid when small or for the tab you are
// on), line or solid, on every OpenVibe site.
// on), line or solid, on every OpenVibe site.
-const DISPLAY = { motion: ['auto', 'reduced'], text: ['100', '112', '125'], seasonal: ['on', 'off'], scheme: ['manual', 'auto'], contrast: ['normal', 'more'], font: ['default', 'readable'], colors: ['default', 'cb-safe'], oled: ['off', 'on'], icons: ['auto', 'line', 'solid'] };
+// motion: auto, full, reduced or off (openvibe-shared 4.183.0): full plays everything even when the device asks for
+// less, reduced is calm, and only off stops motion. The account keeps the choice; the shared theme loader applies it.
+const DISPLAY = { motion: ['auto', 'full', 'reduced', 'off'], text: ['100', '112', '125'], seasonal: ['on', 'off'], scheme: ['manual', 'auto'], contrast: ['normal', 'more'], font: ['default', 'readable'], colors: ['default', 'cb-safe'], oled: ['off', 'on'], icons: ['auto', 'line', 'solid'] };
function cleanDisplay(d) {
function cleanDisplay(d) {
if (!d || typeof d !== 'object') return null;
if (!d || typeof d !== 'object') return null;
const out = {};
const out = {};
@@ -119,6 +119,13 @@ const token = async (id) => signToken(await db.prepare('SELECT * FROM users WHER
@@ -119,6 +119,13 @@ const token = async (id) => signToken(await db.prepare('SELECT * FROM users WHER
assert.strictEqual(r.body.display.icons, 'solid', 'a person who prefers solid icons keeps that on every site');
assert.strictEqual(r.body.display.icons, 'solid', 'a person who prefers solid icons keeps that on every site');
assert.strictEqual((await call('GET', '/api/themes/me/active', { as: 2 })).body.display.icons, 'solid');
assert.strictEqual((await call('GET', '/api/themes/me/active', { as: 2 })).body.display.icons, 'solid');
assert.strictEqual((await call('PUT', '/api/themes/me/display', { as: 2, body: { icons: 'outline' } })).body.display.icons, undefined, 'only auto, line or solid');
assert.strictEqual((await call('PUT', '/api/themes/me/display', { as: 2, body: { icons: 'outline' } })).body.display.icons, undefined, 'only auto, line or solid');
+ // Motion (openvibe-shared 4.183.0): auto, full, reduced or off follows the account, and each one reads back.
+ for (const motion of ['auto', 'full', 'reduced', 'off']) {
+ r = await call('PUT', '/api/themes/me/display', { as: 2, body: { motion } });
+ assert.strictEqual(r.body.display.motion, motion, `motion ${motion} is kept`);
+ assert.strictEqual((await call('GET', '/api/themes/me/active', { as: 2 })).body.display.motion, motion, `motion ${motion} reads back`);
+ }
+ assert.strictEqual((await call('PUT', '/api/themes/me/display', { as: 2, body: { motion: 'calm' } })).body.display.motion, undefined, 'only auto, full, reduced or off');
// ── The site switcher's pinned and recent sites follow the account (migration 0029) ──
// ── The site switcher's pinned and recent sites follow the account (migration 0029) ──
r = await call('GET', '/api/themes/me/sites', { as: 2 });
r = await call('GET', '/api/themes/me/sites', { as: 2 });