mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
fix(quality): clear the SonarQube findings on the 4.0.0 branch (#2062)
The day-swipe move handler mixed classifying the gesture with following the finger, which put it at cognitive complexity 20. The classifying half is a pure question about a gesture, so it moves out as classifyLock: null keeps waiting for the next move, dead and h end the same way they did before. Also reads the reduce-motion flag through dataset, seeds the closest-year reduce with years[0] so it cannot throw if the empty guard above it ever loosens, and compares the in-flight preview entry against undefined instead of leaning on a promise being truthy.
This commit is contained in:
@@ -79,11 +79,34 @@ function band(dx: number, free: number, factor: number, max: number): number {
|
||||
return Math.sign(dx) * Math.min(a <= free ? a : free + (a - free) * factor, max)
|
||||
}
|
||||
|
||||
/**
|
||||
* Which way this finger is going, once it has moved far enough to tell.
|
||||
* `null` means it has not, so the caller waits for the next move.
|
||||
*/
|
||||
function classifyLock(
|
||||
g: Gesture,
|
||||
dx: number,
|
||||
dy: number,
|
||||
now: number,
|
||||
card: HTMLElement | null,
|
||||
s: { dragging: boolean; editing: boolean },
|
||||
): Lock {
|
||||
// The browser has already committed this gesture to scrolling, so obey it.
|
||||
// scrollLeft counts too: overflow-y-auto on its own leaves overflow-x
|
||||
// computing to auto, and a wide markdown table in a day note fills it.
|
||||
if (card && (card.scrollTop !== g.scrollTop0 || card.scrollLeft !== g.scrollLeft0)) return 'dead'
|
||||
if (Math.abs(dx) <= CLASSIFY_PX && Math.abs(dy) <= CLASSIFY_PX) return null
|
||||
// Edit mode only: past the bridge's press window this finger belongs to a
|
||||
// reorder drag. Go mode has no bridge, so a slow swipe still counts.
|
||||
if (s.dragging || (s.editing && now - g.t0 > PRESS_WINDOW_MS)) return 'dead'
|
||||
return Math.abs(dx) >= Math.abs(dy) * AXIS_BIAS ? 'h' : 'dead'
|
||||
}
|
||||
|
||||
/** The media query plus the app's own appearance toggle, which writes the same
|
||||
* attribute PluginFrame reads. */
|
||||
function reducedMotion(): boolean {
|
||||
if (typeof window === 'undefined') return false
|
||||
if (document.documentElement.hasAttribute('data-reduce-motion')) return true
|
||||
if (document.documentElement.dataset.reduceMotion !== undefined) return true
|
||||
return window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches ?? false
|
||||
}
|
||||
|
||||
@@ -297,21 +320,8 @@ export function useMPlanDaySwipe({
|
||||
while (g.samples.length > 2 && now - g.samples[0].t > SAMPLE_MS) g.samples.shift()
|
||||
|
||||
if (g.lock === null) {
|
||||
const card = cardRef.current
|
||||
// The browser has already committed this gesture to scrolling, so obey it.
|
||||
// scrollLeft counts too: overflow-y-auto on its own leaves overflow-x
|
||||
// computing to auto, and a wide markdown table in a day note fills it.
|
||||
if (card && (card.scrollTop !== g.scrollTop0 || card.scrollLeft !== g.scrollLeft0)) {
|
||||
g.lock = 'dead'
|
||||
return
|
||||
}
|
||||
if (Math.abs(dx) <= CLASSIFY_PX && Math.abs(dy) <= CLASSIFY_PX) return
|
||||
const s = latest.current
|
||||
// Edit mode only: past the bridge's press window this finger belongs to a
|
||||
// reorder drag. Go mode has no bridge, so a slow swipe still counts.
|
||||
if (s.dragging || (s.editing && now - g.t0 > PRESS_WINDOW_MS)) { g.lock = 'dead'; return }
|
||||
g.lock = Math.abs(dx) >= Math.abs(dy) * AXIS_BIAS ? 'h' : 'dead'
|
||||
if (g.lock === 'dead') return
|
||||
g.lock = classifyLock(g, dx, dy, now, cardRef.current, latest.current)
|
||||
if (g.lock !== 'h') return
|
||||
}
|
||||
|
||||
if (reducedMotion()) return // classify and commit, but never follow the finger
|
||||
|
||||
@@ -110,9 +110,11 @@ export function currentPeriodYear(s: VacayYearSettings = DEFAULT_YEAR_SETTINGS,
|
||||
export function defaultPeriodYear(years: number[], s: VacayYearSettings = DEFAULT_YEAR_SETTINGS, today = new Date()): number {
|
||||
const current = currentPeriodYear(s, today)
|
||||
if (years.length === 0 || years.includes(current)) return current
|
||||
// Seeded with years[0] rather than left to reduce's implicit first element:
|
||||
// same result, and it cannot throw if the guard above ever loosens.
|
||||
return years.reduce((best, year) => {
|
||||
const distance = Math.abs(year - current)
|
||||
const bestDistance = Math.abs(best - current)
|
||||
return distance < bestDistance || (distance === bestDistance && year > best) ? year : best
|
||||
})
|
||||
}, years[0])
|
||||
}
|
||||
|
||||
@@ -545,7 +545,7 @@ export class CollabService {
|
||||
// entry yet, since the first has not answered. Joining the running fetch keeps
|
||||
// that a single outbound request instead of twenty.
|
||||
const running = this.inFlight.get(url);
|
||||
if (running) return { ...(await running), url };
|
||||
if (running !== undefined) return { ...(await running), url };
|
||||
|
||||
// Charged per outbound fetch rather than per request, which is what the
|
||||
// budget is actually protecting. Without a user there is no one to charge —
|
||||
|
||||
Reference in New Issue
Block a user