Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 795056f

Browse files
committed
Enable Android's context menus in network list.
After thelounge#4326 Android users could no longer long-touch to bring up the context menu for channels in the network list. Now they can again.
1 parent a3a9a2c commit 795056f

File tree

6 files changed

+64
-14
lines changed

6 files changed

+64
-14
lines changed

‎client/components/ChannelWrapper.vue‎

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,11 @@ export default {
8282
this.$root.switchToChannel(this.channel);
8383
},
8484
openContextMenu(event) {
85-
// events.buttons will be 0 when the event is caused by a long
86-
// touch on Android.
87-
if (event.buttons !== 0) {
88-
eventbus.emit("contextmenu:channel", {
89-
event: event,
90-
channel: this.channel,
91-
network: this.network,
92-
});
93-
}
85+
eventbus.emit("contextmenu:channel", {
86+
event: event,
87+
channel: this.channel,
88+
network: this.network,
89+
});
9490
},
9591
},
9692
};

‎client/components/ContextMenu.vue‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<div
33
v-if="isOpen"
44
id="context-menu-container"
5+
:class="[passthrough && 'passthrough']"
56
@click="containerClick"
67
@contextmenu.prevent="containerClick"
78
@keydown.exact.up.prevent="navigateMenu(-1)"
@@ -49,6 +50,7 @@ export default {
4950
data() {
5051
return {
5152
isOpen: false,
53+
passthrough: false,
5254
previousActiveElement: null,
5355
items: [],
5456
activeItem: -1,
@@ -60,18 +62,35 @@ export default {
6062
},
6163
mounted() {
6264
eventbus.on("escapekey", this.close);
65+
eventbus.on("contextmenu:cancel", this.close);
6366
eventbus.on("contextmenu:user", this.openUserContextMenu);
6467
eventbus.on("contextmenu:channel", this.openChannelContextMenu);
6568
},
6669
destroyed() {
6770
eventbus.off("escapekey", this.close);
71+
eventbus.off("contextmenu:cancel", this.close);
6872
eventbus.off("contextmenu:user", this.openUserContextMenu);
6973
eventbus.off("contextmenu:channel", this.openChannelContextMenu);
7074
7175
this.close();
7276
},
7377
methods: {
78+
enablePointerEvents() {
79+
this.passthrough = false;
80+
document.body.removeEventListener("pointerup", this.enablePointerEvents, {
81+
passive: true,
82+
});
83+
},
7484
openChannelContextMenu(data) {
85+
if (data.event.type === "contextmenu") {
86+
// Pass through all pointer events to allow the network list's
87+
// dragging events to continue triggering.
88+
this.passthrough = true;
89+
document.body.addEventListener("pointerup", this.enablePointerEvents, {
90+
passive: true,
91+
});
92+
}
93+
7594
const items = generateChannelContextMenu(this.$root, data.channel, data.network);
7695
this.open(data.event, items);
7796
},

‎client/components/NetworkList.vue‎

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
role="region"
8383
aria-live="polite"
8484
@touchstart="onDraggableTouchStart"
85+
@touchmove="onDraggableTouchMove"
8586
@touchend="onDraggableTouchEnd"
8687
@touchcancel="onDraggableTouchEnd"
8788
>
@@ -205,6 +206,8 @@ import JoinChannel from "./JoinChannel.vue";
205206
import socket from "../js/socket";
206207
import collapseNetwork from "../js/helpers/collapseNetwork";
207208
import isIgnoredKeybind from "../js/helpers/isIgnoredKeybind";
209+
import distance from "../js/helpers/distance";
210+
import eventbus from "../js/eventbus";
208211
209212
export default {
210213
name: "NetworkList",
@@ -325,16 +328,25 @@ export default {
325328
);
326329
},
327330
onDraggableChoose(event) {
328-
if (this.isTouchEvent(event.originalEvent)) {
331+
const original = event.originalEvent;
332+
333+
if (this.isTouchEvent(original)) {
329334
// onDrag is only triggered when the user actually moves the
330335
// dragged object but onChoose is triggered as soon as the
331336
// item is eligible for dragging. This gives us an opportunity
332337
// to tell the user they've held the touch long enough.
333338
event.item.classList.add("ui-sortable-dragging-touch-cue");
339+
340+
if (original instanceof TouchEvent && original.touches.length > 0) {
341+
this.startDrag = [original.touches[0].clientX, original.touches[0].clientY];
342+
} else if (original instanceof PointerEvent) {
343+
this.startDrag = [original.clientX, original.clientY];
344+
}
334345
}
335346
},
336347
onDraggableUnchoose(event) {
337348
event.item.classList.remove("ui-sortable-dragging-touch-cue");
349+
this.startDrag = null;
338350
},
339351
onDraggableTouchStart() {
340352
if (event.touches.length === 1) {
@@ -343,6 +355,18 @@ export default {
343355
document.body.classList.add("force-no-select");
344356
}
345357
},
358+
onDraggableTouchMove(event) {
359+
if (this.startDrag && event.touches.length > 0) {
360+
const touch = event.touches[0];
361+
const currentPosition = [touch.clientX, touch.clientY];
362+
363+
if (distance(this.startDrag, currentPosition) > 10) {
364+
// Context menu is shown on Android after long touch.
365+
// Dismiss it now that we're sure the user is dragging.
366+
eventbus.emit("contextmenu:cancel");
367+
}
368+
}
369+
},
346370
onDraggableTouchEnd(event) {
347371
if (event.touches.length === 0) {
348372
document.body.classList.remove("force-no-select");

‎client/css/style.css‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2252,6 +2252,14 @@ part/quit messages where we don't load previews (adds a blank line otherwise) */
22522252
background: transparent;
22532253
}
22542254

2255+
#context-menu-container.passthrough {
2256+
pointer-events: none;
2257+
}
2258+
2259+
#context-menu-container.passthrough > * {
2260+
pointer-events: auto;
2261+
}
2262+
22552263
.mentions-popup,
22562264
#context-menu,
22572265
.textcomplete-menu {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
function distance([x1, y1], [x2, y2]) {
2+
return Math.hypot(x1 - x2, y1 - y2);
3+
}
4+
5+
export default distance;

‎client/js/helpers/listenForTwoFingerSwipes.js‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"use strict";
22

3+
import distance from "./distance";
4+
35
// onTwoFingerSwipe will be called with a cardinal direction ("n", "e", "s" or
46
// "w") as its only argument.
57
function listenForTwoFingerSwipes(onTwoFingerSwipe) {
@@ -89,10 +91,6 @@ function getSwipe(hist) {
8991
return getCardinalDirection(hist[0].center, hist[hist.length - 1].center);
9092
}
9193

92-
function distance([x1, y1], [x2, y2]) {
93-
return Math.hypot(x1 - x2, y1 - y2);
94-
}
95-
9694
function getCardinalDirection([x1, y1], [x2, y2]) {
9795
// If θ is the angle of the vector then this is tan(θ)
9896
const tangent = (y2 - y1) / (x2 - x1);

0 commit comments

Comments
 (0)