Browse Source

Works on Safari 12 @ IOS

master
A.Olokhtonov 1 year ago
parent
commit
664f44c4ea
  1. 2
      client/default.css
  2. 2
      client/draw.js
  3. 22
      client/index.html
  4. 5
      client/index.js
  5. 14
      client/recv.js
  6. 10
      client/send.js
  7. 2
      client/tools.js
  8. 3
      client/touch.css
  9. 26
      client/websocket.js

2
client/default.css

@ -59,9 +59,11 @@ html, body {
justify-content: center; justify-content: center;
align-items: end; align-items: end;
z-index: 10; z-index: 10;
pointer-events: none;
} }
.tools { .tools {
pointer-events: all;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;

2
client/draw.js

@ -5,7 +5,7 @@ function draw_stroke(stroke) {
return; return;
} }
// console.debug(points) // if (config.debug_print) console.debug(points)
storage.ctx0.beginPath(); storage.ctx0.beginPath();
storage.ctx0.moveTo(points[0].x, points[0].y); storage.ctx0.moveTo(points[0].x, points[0].y);

22
client/index.html

@ -5,17 +5,17 @@
<title>Desk</title> <title>Desk</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="shortcut icon" href="icons/favicon.svg" id="favicon"> <link rel="shortcut icon" href="icons/favicon.svg" id="favicon">
<link rel="stylesheet" type="text/css" href="default.css?v=5"> <link rel="stylesheet" type="text/css" href="default.css?v=6">
<link rel="stylesheet" type="text/css" href="touch.css?v=2"> <link rel="stylesheet" type="text/css" href="touch.css?v=4">
<script type="text/javascript" src="index.js?v=5"></script> <script type="text/javascript" src="index.js?v=10"></script>
<script type="text/javascript" src="cursor.js"></script> <script type="text/javascript" src="cursor.js?v=5"></script>
<script type="text/javascript" src="touch.js?v=18"></script> <script type="text/javascript" src="touch.js?v=20"></script>
<script type="text/javascript" src="websocket.js"></script> <script type="text/javascript" src="websocket.js?v=6"></script>
<script type="text/javascript" src="send.js"></script> <script type="text/javascript" src="send.js?v=5"></script>
<script type="text/javascript" src="recv.js"></script> <script type="text/javascript" src="recv.js?v=5"></script>
<script type="text/javascript" src="math.js"></script> <script type="text/javascript" src="math.js?v=5"></script>
<script type="text/javascript" src="draw.js"></script> <script type="text/javascript" src="draw.js?v=5"></script>
<script type="text/javascript" src="tools.js?v=2"></script> <script type="text/javascript" src="tools.js?v=6"></script>
</head> </head>
<body> <body>
<div class="toolbar"> <div class="toolbar">

5
client/index.js

@ -30,6 +30,7 @@ const config = {
ws_reconnect_timeout: 2000, ws_reconnect_timeout: 2000,
second_finger_timeout: 500, second_finger_timeout: 500,
buffer_first_touchmoves: 5, buffer_first_touchmoves: 5,
debug_print: false,
}; };
const storage = { const storage = {
@ -83,8 +84,8 @@ const storage = {
'canvas': { 'canvas': {
'zoom': 1, 'zoom': 1,
'width': 4096, 'width': 1500,
'height': 4096, 'height': 4000,
'offset_x': 0, 'offset_x': 0,
'offset_y': 0, 'offset_y': 0,
}, },

14
client/recv.js

@ -120,7 +120,7 @@ function bitmap_bbox(event) {
} }
async function handle_event(event) { async function handle_event(event) {
console.debug(`event type ${event.type} from user ${event.user_id}`); if (config.debug_print) console.debug(`event type ${event.type} from user ${event.user_id}`);
// TODO(@speed): do not handle locally predicted events // TODO(@speed): do not handle locally predicted events
@ -246,7 +246,7 @@ async function handle_event(event) {
async function handle_message(d) { async function handle_message(d) {
const message_type = des_u8(d); const message_type = des_u8(d);
console.debug(message_type); if (config.debug_print) console.debug(message_type);
switch (message_type) { switch (message_type) {
case MESSAGE.JOIN: case MESSAGE.JOIN:
@ -263,14 +263,14 @@ async function handle_message(d) {
if (message_type === MESSAGE.JOIN) { if (message_type === MESSAGE.JOIN) {
ls.setItem('sessionId', des_u32(d)); ls.setItem('sessionId', des_u32(d));
console.debug('join in'); if (config.debug_print) console.debug('join in');
} else { } else {
console.debug('init in'); if (config.debug_print) console.debug('init in');
} }
const event_count = des_u32(d); const event_count = des_u32(d);
console.debug(`${event_count} events in init`); if (config.debug_print) console.debug(`${event_count} events in init`);
storage.ctx0.clearRect(0, 0, storage.ctx0.canvas.width, storage.ctx0.canvas.height); storage.ctx0.clearRect(0, 0, storage.ctx0.canvas.width, storage.ctx0.canvas.height);
elements.images.innerHTML = ''; elements.images.innerHTML = '';
@ -303,7 +303,7 @@ async function handle_message(d) {
case MESSAGE.ACK: { case MESSAGE.ACK: {
const lsn = des_u32(d); const lsn = des_u32(d);
console.debug(`ack ${lsn} in`); if (config.debug_print) console.debug(`ack ${lsn} in`);
if (lsn > storage.server_lsn) { if (lsn > storage.server_lsn) {
// ACKs may arrive out of order // ACKs may arrive out of order
@ -320,7 +320,7 @@ async function handle_message(d) {
const we_expect = sn - storage.sn; const we_expect = sn - storage.sn;
const first = count - we_expect; const first = count - we_expect;
console.debug(`syn ${sn} in`); if (config.debug_print) console.debug(`syn ${sn} in`);
for (let i = 0; i < count; ++i) { for (let i = 0; i < count; ++i) {
const event = des_event(d); const event = des_event(d);

10
client/send.js

@ -40,7 +40,7 @@ function ser_event(s, event) {
ser_u16(s, event.width); ser_u16(s, event.width);
ser_u32(s, event.color); ser_u32(s, event.color);
console.debug('original', event.points); if (config.debug_print) console.debug('original', event.points);
for (const point of event.points) { for (const point of event.points) {
ser_u16(s, point.x); ser_u16(s, point.x);
@ -81,7 +81,7 @@ async function send_ack(sn) {
ser_u8(s, MESSAGE.ACK); ser_u8(s, MESSAGE.ACK);
ser_u32(s, sn); ser_u32(s, sn);
console.debug(`ack ${sn} out`); if (config.debug_print) console.debug(`ack ${sn} out`);
try { try {
if (ws) await ws.send(s.buffer); if (ws) await ws.send(s.buffer);
@ -92,7 +92,7 @@ async function send_ack(sn) {
async function sync_queue() { async function sync_queue() {
if (ws === null) { if (ws === null) {
console.debug('socket has closed, stopping SYNs'); if (config.debug_print) console.debug('socket has closed, stopping SYNs');
return; return;
} }
@ -100,7 +100,7 @@ async function sync_queue() {
let count = storage.lsn - storage.server_lsn; let count = storage.lsn - storage.server_lsn;
if (count === 0) { if (count === 0) {
console.debug('server ACKed all events, clearing queue'); if (config.debug_print) console.debug('server ACKed all events, clearing queue');
storage.queue.length = 0; storage.queue.length = 0;
return; return;
} }
@ -122,7 +122,7 @@ async function sync_queue() {
ser_event(s, event); ser_event(s, event);
} }
console.debug(`syn ${storage.lsn} out`); if (config.debug_print) console.debug(`syn ${storage.lsn} out`);
try { try {
if (ws) await ws.send(s.buffer); if (ws) await ws.send(s.buffer);

2
client/tools.js

@ -4,7 +4,7 @@ function tools_switch(tool) {
} }
storage.tools.active = tool; storage.tools.active = tool;
storage.tools.active_element = document.querySelector(`.tool[data-tool="${tool}"`); storage.tools.active_element = document.querySelector(`.tool[data-tool="${tool}"]`);
storage.tools.active_element.classList.add('active'); storage.tools.active_element.classList.add('active');
} }

3
client/touch.css

@ -1,2 +1,5 @@
@media (pointer:none), (pointer:coarse) { @media (pointer:none), (pointer:coarse) {
.tool:hover {
background: #333;
}
} }

26
client/websocket.js

@ -20,21 +20,35 @@ function ws_connect(first_connect = false) {
function on_open() { function on_open() {
clearTimeout(storage.timers.ws_reconnect); clearTimeout(storage.timers.ws_reconnect);
console.debug('open') if (config.debug_print) console.debug('open')
} }
async function on_message(event) { async function on_message(event) {
const data = event.data; const data = event.data;
const message_data = await data.arrayBuffer(); let message_data = null;
const view = new DataView(message_data);
const d = deserializer_create(message_data, view);
await handle_message(d); if ('arrayBuffer' in data) {
message_data = await data.arrayBuffer();
const view = new DataView(message_data);
const d = deserializer_create(message_data, view);
await handle_message(d);
} else {
/* For all my Safari < 14 bros out there */
const reader = new FileReader();
reader.onload = async (e) => {
message_data = e.target.result;
const view = new DataView(message_data);
const d = deserializer_create(message_data, view);
await handle_message(d);
};
reader.readAsArrayBuffer(data);
}
} }
function on_close() { function on_close() {
ws = null; ws = null;
console.debug('close'); if (config.debug_print) console.debug('close');
storage.timers.ws_reconnect = setTimeout(ws_connect, config.ws_reconnect_timeout); storage.timers.ws_reconnect = setTimeout(ws_connect, config.ws_reconnect_timeout);
} }

Loading…
Cancel
Save