aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/App.vue65
-rw-r--r--src/components/TolTile.vue37
-rw-r--r--src/layout.ts2
3 files changed, 59 insertions, 45 deletions
diff --git a/src/App.vue b/src/App.vue
index 6ed2423..01f41a2 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -236,7 +236,7 @@ async function reInit(){
// Collapse tree to root
await onDetachedAncestorClick(layoutTree.value, true);
}
- await onNonleafClick(layoutTree.value, true);
+ await onNonleafClick(layoutTree.value, null, true);
await initTreeFromServer(false);
}
onMounted(() => initTreeFromServer());
@@ -339,7 +339,8 @@ onMounted(() => window.addEventListener('resize', onResize));
onUnmounted(() => window.removeEventListener('resize', onResize));
// For tile expand/collapse events
-async function onLeafClick(layoutNode: LayoutNode, subAction = false): Promise<boolean> {
+async function onLeafClick(
+ layoutNode: LayoutNode, onFail: null | (() => void) = null, subAction = false): Promise<boolean> {
if (!subAction && !onActionStart('expand')){
return false;
}
@@ -377,8 +378,8 @@ async function onLeafClick(layoutNode: LayoutNode, subAction = false): Promise<b
}
}
//
- if (!subAction && !success){
- layoutNode.failFlag = !layoutNode.failFlag; // Triggers failure animation
+ if (!subAction && !success && onFail != null){
+ onFail(); // Triggers failure animation
}
nextTick(endLoadInd);
return success;
@@ -387,8 +388,8 @@ async function onLeafClick(layoutNode: LayoutNode, subAction = false): Promise<b
let success: boolean;
if (overflownRoot.value){ // If clicking child of overflowing active-root
if (!uiOpts.value.autoHide){
- if (!subAction){
- layoutNode.failFlag = !layoutNode.failFlag; // Triggers failure animation
+ if (!subAction && onFail != null){
+ onFail(); // Triggers failure animation
}
success = false;
} else {
@@ -415,7 +416,8 @@ async function onLeafClick(layoutNode: LayoutNode, subAction = false): Promise<b
}
return success;
}
-async function onNonleafClick(layoutNode: LayoutNode, subAction = false): Promise<boolean> {
+async function onNonleafClick(
+ layoutNode: LayoutNode, onFail: null | (() => void) = null, subAction = false): Promise<boolean> {
if (!subAction && !onActionStart('collapse')){
return false;
}
@@ -432,12 +434,14 @@ async function onNonleafClick(layoutNode: LayoutNode, subAction = false): Promis
}
if (!subAction){
if (!success){
- layoutNode.failFlag = !layoutNode.failFlag; // Triggers failure animation
+ if (onFail != null){
+ onFail(); // Triggers failure animation
+ }
} else {
// Possibly clear out excess nodes when a threshold is reached
let numNodes = tolMap.value.size;
let extraNodes = numNodes - layoutMap.value.size;
- if (extraNodes > EXCESS_TOLNODE_THRESHOLD.value){
+ if (extraNodes > EXCESS_TOLNODE_THRESHOLD){
for (let n of tolMap.value.keys()){
if (!layoutMap.value.has(n)){
tolMap.value.delete(n)
@@ -454,7 +458,8 @@ async function onNonleafClick(layoutNode: LayoutNode, subAction = false): Promis
return success;
}
// For expand-to-view and ancestry-bar events
-async function onLeafClickHeld(layoutNode: LayoutNode, subAction = false): Promise<boolean> {
+async function onLeafClickHeld(
+ layoutNode: LayoutNode, onFail: null | (() => void) = null, subAction = false): Promise<boolean> {
// Special case for active root
if (layoutNode == activeRoot.value){
console.log('Ignored expand-to-view on active-root node');
@@ -488,8 +493,8 @@ async function onLeafClickHeld(layoutNode: LayoutNode, subAction = false): Promi
}
}
//
- if (!success && !subAction){
- layoutNode.failFlag = !layoutNode.failFlag; // Triggers failure animation
+ if (!success && !subAction && onFail != null){
+ onFail(); // Triggers failure animation
}
nextTick(endLoadInd);
return success;
@@ -514,7 +519,8 @@ async function onLeafClickHeld(layoutNode: LayoutNode, subAction = false): Promi
}
return success;
}
-async function onNonleafClickHeld(layoutNode: LayoutNode, subAction = false): Promise<boolean> {
+async function onNonleafClickHeld(
+ layoutNode: LayoutNode, onFail: null | (() => void) = null, subAction = false): Promise<boolean> {
// Special case for active root
if (layoutNode == activeRoot.value){
console.log('Ignored expand-to-view on active-root node');
@@ -555,10 +561,10 @@ async function onDetachedAncestorClick(layoutNode: LayoutNode, subAction = false
if (layoutNode.children.length > 0){
success = relayoutWithCollapse(false); // Second pass for regularity
} else {
- success = await onLeafClick(layoutNode, true);
+ success = await onLeafClick(layoutNode, null, true);
}
} else {
- success = await onNonleafClick(layoutNode, true); // For reducing tile-flashing on-screen
+ success = await onNonleafClick(layoutNode, null, true); // For reducing tile-flashing on-screen
}
LayoutNode.showDownward(layoutNode);
//
@@ -569,7 +575,7 @@ async function onDetachedAncestorClick(layoutNode: LayoutNode, subAction = false
return success;
}
-// For tile-info modal/events
+// For tile-info modal
const infoModalNodeName = ref(null as string | null); // Name of node to display info for, or null
const infoModalData = ref(null as InfoResponse | null);
async function onInfoClick(nodeName: string){
@@ -593,7 +599,7 @@ function onInfoClose(){
onActionEnd('tileInfo');
}
-// For search modal/events
+// For search modal
const searchOpen = ref(false);
function onSearchIconClick(){
if (!onActionStart('search')){
@@ -666,20 +672,20 @@ async function expandToNode(name: string){
LayoutNode.hideUpward(targetNode!.parent!, layoutMap.value);
activeRoot.value = targetNode!.parent!;
updateAreaDims();
- await onNonleafClick(activeRoot.value, true);
- await onLeafClick(activeRoot.value, true);
+ await onNonleafClick(activeRoot.value, null, true);
+ await onLeafClick(activeRoot.value, null, true);
} else {
- await onLeafClick(activeRoot.value, true);
+ await onLeafClick(activeRoot.value, null, true);
}
setTimeout(() => expandToNode(name), uiOpts.value.transitionDuration);
return;
}
if (overflownRoot.value){
- await onLeafClickHeld(layoutNode, true);
+ await onLeafClickHeld(layoutNode, null, true);
setTimeout(() => expandToNode(name), uiOpts.value.transitionDuration);
return;
}
- let success = await onLeafClick(layoutNode, true);
+ let success = await onLeafClick(layoutNode, null, true);
if (success){
setTimeout(() => expandToNode(name), uiOpts.value.transitionDuration);
return;
@@ -696,7 +702,7 @@ async function expandToNode(name: string){
ancestorChain.push(layoutNode);
}
layoutNode = ancestorChain[Math.floor((ancestorChain.length - 1) / 2)]
- await onNonleafClickHeld(layoutNode, true);
+ await onNonleafClickHeld(layoutNode, null, true);
setTimeout(() => expandToNode(name), uiOpts.value.transitionDuration);
}
function onSearchClose(){
@@ -820,13 +826,13 @@ async function autoAction(){
setLastFocused(node.parent!);
break;
case 'expand':
- success = await onLeafClick(node, true);
+ success = await onLeafClick(node, null, true);
break;
case 'collapse':
- success = await onNonleafClick(node, true);
+ success = await onNonleafClick(node, null, true);
break;
case 'expandToView':
- success = await onNonleafClickHeld(node, true);
+ success = await onNonleafClickHeld(node, null, true);
break;
case 'unhideAncestor':
success = await onDetachedAncestorClick(node.parent!, true);
@@ -846,7 +852,7 @@ function onAutoClose(){
onActionEnd('autoMode');
}
-// For settings modal/events
+// For settings modal
const settingsOpen = ref(false);
function onSettingsIconClick(){
if (!onActionStart('settings')){
@@ -884,7 +890,7 @@ function onResetSettings(reinit: boolean){
}
}
-// For help modal/events
+// For help modal
const helpOpen = ref(false);
function onHelpIconClick(){
if (!onActionStart('help')){
@@ -898,13 +904,12 @@ function onHelpClose(){
onActionEnd('help');
}
-// For tutorial pane/events
+// For tutorial pane
const tutPaneOpen = ref(!uiOpts.value.tutorialSkip);
const tutWelcome = ref(!uiOpts.value.tutorialSkip);
const tutTriggerAction = ref(null as Action | null); // Used to advance tutorial upon user-actions
const tutTriggerFlag = ref(false);
const actionsDone = ref(new Set() as Set<Action>); // Used to avoid disabling actions the user has already seen
-// For tutorial-pane events
function onStartTutorial(){
if (!tutPaneOpen.value){
tutPaneOpen.value = true;
diff --git a/src/components/TolTile.vue b/src/components/TolTile.vue
index d3b3539..810c5b7 100644
--- a/src/components/TolTile.vue
+++ b/src/components/TolTile.vue
@@ -165,14 +165,22 @@ function onClick(): void {
return;
}
wasClicked.value = true;
- emit(isLeaf.value ? 'leaf-click' : 'nonleaf-click', props.layoutNode);
+ if (isLeaf.value){
+ emit('leaf-click', props.layoutNode, onExpandFail);
+ } else {
+ emit('nonleaf-click', props.layoutNode, onCollapseFail);
+ }
}
function onClickHold(): void {
if (isLeaf.value && !isExpandableLeaf.value){
console.log('Ignored click-hold on non-expandable node');
return;
}
- emit(isLeaf.value ? 'leaf-click-held' : 'nonleaf-click-held', props.layoutNode);
+ if (isLeaf.value){
+ emit('leaf-click-held', props.layoutNode, onExpandFail);
+ } else {
+ emit('nonleaf-click-held', props.layoutNode, onCollapseFail);
+ }
}
function onDblClick(): void {
onClickHold();
@@ -181,19 +189,19 @@ function onInfoIconClick(): void {
emit('info-click', props.layoutNode.name);
}
// Child click-action propagation
-function onInnerLeafClick(node: LayoutNode): void {
+function onInnerLeafClick(node: LayoutNode, onFail: () => void): void {
wasClicked.value = true;
- emit('leaf-click', node);
+ emit('leaf-click', node, onFail);
}
-function onInnerNonleafClick(node: LayoutNode): void {
+function onInnerNonleafClick(node: LayoutNode, onFail: () => void): void {
wasClicked.value = true;
- emit('nonleaf-click', node);
+ emit('nonleaf-click', node, onFail);
}
-function onInnerLeafClickHeld(node: LayoutNode): void {
- emit('leaf-click-held', node);
+function onInnerLeafClickHeld(node: LayoutNode, onFail: () => void): void {
+ emit('leaf-click-held', node, onFail);
}
-function onInnerNonleafClickHeld(node: LayoutNode): void {
- emit('nonleaf-click-held', node);
+function onInnerNonleafClickHeld(node: LayoutNode, onFail: () => void): void {
+ emit('nonleaf-click-held', node, onFail);
}
function onInnerInfoIconClick(nodeName: string): void {
emit('info-click', nodeName);
@@ -265,9 +273,12 @@ function triggerAnimation(animation: string){
el.offsetWidth; // Triggers reflow
el.classList.add(animation);
}
-watch(() => props.layoutNode.failFlag, () =>
- triggerAnimation(isLeaf.value ? 'animate-expand-shrink' : 'animate-shrink-expand')
-);
+function onExpandFail(){
+ triggerAnimation('animate-expand-shrink');
+}
+function onCollapseFail(){
+ triggerAnimation('animate-shrink-expand');
+}
// For 'flashing' the tile when focused
const inFlash = ref(false); // Used to 'flash' the tile when focused
diff --git a/src/layout.ts b/src/layout.ts
index ec5b70c..140af77 100644
--- a/src/layout.ts
+++ b/src/layout.ts
@@ -27,7 +27,6 @@ export class LayoutNode {
hidden: boolean; // Used to hide nodes upon an expand-to-view
hiddenWithVisibleTip: boolean;
hasFocus: boolean; // Used by search and auto-mode to mark/flash a tile
- failFlag: boolean; // Used to trigger failure animations
// Constructor ('parent' are 'depth' are generally initialised later, 'tips' is computed)
constructor(name: string, children: LayoutNode[]){
this.name = name;
@@ -45,7 +44,6 @@ export class LayoutNode {
this.hidden = false;
this.hiddenWithVisibleTip = false;
this.hasFocus = false;
- this.failFlag = false;
}
// Returns a new tree with the same structure and names
// 'chg' is usable to apply a change to the resultant tree