Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions public/js/modules/graph.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { switchToState, stateKeys, diagramKeys, switchDiagramView } from "./ui-orchestrator";
import { getActiveGraph } from "./options";
import { parsePinyin, trimTone, findPinyinRelationships } from "./pronunciation-parser";
import { hanziBox } from "./dom.js";
import cytoscape from "cytoscape";
import fcose from 'cytoscape-fcose';

Expand Down Expand Up @@ -455,16 +456,21 @@ function toggleColorCodeVisibility() {

let skipResize = false;
let pendingSkipResizeTimeout = null;
function isSearchFocusedOnTouchDevice() {
return document.activeElement === hanziBox && window.matchMedia('(pointer: coarse)').matches;
}

function handleResize() {
clearTimeout(pendingResizeTimeout);
pendingResizeTimeout = setTimeout(() => {
const shouldSkipLayout = skipResize || isSearchFocusedOnTouchDevice();
// if the window resizes with the graph collapsed, re-expand it
// note that switchDiagramView no-ops if we're going main-->main
if (!window.matchMedia('(max-width:664px)').matches) {
switchDiagramView(diagramKeys.main);
}
// TODO: probably want a sizeDirty bit we can check for when the graph isn't shown and a resize happens
if (!skipResize && cy && showingGraph) {
if (!shouldSkipLayout && cy && showingGraph) {
cy.layout(mode === modes.graph ? layout(cy.nodes().length) : bfsLayout(root)).run();
}
skipResize = false;
Expand Down Expand Up @@ -519,4 +525,4 @@ function initialize() {
matchMedia("(prefers-color-scheme: dark)").addEventListener("change", updateColorScheme);
}

export { initialize, isInGraph }
export { initialize, isInGraph }
11 changes: 0 additions & 11 deletions public/js/modules/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,20 +101,9 @@ Promise.all(
search(hanziBox.value);
switchToState(stateKeys.main);

// we're about to force a blur, which should hide the soft keyboard on android or ios
// but in some cases, the keyboard hiding triggers a resize, so you get an annoying graph re-render.
// This in very rare cases could cause cause a skipped re-layout on window size change
// but that should be rare.
document.dispatchEvent(new Event('skip-graph-resize'));
hanziBox.blur();
});

// similar to the blur logic above, the soft keyboard will show. Skip the next resize event.
// Same edge case with possible skipped 'real' resizes, but that should be very rare.
hanziBox.addEventListener('focus', function () {
document.dispatchEvent(new Event('skip-graph-resize'));
});

// TODO(refactor): this belongs in explore rather than main?
let oldState = readExploreState();
// precedence goes to the direct URL entered first, then to anything hanging around in history, then localstorage.
Expand Down
51 changes: 38 additions & 13 deletions public/js/modules/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,20 @@ function sendDataToWorker() {
});
}

let skipBlur = false;
let lastPointerDown = null;

function clearIfOutsideSearchControl(event) {
if (!searchControl.contains(event.target) && !hanziBox.contains(event.target)) {
function isInSearchUi(target) {
return target && (
searchControl.contains(target) ||
searchSuggestionsContainer.contains(target) ||
hanziBox.contains(target)
);
}

function handleDocumentPointerDown(event) {
lastPointerDown = { target: event.target, time: Date.now() };
if (!isInSearchUi(event.target)) {
clearSuggestions();
} else {
document.addEventListener('mousedown', clearIfOutsideSearchControl, { once: true });
}
}

Expand All @@ -262,17 +269,35 @@ async function initialize(term, mode) {
// it sends, so allow waiting.
const ensureLoaded = new Promise(ready => searchSuggestionsWorker.addEventListener("message", ready, { once: true }));
hanziBox.addEventListener('input', suggestSearches);
hanziBox.addEventListener('blur', function () {
if (skipBlur) {
skipBlur = false;
document.addEventListener('mousedown', clearIfOutsideSearchControl, { once: true });
hanziBox.addEventListener('blur', function (event) {
document.dispatchEvent(new Event('skip-graph-resize'));
setTimeout(function () {
const recentPointerTarget = lastPointerDown && Date.now() - lastPointerDown.time < 500
? lastPointerDown.target
: null;
if (
isInSearchUi(event.relatedTarget) ||
isInSearchUi(document.activeElement) ||
isInSearchUi(recentPointerTarget)
) {
return;
}
clearSuggestions();
}, 0);
});
hanziBox.addEventListener('focus', showControlsIfEligible);
document.addEventListener('pointerdown', handleDocumentPointerDown);
document.addEventListener('touchstart', function (event) {
if (window.PointerEvent) {
return;
}
clearSuggestions()
handleDocumentPointerDown(event);
});
hanziBox.addEventListener('focus', showControlsIfEligible);
searchControl.addEventListener('mousedown', function () {
skipBlur = true;
document.addEventListener('mousedown', function (event) {
if (window.PointerEvent) {
return;
}
handleDocumentPointerDown(event);
});
if (term) {
await ensureLoaded;
Expand Down
Loading