mirror of
https://github.com/responsively-org/responsively-app
synced 2024-11-10 14:54:12 +00:00
Replicating click across devices
This commit is contained in:
parent
49afb61f1f
commit
8adafd5806
5 changed files with 97 additions and 23 deletions
|
@ -2,5 +2,9 @@
|
|||
margin: 10px;
|
||||
}
|
||||
|
||||
.deviceTitle {
|
||||
font-weight: normal;
|
||||
font-size: 16px;
|
||||
}
|
||||
.deviceWrapper {
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import React, {Component, createRef} from 'react';
|
||||
import {ipcRenderer} from 'electron';
|
||||
import pubsub from 'pubsub.js';
|
||||
import BugIcon from '../icons/Bug';
|
||||
import cx from 'classnames';
|
||||
|
||||
|
@ -8,6 +9,7 @@ import styles from './style.module.css';
|
|||
|
||||
const MESSAGE_TYPES = {
|
||||
scroll: 'scroll',
|
||||
click: 'click',
|
||||
};
|
||||
|
||||
class WebView extends Component {
|
||||
|
@ -21,6 +23,8 @@ class WebView extends Component {
|
|||
'ipc-message',
|
||||
this.messageHandler
|
||||
);
|
||||
pubsub.subscribe('scroll', this.processScrollEvent);
|
||||
pubsub.subscribe('click', this.processClickEvent);
|
||||
|
||||
this.webviewRef.current.addEventListener('dom-ready', () => {
|
||||
this.initEventTriggers(this.webviewRef.current);
|
||||
|
@ -32,33 +36,28 @@ class WebView extends Component {
|
|||
});
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
this.processIfScrollChange(prevProps);
|
||||
}
|
||||
|
||||
processIfScrollChange = prevProps => {
|
||||
const {
|
||||
browser: {
|
||||
scrollPosition: {x: prevX, y: prevY},
|
||||
},
|
||||
} = prevProps;
|
||||
const {
|
||||
browser: {
|
||||
scrollPosition: {x, y},
|
||||
},
|
||||
} = this.props;
|
||||
if (x === prevX && y === prevY) {
|
||||
processScrollEvent = message => {
|
||||
if (message.sourceDeviceId === this.props.device.id) {
|
||||
return;
|
||||
}
|
||||
console.log('Scrolling to ', {x, y});
|
||||
this.webviewRef.current.send('scroll', {x, y});
|
||||
this.webviewRef.current.send('scrollMessage', message.position);
|
||||
};
|
||||
|
||||
processClickEvent = message => {
|
||||
if (message.sourceDeviceId === this.props.device.id) {
|
||||
return;
|
||||
}
|
||||
this.webviewRef.current.send('clickMessage', message);
|
||||
};
|
||||
|
||||
messageHandler = ({channel: type, args: [message]}) => {
|
||||
console.log('Message recieved', message);
|
||||
switch (type) {
|
||||
case MESSAGE_TYPES.scroll:
|
||||
this.props.onScrollChange(message);
|
||||
pubsub.publish('scroll', [message]);
|
||||
return;
|
||||
case MESSAGE_TYPES.click:
|
||||
pubsub.publish('click', [message]);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
@ -66,6 +65,7 @@ class WebView extends Component {
|
|||
initEventTriggers = webview => {
|
||||
console.log('Initializing triggers');
|
||||
webview.getWebContents().executeJavaScript(`
|
||||
responsivelyApp.deviceId = ${this.props.device.id};
|
||||
document.body.addEventListener('mouseleave', () => responsivelyApp.mouseOn = false)
|
||||
document.body.addEventListener('mouseenter', () => responsivelyApp.mouseOn = true)
|
||||
|
||||
|
@ -73,11 +73,32 @@ class WebView extends Component {
|
|||
if (!responsivelyApp.mouseOn) {
|
||||
return;
|
||||
}
|
||||
responsivelyApp.sendMessageToHost(
|
||||
window.responsivelyApp.sendMessageToHost(
|
||||
'${MESSAGE_TYPES.scroll}',
|
||||
{x: window.scrollX, y: window.scrollY}
|
||||
{
|
||||
sourceDeviceId: window.responsivelyApp.deviceId,
|
||||
position: {x: window.scrollX, y: window.scrollY},
|
||||
}
|
||||
);
|
||||
})
|
||||
});
|
||||
|
||||
document.querySelectorAll('*')
|
||||
.forEach(elem => {
|
||||
elem.addEventListener('click', e => {
|
||||
if (e.responsivelyAppProcessed) {
|
||||
return;
|
||||
}
|
||||
e.responsivelyAppProcessed = true;
|
||||
console.log('clicked', e);
|
||||
window.responsivelyApp.sendMessageToHost(
|
||||
'${MESSAGE_TYPES.click}',
|
||||
{
|
||||
sourceDeviceId: window.responsivelyApp.deviceId,
|
||||
cssPath: window.responsivelyApp.cssPath(e.target),
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
`);
|
||||
};
|
||||
|
||||
|
|
|
@ -2,12 +2,55 @@ const {ipcRenderer} = require('electron');
|
|||
console.log('Preloader');
|
||||
global.responsivelyApp = {
|
||||
sendMessageToHost: (type, message) => ipcRenderer.sendToHost(type, message),
|
||||
cssPath: el => {
|
||||
if (!(el instanceof Element)) return;
|
||||
var path = [];
|
||||
while (el.nodeType === Node.ELEMENT_NODE) {
|
||||
var selector = el.nodeName.toLowerCase();
|
||||
if (selector === 'html') {
|
||||
} else if (el.id) {
|
||||
selector += '#' + el.id;
|
||||
} else {
|
||||
var sib = el,
|
||||
nth = 1;
|
||||
while (
|
||||
sib.nodeType === Node.ELEMENT_NODE &&
|
||||
(sib = sib.previousSibling) &&
|
||||
nth++
|
||||
);
|
||||
selector += ':nth-child(' + nth + ')';
|
||||
}
|
||||
path.unshift(selector);
|
||||
el = el.parentNode;
|
||||
}
|
||||
return path.join(' > ');
|
||||
},
|
||||
eventFire: (el, etype) => {
|
||||
if (el.fireEvent) {
|
||||
el.fireEvent('on' + etype);
|
||||
} else {
|
||||
var evObj = document.createEvent('Events');
|
||||
evObj.initEvent(etype, true, false);
|
||||
evObj.responsivelyAppProcessed = true;
|
||||
el.dispatchEvent(evObj);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
ipcRenderer.on('scroll', (event, args) => {
|
||||
ipcRenderer.on('scrollMessage', (event, args) => {
|
||||
console.log('Recieved scroll message from host', event, args);
|
||||
window.scrollTo({
|
||||
top: args.y,
|
||||
left: args.x,
|
||||
});
|
||||
});
|
||||
|
||||
ipcRenderer.on('clickMessage', (event, args) => {
|
||||
console.log('Recieved click message from host', event, args);
|
||||
const elem = document.querySelector(args.cssPath);
|
||||
if (!elem) {
|
||||
console.log('Element to click is not found', args);
|
||||
return;
|
||||
}
|
||||
window.responsivelyApp.eventFire(elem, 'click');
|
||||
});
|
||||
|
|
|
@ -235,6 +235,7 @@
|
|||
"electron-log": "^3.0.7",
|
||||
"electron-updater": "^4.1.2",
|
||||
"history": "^4.7.2",
|
||||
"pubsub.js": "^1.5.2",
|
||||
"react": "^16.9.0",
|
||||
"react-dom": "^16.9.0",
|
||||
"react-hot-loader": "^4.3.12",
|
||||
|
|
|
@ -9833,6 +9833,11 @@ public-encrypt@^4.0.0:
|
|||
randombytes "^2.0.1"
|
||||
safe-buffer "^5.1.2"
|
||||
|
||||
pubsub.js@^1.5.2:
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/pubsub.js/-/pubsub.js-1.5.2.tgz#f7a6c5e12cabe5b48b24326e2e2d6cd6542f0a4b"
|
||||
integrity sha1-96bF4Syr5bSLJDJuLi1s1lQvCks=
|
||||
|
||||
pump@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909"
|
||||
|
|
Loading…
Reference in a new issue