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": "*",
|
"roboto-fontface": "*",
|
||||||
"v-emoji-picker": "^2.3.1",
|
"v-emoji-picker": "^2.3.1",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
"vue-mobile-event": "^1.2.6",
|
|
||||||
"vue-router": "^3.2.0",
|
"vue-router": "^3.2.0",
|
||||||
"vuetify": "^2.2.11",
|
"vuetify": "^2.2.11",
|
||||||
"vuex": "^3.5.1"
|
"vuex": "^3.5.1"
|
||||||
|
|
@ -13491,11 +13490,6 @@
|
||||||
"integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
|
"integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
|
||||||
"dev": true
|
"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": {
|
"node_modules/vue-property-decorator": {
|
||||||
"version": "9.1.2",
|
"version": "9.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vue-property-decorator/-/vue-property-decorator-9.1.2.tgz",
|
"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": {
|
"vue-property-decorator": {
|
||||||
"version": "9.1.2",
|
"version": "9.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vue-property-decorator/-/vue-property-decorator-9.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vue-property-decorator/-/vue-property-decorator-9.1.2.tgz",
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
"roboto-fontface": "*",
|
"roboto-fontface": "*",
|
||||||
"v-emoji-picker": "^2.3.1",
|
"v-emoji-picker": "^2.3.1",
|
||||||
"vue": "^2.6.11",
|
"vue": "^2.6.11",
|
||||||
"vue-mobile-event": "^1.2.6",
|
|
||||||
"vue-router": "^3.2.0",
|
"vue-router": "^3.2.0",
|
||||||
"vuetify": "^2.2.11",
|
"vuetify": "^2.2.11",
|
||||||
"vuex": "^3.5.1"
|
"vuex": "^3.5.1"
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,20 @@
|
||||||
class="chat-content flex-grow-1 flex-shrink-1"
|
class="chat-content flex-grow-1 flex-shrink-1"
|
||||||
ref="chatContainer"
|
ref="chatContainer"
|
||||||
style="overflow-x: hidden; overflow-y: auto"
|
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-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 v-if="!event.isRelation() && !event.isRedacted() && !event.isRedaction()">
|
||||||
<div style="position:relative;user-select:none">
|
<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
|
<component
|
||||||
:is="componentForEvent(event)"
|
:is="componentForEvent(event)"
|
||||||
:room="room"
|
:room="room"
|
||||||
:event="event"
|
:event="event"
|
||||||
:reactions="
|
:reactions="
|
||||||
timelineWindow._timelineSet.getRelationsForEvent(
|
timelineWindow._timelineSet.getRelationsForEvent(
|
||||||
event.getId(),
|
event.getId(),
|
||||||
|
|
@ -23,6 +28,7 @@
|
||||||
v-on:send-quick-reaction="sendQuickReaction"
|
v-on:send-quick-reaction="sendQuickReaction"
|
||||||
/>
|
/>
|
||||||
<message-operations
|
<message-operations
|
||||||
|
v-on:close="showContextMenu = false"
|
||||||
v-if="selectedEvent == event && showContextMenu"
|
v-if="selectedEvent == event && showContextMenu"
|
||||||
v-on:addreaction="addReaction"
|
v-on:addreaction="addReaction"
|
||||||
:event="event"
|
:event="event"
|
||||||
|
|
@ -102,7 +108,7 @@
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div v-if="showEmojiPicker">
|
||||||
<v-dialog v-model="showEmojiPicker" class="ma-0 pa-0" width="50%">
|
<v-dialog v-model="showEmojiPicker" class="ma-0 pa-0" width="50%">
|
||||||
<VEmojiPicker style="width: 100%" @select="emojiSelected" />
|
<VEmojiPicker style="width: 100%" @select="emojiSelected" />
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
|
|
@ -251,16 +257,48 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
touchTap(ignoredEvent) {
|
touchX(event) {
|
||||||
if (this.selectedEvent && this.showContextMenu) {
|
if(event.type.indexOf('mouse') !== -1){
|
||||||
// If anything is selected, unselect
|
return event.clientX;
|
||||||
this.selectedEvent = null;
|
}
|
||||||
|
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;
|
this.showContextMenu = false;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
touchLongTap(event) {
|
|
||||||
this.selectedEvent = 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;
|
this.showContextMenu = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -319,13 +357,14 @@ export default {
|
||||||
// Scrolled to top
|
// Scrolled to top
|
||||||
this.handleScrolledToTop();
|
this.handleScrolledToTop();
|
||||||
} else if (
|
} else if (
|
||||||
container.scrollHeight - container.scrollTop ==
|
container.scrollHeight - container.scrollTop.toFixed(0) ==
|
||||||
container.clientHeight
|
container.clientHeight
|
||||||
) {
|
) {
|
||||||
this.handleScrolledToBottom(false);
|
this.handleScrolledToBottom(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onEvent(event) {
|
onEvent(event) {
|
||||||
|
console.log("OnEvent", event);
|
||||||
if (event.getRoomId() !== this.roomId) {
|
if (event.getRoomId() !== this.roomId) {
|
||||||
return; // Not for this room
|
return; // Not for this room
|
||||||
}
|
}
|
||||||
|
|
@ -333,11 +372,15 @@ export default {
|
||||||
|
|
||||||
// If we are at bottom, scroll to see new events...
|
// If we are at bottom, scroll to see new events...
|
||||||
const container = this.$refs.chatContainer;
|
const container = this.$refs.chatContainer;
|
||||||
|
var scrollToSeeNew = (event.getSender() == this.$matrix.currentUserId); // When we sent, scroll
|
||||||
if (
|
if (
|
||||||
container.scrollHeight - container.scrollTop ==
|
container.scrollHeight - container.scrollTop.toFixed(0) ==
|
||||||
container.clientHeight
|
container.clientHeight
|
||||||
) {
|
) {
|
||||||
this.handleScrolledToBottom(true);
|
scrollToSeeNew = true;
|
||||||
|
}
|
||||||
|
if (event.forwardLooking) {
|
||||||
|
this.handleScrolledToBottom(scrollToSeeNew);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div :class="{'messageOperations':true,'incoming':incoming,'outgoing':!incoming}">
|
<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-icon>mood</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -26,9 +26,10 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
addReaction() {
|
addReaction() {
|
||||||
|
this.$emit("close");
|
||||||
this.$emit("addreaction", {event:this.event});
|
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 'roboto-fontface/css/roboto/roboto-fontface.css'
|
||||||
import 'material-design-icons-iconfont/dist/material-design-icons.css'
|
import 'material-design-icons-iconfont/dist/material-design-icons.css'
|
||||||
import VEmojiPicker from 'v-emoji-picker';
|
import VEmojiPicker from 'v-emoji-picker';
|
||||||
import VueMobileEvent from 'vue-mobile-event';
|
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
Vue.use(VueMobileEvent);
|
|
||||||
Vue.use(VEmojiPicker);
|
Vue.use(VEmojiPicker);
|
||||||
Vue.use(matrix, {store: store});
|
Vue.use(matrix, {store: store});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue