Touch events
This commit is contained in:
parent
a19082e2ea
commit
a29bd9fffa
5 changed files with 61 additions and 31 deletions
11
package-lock.json
generated
11
package-lock.json
generated
|
|
@ -20,7 +20,6 @@
|
|||
"roboto-fontface": "*",
|
||||
"v-emoji-picker": "^2.3.1",
|
||||
"vue": "^2.6.11",
|
||||
"vue-mobile-event": "^1.2.6",
|
||||
"vue-router": "^3.2.0",
|
||||
"vuetify": "^2.2.11",
|
||||
"vuex": "^3.5.1"
|
||||
|
|
@ -13491,11 +13490,6 @@
|
|||
"integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/vue-mobile-event": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/vue-mobile-event/-/vue-mobile-event-1.2.6.tgz",
|
||||
"integrity": "sha512-PRy/KAokz2xvfKREcg0l+biWVMWlb/7c2J0qq71JRG58TuU2MQQTiLvOyqaaf1kMuKqoKUfqfqj2BYC7rDPHcA=="
|
||||
},
|
||||
"node_modules/vue-property-decorator": {
|
||||
"version": "9.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-property-decorator/-/vue-property-decorator-9.1.2.tgz",
|
||||
|
|
@ -25652,11 +25646,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"vue-mobile-event": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/vue-mobile-event/-/vue-mobile-event-1.2.6.tgz",
|
||||
"integrity": "sha512-PRy/KAokz2xvfKREcg0l+biWVMWlb/7c2J0qq71JRG58TuU2MQQTiLvOyqaaf1kMuKqoKUfqfqj2BYC7rDPHcA=="
|
||||
},
|
||||
"vue-property-decorator": {
|
||||
"version": "9.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-property-decorator/-/vue-property-decorator-9.1.2.tgz",
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
"roboto-fontface": "*",
|
||||
"v-emoji-picker": "^2.3.1",
|
||||
"vue": "^2.6.11",
|
||||
"vue-mobile-event": "^1.2.6",
|
||||
"vue-router": "^3.2.0",
|
||||
"vuetify": "^2.2.11",
|
||||
"vuex": "^3.5.1"
|
||||
|
|
|
|||
|
|
@ -4,15 +4,20 @@
|
|||
class="chat-content flex-grow-1 flex-shrink-1"
|
||||
ref="chatContainer"
|
||||
style="overflow-x: hidden; overflow-y: auto"
|
||||
v-on:scroll="onScroll"
|
||||
v-on:sscroll="onScroll"
|
||||
>
|
||||
<div v-for="event in events" :key="event.getId()">
|
||||
<div v-event:tap.self="(e) => { touchTap(event); } " v-event:longTap="(e) => { touchLongTap(event); } " v-if="!event.isRelation() && !event.isRedacted() && !event.isRedaction()">
|
||||
<div style="position:relative;user-select:none">
|
||||
<div v-if="!event.isRelation() && !event.isRedacted() && !event.isRedaction()">
|
||||
<div style="position:relative;user-select:none"
|
||||
v-on:touchstart="(e) => { touchStart(e, event) }"
|
||||
v-on:touchend="touchEnd"
|
||||
v-on:touchcancel="touchCancel"
|
||||
v-on:touchmove="touchMove"
|
||||
>
|
||||
<component
|
||||
:is="componentForEvent(event)"
|
||||
:room="room"
|
||||
:event="event"
|
||||
:event="event"
|
||||
:reactions="
|
||||
timelineWindow._timelineSet.getRelationsForEvent(
|
||||
event.getId(),
|
||||
|
|
@ -23,6 +28,7 @@
|
|||
v-on:send-quick-reaction="sendQuickReaction"
|
||||
/>
|
||||
<message-operations
|
||||
v-on:close="showContextMenu = false"
|
||||
v-if="selectedEvent == event && showContextMenu"
|
||||
v-on:addreaction="addReaction"
|
||||
:event="event"
|
||||
|
|
@ -102,7 +108,7 @@
|
|||
</v-dialog>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div v-if="showEmojiPicker">
|
||||
<v-dialog v-model="showEmojiPicker" class="ma-0 pa-0" width="50%">
|
||||
<VEmojiPicker style="width: 100%" @select="emojiSelected" />
|
||||
</v-dialog>
|
||||
|
|
@ -251,16 +257,48 @@ export default {
|
|||
},
|
||||
|
||||
methods: {
|
||||
touchTap(ignoredEvent) {
|
||||
if (this.selectedEvent && this.showContextMenu) {
|
||||
// If anything is selected, unselect
|
||||
this.selectedEvent = null;
|
||||
touchX(event) {
|
||||
if(event.type.indexOf('mouse') !== -1){
|
||||
return event.clientX;
|
||||
}
|
||||
return event.touches[0].clientX;
|
||||
},
|
||||
touchY(event) {
|
||||
if(event.type.indexOf('mouse') !== -1){
|
||||
return event.clientY;
|
||||
}
|
||||
return event.touches[0].clientY;
|
||||
},
|
||||
touchStart(e, event) {
|
||||
console.log("TouchStart");
|
||||
if (this.selectedEvent != event) {
|
||||
this.showContextMenu = false;
|
||||
}
|
||||
},
|
||||
|
||||
touchLongTap(event) {
|
||||
this.selectedEvent = event;
|
||||
this.touchStartX = this.touchX(e);
|
||||
this.touchStartY = this.touchY(e);
|
||||
this.touchTimer = setTimeout(this.touchTimerElapsed, 500);
|
||||
},
|
||||
touchEnd() {
|
||||
console.log("TouchEnd");
|
||||
this.touchTimer && clearTimeout(this.touchTimer);
|
||||
},
|
||||
touchCancel() {
|
||||
console.log("TouchCancel");
|
||||
this.touchTimer && clearTimeout(this.touchTimer);
|
||||
},
|
||||
touchMove(e) {
|
||||
this.touchCurrentX = this.touchX(e);
|
||||
this.touchCurrentY = this.touchY(e);
|
||||
var tapTolerance = 4;
|
||||
var touchMoved = Math.abs(this.touchStartX - this.touchCurrentX) > tapTolerance ||
|
||||
Math.abs(this.touchStartY - this.touchCurrentY) > tapTolerance;
|
||||
if(touchMoved){
|
||||
this.touchTimer && clearTimeout(this.touchTimer);
|
||||
}
|
||||
},
|
||||
touchTimerElapsed() {
|
||||
console.log('timer');
|
||||
this.showContextMenu = true;
|
||||
},
|
||||
|
||||
|
|
@ -319,13 +357,14 @@ export default {
|
|||
// Scrolled to top
|
||||
this.handleScrolledToTop();
|
||||
} else if (
|
||||
container.scrollHeight - container.scrollTop ==
|
||||
container.scrollHeight - container.scrollTop.toFixed(0) ==
|
||||
container.clientHeight
|
||||
) {
|
||||
this.handleScrolledToBottom(false);
|
||||
}
|
||||
},
|
||||
onEvent(event) {
|
||||
console.log("OnEvent", event);
|
||||
if (event.getRoomId() !== this.roomId) {
|
||||
return; // Not for this room
|
||||
}
|
||||
|
|
@ -333,11 +372,15 @@ export default {
|
|||
|
||||
// If we are at bottom, scroll to see new events...
|
||||
const container = this.$refs.chatContainer;
|
||||
var scrollToSeeNew = (event.getSender() == this.$matrix.currentUserId); // When we sent, scroll
|
||||
if (
|
||||
container.scrollHeight - container.scrollTop ==
|
||||
container.scrollHeight - container.scrollTop.toFixed(0) ==
|
||||
container.clientHeight
|
||||
) {
|
||||
this.handleScrolledToBottom(true);
|
||||
scrollToSeeNew = true;
|
||||
}
|
||||
if (event.forwardLooking) {
|
||||
this.handleScrolledToBottom(scrollToSeeNew);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div :class="{'messageOperations':true,'incoming':incoming,'outgoing':!incoming}">
|
||||
<v-btn icon v-event:tap.self="(e) => { addReaction() }" class="ma-0 pa-0">
|
||||
<v-btn icon @click.stop="addReaction" class="ma-0 pa-0">
|
||||
<v-icon>mood</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
|
|
@ -26,9 +26,10 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
methods: {
|
||||
addReaction() {
|
||||
this.$emit("close");
|
||||
this.$emit("addreaction", {event:this.event});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,9 @@ import matrix from './services/matrix.service'
|
|||
import 'roboto-fontface/css/roboto/roboto-fontface.css'
|
||||
import 'material-design-icons-iconfont/dist/material-design-icons.css'
|
||||
import VEmojiPicker from 'v-emoji-picker';
|
||||
import VueMobileEvent from 'vue-mobile-event';
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
Vue.use(VueMobileEvent);
|
||||
Vue.use(VEmojiPicker);
|
||||
Vue.use(matrix, {store: store});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue