Finished WebRTC messages.

This commit is contained in:
Jared Goodwin 2020-04-15 12:59:18 -07:00
parent a1e2f8bff8
commit 04031eb08d
45 changed files with 798 additions and 183 deletions

View File

@ -260,6 +260,7 @@ namespace Remotely.Desktop.Win.ViewModels
serviceCollection.AddSingleton<Conductor>();
serviceCollection.AddTransient<IScreenCapturer, ScreenCapturerWin>();
serviceCollection.AddTransient<Viewer>();
serviceCollection.AddScoped<IWebRtcSessionFactory, WebRtcSessionFactory>();
ServiceContainer.Instance = serviceCollection.BuildServiceProvider();

View File

@ -18,26 +18,20 @@ namespace Remotely.ScreenCast.Core.Communication
public CasterSocket(
IKeyboardMouseInput keyboardMouseInput,
IScreenCaster screenCastService,
IAudioCapturer audioCapturer,
IClipboardService clipboardService)
IAudioCapturer audioCapturer)
{
KeyboardMouseInput = keyboardMouseInput;
ClipboardService = clipboardService;
AudioCapturer = audioCapturer;
ScreenCaster = screenCastService;
ClipboardService.ClipboardTextChanged += ClipboardService_ClipboardTextChanged;
}
public HubConnection Connection { get; private set; }
public bool IsConnected => Connection?.State == HubConnectionState.Connected;
public IScreenCaster ScreenCaster { get; }
private IAudioCapturer AudioCapturer { get; }
private IClipboardService ClipboardService { get; }
public HubConnection Connection { get; private set; }
private IKeyboardMouseInput KeyboardMouseInput { get; }
public async Task Connect(string host)
{
@ -78,9 +72,9 @@ namespace Remotely.ScreenCast.Core.Communication
await Connection.SendAsync("NotifyViewersRelaunchedScreenCasterReady", viewerIDs);
}
public async Task SendAudioSample(byte[] buffer, List<string> viewerIDs)
public async Task SendAudioSample(byte[] buffer, string viewerID)
{
await Connection.SendAsync("SendAudioSample", buffer, viewerIDs);
await Connection.SendAsync("SendAudioSample", buffer, viewerID);
}
public async Task SendClipboardText(string clipboardText, string viewerID)
@ -93,6 +87,11 @@ namespace Remotely.ScreenCast.Core.Communication
await Connection.SendAsync("SendConnectionFailedToViewers", viewerIDs);
}
public async Task SendCtrlAltDel()
{
await Connection.SendAsync("CtrlAltDel");
}
public async Task SendCursorChange(CursorInfo cursor, List<string> viewerIDs)
{
await Connection.SendAsync("SendCursorChange", cursor, viewerIDs);
@ -203,7 +202,7 @@ namespace Remotely.ScreenCast.Core.Communication
{
if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl)
{
await Connection.SendAsync("CtrlAltDel");
await SendCtrlAltDel();
}
});
@ -441,15 +440,5 @@ namespace Remotely.ScreenCast.Core.Communication
conductor.InvokeSessionIDChanged(sessionID);
});
}
private async void ClipboardService_ClipboardTextChanged(object sender, string clipboardText)
{
var conductor = ServiceContainer.Instance.GetRequiredService<Conductor>();
var viewerIDs = conductor.Viewers.Values.ToList();
foreach (var viewer in viewerIDs)
{
await viewer.SendClipboardText(clipboardText);
}
}
}
}

View File

@ -12,16 +12,21 @@ namespace Remotely.ScreenCast.Core.Communication
{
public class WebRtcSession : IDisposable
{
public WebRtcSession(IRtcMessageHandler rtcMessageHandler)
{
RtcMessageHandler = rtcMessageHandler;
}
public event EventHandler<(string candidate, int sdpMlineIndex, string sdpMid)> IceCandidateReady;
public event EventHandler<string> LocalSdpReady;
public ulong CurrentBuffer { get; private set; }
public bool IsDataChannelOpen => CaptureChannel?.State == DataChannel.ChannelState.Open;
public bool IsPeerConnected => PeerConnection?.IsConnected == true;
private DataChannel CaptureChannel { get; set; }
private PeerConnection PeerConnection { get; set; }
private IRtcMessageHandler RtcMessageHandler { get; }
public void AddIceCandidate(string sdpMid, int sdpMlineIndex, string candidate)
{
PeerConnection.AddIceCandidate(sdpMid, sdpMlineIndex, candidate);
@ -95,6 +100,11 @@ namespace Remotely.ScreenCast.Core.Communication
SendDto(new MachineNameDto(machineName));
}
public void SendAudioSample(byte[] audioSample)
{
SendDto(new AudioSampleDto(audioSample));
}
public void SendScreenData(string selectedScreen, string[] displayNames)
{
SendDto(new ScreenDataDto(selectedScreen, displayNames));
@ -113,9 +123,10 @@ namespace Remotely.ScreenCast.Core.Communication
PeerConnection.CreateAnswer();
}
}
private void CaptureChannel_MessageReceived(byte[] obj)
private async void CaptureChannel_MessageReceived(byte[] obj)
{
Logger.Debug($"DataChannel message received. Size: {obj.Length}");
await RtcMessageHandler.ParseMessage(obj);
}
private async void CaptureChannel_StateChanged()

View File

@ -1,7 +1,10 @@
namespace Remotely.ScreenCast.Core.Interfaces
using System;
namespace Remotely.ScreenCast.Core.Interfaces
{
public interface IAudioCapturer
{
event EventHandler<byte[]> AudioSampleReady;
void ToggleAudio(bool toggleOn);
}
}

View File

@ -11,19 +11,33 @@ namespace Remotely.ScreenCast.Core.Models
{
private int imageQuality;
public Viewer(IScreenCapturer screenCapturer,
CasterSocket casterSocket)
public Viewer(CasterSocket casterSocket,
IScreenCapturer screenCapturer,
IClipboardService clipboardService,
IWebRtcSessionFactory webRtcSessionFactory,
IAudioCapturer audioCapturer)
{
Capturer = screenCapturer;
CasterSocket = casterSocket;
WebRtcSessionFactory = webRtcSessionFactory;
EncoderParams = new EncoderParameters();
ImageQuality = 60;
ClipboardService = clipboardService;
ClipboardService.ClipboardTextChanged += ClipboardService_ClipboardTextChanged;
AudioCapturer = audioCapturer;
AudioCapturer.AudioSampleReady += AudioCapturer_AudioSampleReady;
}
public bool AutoAdjustQuality { get; set; } = true;
public IScreenCapturer Capturer { get; }
public bool DisconnectRequested { get; set; }
public EncoderParameters EncoderParams { get; private set; }
public bool HasControl { get; set; } = true;
public int ImageQuality
{
get
@ -47,26 +61,34 @@ namespace Remotely.ScreenCast.Core.Models
}
public bool IsConnected => CasterSocket.IsConnected;
public string Name { get; set; }
public WebRtcSession RtcSession { get; set; }
public string ViewerConnectionID { get; set; }
public int WebSocketBuffer { get; set; }
private IAudioCapturer AudioCapturer { get; }
private CasterSocket CasterSocket { get; }
public void Disconnect()
{
RtcSession.Dispose();
}
private IClipboardService ClipboardService { get; }
private IWebRtcSessionFactory WebRtcSessionFactory { get; }
public void Dispose()
{
RtcSession?.Dispose();
Capturer?.Dispose();
}
public async Task InitializeWebRtc()
{
try
{
RtcSession = new WebRtcSession();
RtcSession = WebRtcSessionFactory.GetNewSession(this);
RtcSession.LocalSdpReady += async (sender, sdp) =>
{
await CasterSocket.SendRtcOfferToBrowser(sdp, ViewerConnectionID);
@ -93,6 +115,12 @@ namespace Remotely.ScreenCast.Core.Models
return RtcSession?.IsPeerConnected == true && RtcSession?.IsDataChannelOpen == true;
}
public async Task SendAudioSample(byte[] audioSample)
{
await SendToViewer(() => RtcSession.SendAudioSample(audioSample),
() => CasterSocket.SendAudioSample(audioSample, ViewerConnectionID));
}
public async Task SendClipboardText(string clipboardText)
{
await SendToViewer(() => RtcSession.SendClipboardText(clipboardText),
@ -101,11 +129,11 @@ namespace Remotely.ScreenCast.Core.Models
public async Task SendMachineName(string machineName, string viewerID)
{
await SendToViewer(()=> RtcSession.SendMachineName(machineName),
await SendToViewer(() => RtcSession.SendMachineName(machineName),
() => CasterSocket.SendMachineName(machineName, viewerID));
}
public async Task SendScreenCapture(byte[] encodedImageBytes, string viewerID, int left, int top, int width, int height, int imageQuality)
public async Task SendScreenCapture(byte[] encodedImageBytes, string viewerID, int left, int top, int width, int height)
{
await SendToViewer(() =>
{
@ -113,7 +141,7 @@ namespace Remotely.ScreenCast.Core.Models
WebSocketBuffer = 0;
}, async () =>
{
await CasterSocket.SendScreenCapture(encodedImageBytes, viewerID, left, top, width, height, imageQuality);
await CasterSocket.SendScreenCapture(encodedImageBytes, viewerID, left, top, width, height, ImageQuality);
WebSocketBuffer += encodedImageBytes.Length;
});
}
@ -154,6 +182,14 @@ namespace Remotely.ScreenCast.Core.Models
}
}
private async void AudioCapturer_AudioSampleReady(object sender, byte[] sample)
{
await SendAudioSample(sample);
}
private async void ClipboardService_ClipboardTextChanged(object sender, string clipboardText)
{
await SendClipboardText(clipboardText);
}
private Task SendToViewer(Action webRtcSend, Func<Task> websocketSend)
{
if (IsUsingWebRtc())

View File

@ -34,6 +34,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="3.1.3" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="3.1.3" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.3" />
<PackageReference Include="Microsoft.Extensions.Logging.EventLog" Version="3.1.3" />
<PackageReference Include="Microsoft.MixedReality.WebRTC" Version="1.0.3" />

View File

@ -0,0 +1,216 @@
using MessagePack;
using Remotely.ScreenCast.Core.Communication;
using Remotely.ScreenCast.Core.Interfaces;
using Remotely.ScreenCast.Core.Models;
using Remotely.Shared.Enums;
using Remotely.Shared.Models.RtcDtos;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Text;
using System.Threading.Tasks;
namespace Remotely.ScreenCast.Core.Services
{
public interface IRtcMessageHandler
{
Task ParseMessage(byte[] message);
}
public class RtcMessageHandler : IRtcMessageHandler
{
private Viewer Viewer { get; }
public RtcMessageHandler(Viewer viewer,
CasterSocket casterSocket,
IKeyboardMouseInput keyboardMouseInput,
IAudioCapturer audioCapturer,
IClipboardService clipboardService)
{
Viewer = viewer;
CasterSocket = casterSocket;
KeyboardMouseInput = keyboardMouseInput;
AudioCapturer = audioCapturer;
ClipboardService = clipboardService;
}
private CasterSocket CasterSocket { get; }
private IKeyboardMouseInput KeyboardMouseInput { get; }
private IAudioCapturer AudioCapturer { get; }
private IClipboardService ClipboardService { get; }
public async Task ParseMessage(byte[] message)
{
try
{
if (!Viewer.HasControl)
{
return;
}
var baseDto = MessagePackSerializer.Deserialize<BinaryDtoBase>(message);
switch (baseDto.DtoType)
{
case BinaryDtoType.SelectScreen:
SelectScreen(message);
break;
case BinaryDtoType.MouseMove:
MouseMove(message);
break;
case BinaryDtoType.MouseDown:
MouseDown(message);
break;
case BinaryDtoType.MouseUp:
MouseUp(message);
break;
case BinaryDtoType.Tap:
Tap(message);
break;
case BinaryDtoType.MouseWheel:
MouseWheel(message);
break;
case BinaryDtoType.KeyDown:
KeyDown(message);
break;
case BinaryDtoType.KeyUp:
KeyUp(message);
break;
case BinaryDtoType.CtrlAltDel:
await CasterSocket.SendCtrlAltDel();
break;
case BinaryDtoType.AutoQualityAdjust:
SetAutoQualityAdjust(message);
break;
case BinaryDtoType.ToggleAudio:
ToggleAudio(message);
break;
case BinaryDtoType.ToggleBlockInput:
ToggleBlockInput(message);
break;
case BinaryDtoType.ClipboardTransfer:
ClipboardTransfer(message);
break;
case BinaryDtoType.KeyPress:
await KeyPress(message);
break;
case BinaryDtoType.QualityChange:
QualityChange(message);
break;
default:
break;
}
}
catch (Exception ex)
{
Logger.Write(ex);
}
}
private void QualityChange(byte[] message)
{
var dto = MessagePackSerializer.Deserialize<QualityChangeDto>(message);
Viewer.ImageQuality = dto.QualityLevel;
}
private async Task KeyPress(byte[] message)
{
var dto = MessagePackSerializer.Deserialize<KeyPressDto>(message);
KeyboardMouseInput.SendKeyDown(dto.Key, Viewer);
await Task.Delay(1);
KeyboardMouseInput.SendKeyUp(dto.Key, Viewer);
}
private void ClipboardTransfer(byte[] message)
{
var dto = MessagePackSerializer.Deserialize<ClipboardTransferDto>(message);
if (dto.TypeText)
{
KeyboardMouseInput.SendText(dto.Text, Viewer);
}
else
{
ClipboardService.SetText(dto.Text);
}
}
private void ToggleBlockInput(byte[] message)
{
var dto = MessagePackSerializer.Deserialize<ToggleBlockInputDto>(message);
KeyboardMouseInput.ToggleBlockInput(dto.ToggleOn);
}
private void ToggleAudio(byte[] message)
{
var dto = MessagePackSerializer.Deserialize<ToggleAudioDto>(message);
AudioCapturer.ToggleAudio(dto.ToggleOn);
}
private void SetAutoQualityAdjust(byte[] message)
{
var dto = MessagePackSerializer.Deserialize<AutoQualityAdjustDto>(message);
Viewer.AutoAdjustQuality = dto.IsOn;
}
private void KeyUp(byte[] message)
{
var dto = MessagePackSerializer.Deserialize<KeyUpDto>(message);
KeyboardMouseInput.SendKeyUp(dto.Key, Viewer);
}
private void KeyDown(byte[] message)
{
var dto = MessagePackSerializer.Deserialize<KeyDownDto>(message);
KeyboardMouseInput.SendKeyDown(dto.Key, Viewer);
}
private void MouseWheel(byte[] message)
{
var dto = MessagePackSerializer.Deserialize<MouseWheelDto>(message);
KeyboardMouseInput.SendMouseWheel(-(int)dto.DeltaY, Viewer);
}
private void Tap(byte[] message)
{
var dto = MessagePackSerializer.Deserialize<TapDto>(message);
KeyboardMouseInput.SendLeftMouseDown(dto.PercentX, dto.PercentY, Viewer);
KeyboardMouseInput.SendLeftMouseUp(dto.PercentX, dto.PercentY, Viewer);
}
private void MouseUp(byte[] message)
{
var dto = MessagePackSerializer.Deserialize<MouseUpDto>(message);
if (dto.Button == 0)
{
KeyboardMouseInput.SendLeftMouseUp(dto.PercentX, dto.PercentY, Viewer);
}
else if (dto.Button == 2)
{
KeyboardMouseInput.SendRightMouseUp(dto.PercentX, dto.PercentY, Viewer);
}
}
private void MouseDown(byte[] message)
{
var dto = MessagePackSerializer.Deserialize<MouseDownDto>(message);
if (dto.Button == 0)
{
KeyboardMouseInput.SendLeftMouseDown(dto.PercentX, dto.PercentY, Viewer);
}
else if (dto.Button == 2)
{
KeyboardMouseInput.SendRightMouseDown(dto.PercentX, dto.PercentY, Viewer);
}
}
private void MouseMove(byte[] message)
{
var dto = MessagePackSerializer.Deserialize<MouseMoveDto>(message);
KeyboardMouseInput.SendMouseMove(dto.PercentX, dto.PercentY, Viewer);
}
private void SelectScreen(byte[] message)
{
var dto = MessagePackSerializer.Deserialize<SelectScreenDto>(message);
Viewer.Capturer.SetSelectedScreen(dto.DisplayName);
}
}
}

View File

@ -100,7 +100,7 @@ namespace Remotely.ScreenCast.Core.Services
if (encodedImageBytes?.Length > 0)
{
await viewer.SendScreenCapture(encodedImageBytes, viewerID, diffArea.Left, diffArea.Top, diffArea.Width, diffArea.Height, viewer.ImageQuality);
await viewer.SendScreenCapture(encodedImageBytes, viewerID, diffArea.Left, diffArea.Top, diffArea.Width, diffArea.Height);
}
}
}
@ -117,10 +117,6 @@ namespace Remotely.ScreenCast.Core.Services
{
viewer.Dispose();
viewer.Capturer.Dispose();
viewer.Disconnect();
}
catch (Exception ex)
{

View File

@ -0,0 +1,42 @@
using Remotely.ScreenCast.Core.Communication;
using Remotely.ScreenCast.Core.Interfaces;
using Remotely.ScreenCast.Core.Models;
using System;
using System.Collections.Generic;
using System.Text;
namespace Remotely.ScreenCast.Core.Services
{
public interface IWebRtcSessionFactory
{
WebRtcSession GetNewSession(Viewer viewer);
}
public class WebRtcSessionFactory : IWebRtcSessionFactory
{
public WebRtcSessionFactory(CasterSocket casterSocket,
IKeyboardMouseInput keyboardMouseInput,
IAudioCapturer audioCapturer,
IClipboardService clipboardService)
{
CasterSocket = casterSocket;
KeyboardMouseInput = keyboardMouseInput;
AudioCapturer = audioCapturer;
ClipboardService = clipboardService;
}
public WebRtcSession GetNewSession(Viewer viewer)
{
var messageHandler = new RtcMessageHandler(viewer,
CasterSocket,
KeyboardMouseInput,
AudioCapturer,
ClipboardService);
return new WebRtcSession(messageHandler);
}
private CasterSocket CasterSocket { get; }
private IKeyboardMouseInput KeyboardMouseInput { get; }
private IAudioCapturer AudioCapturer { get; }
private IClipboardService ClipboardService { get; }
}
}

View File

@ -1,9 +1,14 @@
using Remotely.ScreenCast.Core.Interfaces;
using System;
namespace Remotely.ScreenCast.Linux.Services
{
public class AudioCapturerLinux : IAudioCapturer
{
#pragma warning disable
public event EventHandler<byte[]> AudioSampleReady;
#pragma warning restore
public void ToggleAudio(bool toggleOn)
{
// Not implemented.

View File

@ -78,6 +78,7 @@ namespace Remotely.ScreenCast.Win
serviceCollection.AddSingleton<ChatHostService>();
serviceCollection.AddTransient<IScreenCapturer, ScreenCapturerWin>();
serviceCollection.AddTransient<Viewer>();
serviceCollection.AddScoped<IWebRtcSessionFactory, WebRtcSessionFactory>();
ServiceContainer.Instance = serviceCollection.BuildServiceProvider();
}

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
@ -11,6 +12,7 @@ namespace Remotely.ScreenCast.Win.Services
{
public class AudioCapturerWin : IAudioCapturer
{
public event EventHandler<byte[]> AudioSampleReady;
private WasapiLoopbackCapture Capturer { get; set; }
private Stopwatch SendTimer { get; set; }
private WaveFormat TargetFormat { get; set; }
@ -27,7 +29,7 @@ namespace Remotely.ScreenCast.Win.Services
}
}
private async void SendTempBuffer()
private void SendTempBuffer()
{
if (TempBuffer.Count == 0)
{
@ -51,8 +53,7 @@ namespace Remotely.ScreenCast.Win.Services
{
WaveFileWriter.WriteWavFileToStream(ms3, resampler);
}
var conductor = ServiceContainer.Instance.GetRequiredService<Conductor>();
await conductor.CasterSocket.SendAudioSample(ms3.ToArray(), Program.Conductor.Viewers.Keys.ToList());
AudioSampleReady?.Invoke(this, ms3.ToArray());
}
}
}
@ -77,7 +78,7 @@ namespace Remotely.ScreenCast.Win.Services
SendTimer.Restart();
}
TempBuffer.AddRange(args.Buffer.Take(args.BytesRecorded));
if (TempBuffer.Count > 200000)
if (TempBuffer.Count > 50000)
{
SendTimer.Reset();
SendTempBuffer();

View File

@ -45,8 +45,8 @@ namespace Remotely.ScreenCast.Win.Services
private bool directXCapable = true;
public ScreenCapturerWin()
{
SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
Init();
SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
}
public event EventHandler<Rectangle> ScreenChanged;

View File

@ -152,9 +152,9 @@ namespace Remotely.Server.Services
return Task.CompletedTask;
}
public Task SendAudioSample(byte[] buffer, List<string> viewerIDs)
public Task SendAudioSample(byte[] buffer, string viewerID)
{
return RCBrowserHub.Clients.Clients(viewerIDs).SendAsync("AudioSample", buffer);
return RCBrowserHub.Clients.Client(viewerID).SendAsync("AudioSample", buffer);
}
public Task SendClipboardText(string clipboardText, string viewerID)

View File

@ -15,7 +15,7 @@ export class ClipboardWatcher {
if (this.LastClipboardText != newText) {
this.LastClipboardText = newText;
ClipboardTransferTextArea.value = newText;
MainRc.RCBrowserSockets.SendClipboardTransfer(newText, false);
MainRc.MessageSender.SendClipboardTransfer(newText, false);
}
});
}, 100);

View File

@ -1 +1 @@
{"version":3,"file":"ClipboardWatcher.js","sourceRoot":"","sources":["ClipboardWatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,MAAM,OAAO,gBAAgB;IAKzB,cAAc;QACV,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;YAC9C,IAAI,CAAC,iBAAiB,GAAG,WAAW,CAAC;YAErC,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;gBACnC,IAAI,IAAI,CAAC,eAAe,EAAE;oBACtB,OAAO;iBACV;gBACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE;oBACtB,OAAO;iBACV;gBAED,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;oBAC1C,IAAI,IAAI,CAAC,iBAAiB,IAAI,OAAO,EAAE;wBACnC,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC;wBACjC,yBAAyB,CAAC,KAAK,GAAG,OAAO,CAAC;wBAC1C,MAAM,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;qBACjE;gBACL,CAAC,CAAC,CAAA;YACN,CAAC,EAAE,GAAG,CAAC,CAAC;QACZ,CAAC,CAAC,CAAC;IACP,CAAC;IAED,gBAAgB,CAAC,IAAY;QACzB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACpC,yBAAyB,CAAC,KAAK,GAAG,IAAI,CAAC;QACvC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;IACjC,CAAC;CACJ"}
{"version":3,"file":"ClipboardWatcher.js","sourceRoot":"","sources":["ClipboardWatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,MAAM,OAAO,gBAAgB;IAKzB,cAAc;QACV,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;YAC9C,IAAI,CAAC,iBAAiB,GAAG,WAAW,CAAC;YAErC,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;gBACnC,IAAI,IAAI,CAAC,eAAe,EAAE;oBACtB,OAAO;iBACV;gBACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE;oBACtB,OAAO;iBACV;gBAED,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;oBAC1C,IAAI,IAAI,CAAC,iBAAiB,IAAI,OAAO,EAAE;wBACnC,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC;wBACjC,yBAAyB,CAAC,KAAK,GAAG,OAAO,CAAC;wBAC1C,MAAM,CAAC,aAAa,CAAC,qBAAqB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;qBAC9D;gBACL,CAAC,CAAC,CAAA;YACN,CAAC,EAAE,GAAG,CAAC,CAAC;QACZ,CAAC,CAAC,CAAC;IACP,CAAC;IAED,gBAAgB,CAAC,IAAY;QACzB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACpC,yBAAyB,CAAC,KAAK,GAAG,IAAI,CAAC;QACvC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;IACjC,CAAC;CACJ"}

View File

@ -22,7 +22,7 @@ export class ClipboardWatcher {
if (this.LastClipboardText != newText) {
this.LastClipboardText = newText;
ClipboardTransferTextArea.value = newText;
MainRc.RCBrowserSockets.SendClipboardTransfer(newText, false);
MainRc.MessageSender.SendClipboardTransfer(newText, false);
}
})
}, 100);

View File

@ -5,10 +5,12 @@ import * as UI from "./UI.js";
import { RemoteControlMode } from "../Enums/RemoteControlMode.js";
import { ClipboardWatcher } from "./ClipboardWatcher.js";
import { RtcMessageHandler } from "./RtcMessageHandler.js";
import { MessageSender } from "./MessageSender.js";
var queryString = Utilities.ParseSearchString();
export const MainRc = {
ClipboardWatcher: new ClipboardWatcher(),
Debug: false,
MessageSender: new MessageSender(),
RCBrowserSockets: new RCBrowserSockets(),
RtcMessageHandler: new RtcMessageHandler(),
RtcSession: new RtcSession(),
@ -17,7 +19,7 @@ export const MainRc = {
RequesterName: queryString["requesterName"] ? decodeURIComponent(queryString["requesterName"]) : "",
Mode: RemoteControlMode.None,
Init: () => {
UI.ApplyInputHandlers(MainRc.RCBrowserSockets);
UI.ApplyInputHandlers();
if (queryString["clientID"]) {
MainRc.Mode = RemoteControlMode.Unattended;
UI.ConnectBox.style.display = "none";

View File

@ -1 +1 @@
{"version":3,"file":"Main.js","sourceRoot":"","sources":["Main.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG3D,IAAI,WAAW,GAAG,SAAS,CAAC,iBAAiB,EAAE,CAAC;AAEhD,MAAM,CAAC,MAAM,MAAM,GAAG;IAClB,gBAAgB,EAAE,IAAI,gBAAgB,EAAE;IACxC,KAAK,EAAE,KAAK;IACZ,gBAAgB,EAAE,IAAI,gBAAgB,EAAE;IACxC,iBAAiB,EAAE,IAAI,iBAAiB,EAAE;IAC1C,UAAU,EAAE,IAAI,UAAU,EAAE;IAC5B,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;IACpF,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;IACvF,aAAa,EAAE,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;IACnG,IAAI,EAAE,iBAAiB,CAAC,IAAI;IAE5B,IAAI,EAAE,GAAG,EAAE;QACP,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAE/C,IAAI,WAAW,CAAC,UAAU,CAAC,EAAE;YACzB,MAAM,CAAC,IAAI,GAAG,iBAAiB,CAAC,UAAU,CAAC;YAC3C,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;YACrC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;SACrC;aACI,IAAI,WAAW,CAAC,WAAW,CAAC,EAAE;YAC/B,EAAE,CAAC,cAAc,CAAC,KAAK,GAAG,kBAAkB,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;YACvE,IAAI,WAAW,CAAC,eAAe,CAAC,EAAE;gBAC9B,EAAE,CAAC,kBAAkB,CAAC,KAAK,GAAG,kBAAkB,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC;gBAC/E,IAAI,CAAC,eAAe,EAAE,CAAC;aAC1B;SACJ;IACL,CAAC;IACD,eAAe,EAAE,GAAG,EAAE;QAClB,EAAE,CAAC,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC;QACjC,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,aAAa,GAAG,EAAE,CAAC,kBAAkB,CAAC,KAAK,CAAC;QACnD,MAAM,CAAC,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC;QACvC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAClC,EAAE,CAAC,aAAa,CAAC,SAAS,GAAG,+BAA+B,CAAC;IACjE,CAAC;CACJ,CAAA;AAED,MAAM,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC"}
{"version":3,"file":"Main.js","sourceRoot":"","sources":["Main.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,IAAI,WAAW,GAAG,SAAS,CAAC,iBAAiB,EAAE,CAAC;AAEhD,MAAM,CAAC,MAAM,MAAM,GAAG;IAClB,gBAAgB,EAAE,IAAI,gBAAgB,EAAE;IACxC,KAAK,EAAE,KAAK;IACZ,aAAa,EAAE,IAAI,aAAa,EAAE;IAClC,gBAAgB,EAAE,IAAI,gBAAgB,EAAE;IACxC,iBAAiB,EAAE,IAAI,iBAAiB,EAAE;IAC1C,UAAU,EAAE,IAAI,UAAU,EAAE;IAC5B,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;IACpF,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;IACvF,aAAa,EAAE,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;IACnG,IAAI,EAAE,iBAAiB,CAAC,IAAI;IAE5B,IAAI,EAAE,GAAG,EAAE;QACP,EAAE,CAAC,kBAAkB,EAAE,CAAC;QAExB,IAAI,WAAW,CAAC,UAAU,CAAC,EAAE;YACzB,MAAM,CAAC,IAAI,GAAG,iBAAiB,CAAC,UAAU,CAAC;YAC3C,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;YACrC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;SACrC;aACI,IAAI,WAAW,CAAC,WAAW,CAAC,EAAE;YAC/B,EAAE,CAAC,cAAc,CAAC,KAAK,GAAG,kBAAkB,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;YACvE,IAAI,WAAW,CAAC,eAAe,CAAC,EAAE;gBAC9B,EAAE,CAAC,kBAAkB,CAAC,KAAK,GAAG,kBAAkB,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC;gBAC/E,IAAI,CAAC,eAAe,EAAE,CAAC;aAC1B;SACJ;IACL,CAAC;IACD,eAAe,EAAE,GAAG,EAAE;QAClB,EAAE,CAAC,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC;QACjC,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,aAAa,GAAG,EAAE,CAAC,kBAAkB,CAAC,KAAK,CAAC;QACnD,MAAM,CAAC,IAAI,GAAG,iBAAiB,CAAC,MAAM,CAAC;QACvC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAClC,EAAE,CAAC,aAAa,CAAC,SAAS,GAAG,+BAA+B,CAAC;IACjE,CAAC;CACJ,CAAA;AAED,MAAM,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC"}

View File

@ -5,6 +5,7 @@ import * as UI from "./UI.js";
import { RemoteControlMode } from "../Enums/RemoteControlMode.js";
import { ClipboardWatcher } from "./ClipboardWatcher.js";
import { RtcMessageHandler } from "./RtcMessageHandler.js";
import { MessageSender } from "./MessageSender.js";
var queryString = Utilities.ParseSearchString();
@ -12,6 +13,7 @@ var queryString = Utilities.ParseSearchString();
export const MainRc = {
ClipboardWatcher: new ClipboardWatcher(),
Debug: false,
MessageSender: new MessageSender(),
RCBrowserSockets: new RCBrowserSockets(),
RtcMessageHandler: new RtcMessageHandler(),
RtcSession: new RtcSession(),
@ -21,7 +23,7 @@ export const MainRc = {
Mode: RemoteControlMode.None,
Init: () => {
UI.ApplyInputHandlers(MainRc.RCBrowserSockets);
UI.ApplyInputHandlers();
if (queryString["clientID"]) {
MainRc.Mode = RemoteControlMode.Unattended;

View File

@ -50,11 +50,11 @@ var lastPinchDistance;
var isMenuButtonDragging;
var startMenuDraggingY;
var startLongPressTimeout;
export function ApplyInputHandlers(sockets) {
export function ApplyInputHandlers() {
AudioButton.addEventListener("click", (ev) => {
AudioButton.classList.toggle("toggled");
var toggleOn = AudioButton.classList.contains("toggled");
sockets.SendToggleAudio(toggleOn);
MainRc.MessageSender.SendToggleAudio(toggleOn);
});
ChangeScreenButton.addEventListener("click", (ev) => {
closeAllHorizontalBars("screenSelectBar");
@ -68,7 +68,7 @@ export function ApplyInputHandlers(sockets) {
if (ClipboardTransferTextArea.value.length == 0) {
return;
}
sockets.SendClipboardTransfer(ClipboardTransferTextArea.value, ClipboardTransferTypeCheckbox.checked);
MainRc.MessageSender.SendClipboardTransfer(ClipboardTransferTextArea.value, ClipboardTransferTypeCheckbox.checked);
ClipboardTransferTextArea.blur();
PopupMessage("Clipboard sent!");
});
@ -81,7 +81,7 @@ export function ApplyInputHandlers(sockets) {
return;
}
closeAllHorizontalBars(null);
MainRc.RCBrowserSockets.SendCtrlAltDel();
MainRc.MessageSender.SendCtrlAltDel();
});
DisconnectButton.addEventListener("click", (ev) => {
ConnectButton.removeAttribute("disabled");
@ -118,10 +118,10 @@ export function ApplyInputHandlers(sockets) {
var button = ev.currentTarget;
button.classList.toggle("toggled");
if (button.classList.contains("toggled")) {
MainRc.RCBrowserSockets.SendToggleBlockInput(true);
MainRc.MessageSender.SendToggleBlockInput(true);
}
else {
MainRc.RCBrowserSockets.SendToggleBlockInput(false);
MainRc.MessageSender.SendToggleBlockInput(false);
}
});
InviteButton.addEventListener("click", (ev) => {
@ -168,10 +168,10 @@ export function ApplyInputHandlers(sockets) {
QualityBar.classList.toggle("open");
});
QualitySlider.addEventListener("change", (ev) => {
sockets.SendQualityChange(Number(QualitySlider.value));
MainRc.MessageSender.SendQualityChange(Number(QualitySlider.value));
});
AutoQualityAdjustCheckBox.addEventListener("change", ev => {
sockets.SendAutoQualityAdjust(AutoQualityAdjustCheckBox.checked);
MainRc.MessageSender.SendAutoQualityAdjust(AutoQualityAdjustCheckBox.checked);
});
ScreenViewer.addEventListener("pointermove", function (e) {
currentPointerDevice = e.pointerType;
@ -190,7 +190,7 @@ export function ApplyInputHandlers(sockets) {
lastPointerMove = Date.now();
var percentX = e.offsetX / ScreenViewer.clientWidth;
var percentY = e.offsetY / ScreenViewer.clientHeight;
sockets.SendMouseMove(percentX, percentY);
MainRc.MessageSender.SendMouseMove(percentX, percentY);
});
ScreenViewer.addEventListener("mousedown", function (e) {
if (currentPointerDevice == "touch") {
@ -202,7 +202,7 @@ export function ApplyInputHandlers(sockets) {
e.preventDefault();
var percentX = e.offsetX / ScreenViewer.clientWidth;
var percentY = e.offsetY / ScreenViewer.clientHeight;
sockets.SendMouseDown(e.button, percentX, percentY);
MainRc.MessageSender.SendMouseDown(e.button, percentX, percentY);
});
ScreenViewer.addEventListener("mouseup", function (e) {
if (currentPointerDevice == "touch") {
@ -214,7 +214,7 @@ export function ApplyInputHandlers(sockets) {
e.preventDefault();
var percentX = e.offsetX / ScreenViewer.clientWidth;
var percentY = e.offsetY / ScreenViewer.clientHeight;
sockets.SendMouseUp(e.button, percentX, percentY);
MainRc.MessageSender.SendMouseUp(e.button, percentX, percentY);
});
ScreenViewer.addEventListener("click", function (e) {
if (cancelNextViewerClick) {
@ -228,7 +228,7 @@ export function ApplyInputHandlers(sockets) {
else if (currentPointerDevice == "touch" && currentTouchCount == 0) {
var percentX = e.offsetX / ScreenViewer.clientWidth;
var percentY = e.offsetY / ScreenViewer.clientHeight;
sockets.SendTap(percentX, percentY);
MainRc.MessageSender.SendTap(percentX, percentY);
}
});
ScreenViewer.addEventListener("touchstart", function (e) {
@ -237,8 +237,8 @@ export function ApplyInputHandlers(sockets) {
startLongPressTimeout = window.setTimeout(() => {
var percentX = e.touches[0].pageX / ScreenViewer.clientWidth;
var percentY = e.touches[0].pageY / ScreenViewer.clientHeight;
sockets.SendMouseDown(2, percentX, percentY);
sockets.SendMouseUp(2, percentX, percentY);
MainRc.MessageSender.SendMouseDown(2, percentX, percentY);
MainRc.MessageSender.SendMouseUp(2, percentX, percentY);
}, 1000);
}
if (currentTouchCount > 1) {
@ -287,7 +287,7 @@ export function ApplyInputHandlers(sockets) {
else if (isDragging) {
e.preventDefault();
e.stopPropagation();
sockets.SendMouseMove(percentX, percentY);
MainRc.MessageSender.SendMouseMove(percentX, percentY);
}
});
ScreenViewer.addEventListener("touchend", function (e) {
@ -297,8 +297,8 @@ export function ApplyInputHandlers(sockets) {
isDragging = true;
var percentX = (e.touches[0].pageX - ScreenViewer.getBoundingClientRect().left) / ScreenViewer.clientWidth;
var percentY = (e.touches[0].pageY - ScreenViewer.getBoundingClientRect().top) / ScreenViewer.clientHeight;
sockets.SendMouseMove(percentX, percentY);
sockets.SendMouseDown(0, percentX, percentY);
MainRc.MessageSender.SendMouseMove(percentX, percentY);
MainRc.MessageSender.SendMouseDown(0, percentX, percentY);
return;
}
if (currentTouchCount == 0) {
@ -310,7 +310,7 @@ export function ApplyInputHandlers(sockets) {
if (isDragging) {
var percentX = (e.changedTouches[0].pageX - ScreenViewer.getBoundingClientRect().left) / ScreenViewer.clientWidth;
var percentY = (e.changedTouches[0].pageY - ScreenViewer.getBoundingClientRect().top) / ScreenViewer.clientHeight;
sockets.SendMouseUp(0, percentX, percentY);
MainRc.MessageSender.SendMouseUp(0, percentX, percentY);
}
isDragging = false;
});
@ -319,17 +319,17 @@ export function ApplyInputHandlers(sockets) {
});
ScreenViewer.addEventListener("wheel", function (e) {
e.preventDefault();
sockets.SendMouseWheel(e.deltaX, e.deltaY);
MainRc.MessageSender.SendMouseWheel(e.deltaX, e.deltaY);
});
TouchKeyboardTextArea.addEventListener("input", (ev) => {
if (TouchKeyboardTextArea.value.length == 1) {
sockets.SendKeyPress("Backspace");
MainRc.MessageSender.SendKeyPress("Backspace");
}
else if (TouchKeyboardTextArea.value.endsWith("\n")) {
sockets.SendKeyPress("Enter");
MainRc.MessageSender.SendKeyPress("Enter");
}
else if (TouchKeyboardTextArea.value.endsWith(" ")) {
sockets.SendKeyPress(" ");
MainRc.MessageSender.SendKeyPress(" ");
}
else {
var input = TouchKeyboardTextArea.value.trim().substr(1);
@ -337,11 +337,11 @@ export function ApplyInputHandlers(sockets) {
var character = input.charAt(i);
var sendShift = character.match(/[A-Z~!@#$%^&*()_+{}|<>?]/);
if (sendShift) {
sockets.SendKeyDown("Shift");
MainRc.MessageSender.SendKeyDown("Shift");
}
sockets.SendKeyPress(character);
MainRc.MessageSender.SendKeyPress(character);
if (sendShift) {
sockets.SendKeyUp("Shift");
MainRc.MessageSender.SendKeyUp("Shift");
}
}
}
@ -355,14 +355,14 @@ export function ApplyInputHandlers(sockets) {
return;
}
e.preventDefault();
sockets.SendKeyDown(e.key);
MainRc.MessageSender.SendKeyDown(e.key);
});
window.addEventListener("keyup", function (e) {
if (document.querySelector("input:focus") || document.querySelector("textarea:focus")) {
return;
}
e.preventDefault();
sockets.SendKeyUp(e.key);
MainRc.MessageSender.SendKeyUp(e.key);
});
window.ondragover = function (e) {
e.preventDefault();
@ -451,34 +451,34 @@ export function UpdateDisplays(selectedDisplay, displayNames) {
}
}
function uploadFiles(fileList) {
ShowMessage("File upload started...");
FileTransferProgress.value = 0;
FileTransferProgress.parentElement.removeAttribute("hidden");
var strPath = "/API/FileSharing/";
var fd = new FormData();
for (var i = 0; i < fileList.length; i++) {
fd.append('fileUpload' + i, fileList[i]);
}
var xhr = new XMLHttpRequest();
xhr.open('POST', strPath, true);
xhr.addEventListener("load", function () {
FileTransferProgress.parentElement.setAttribute("hidden", "hidden");
if (xhr.status === 200) {
ShowMessage("File upload completed.");
MainRc.RCBrowserSockets.SendSharedFileIDs(xhr.responseText);
}
else {
ShowMessage("File upload failed.");
}
});
xhr.addEventListener("error", () => {
FileTransferProgress.parentElement.setAttribute("hidden", "hidden");
ShowMessage("File upload failed.");
});
xhr.addEventListener("progress", function (e) {
FileTransferProgress.value = isFinite(e.loaded / e.total) ? e.loaded / e.total : 0;
});
xhr.send(fd);
//ShowMessage("File upload started...");
//FileTransferProgress.value = 0;
//FileTransferProgress.parentElement.removeAttribute("hidden");
//var strPath = "/API/FileSharing/";
//var fd = new FormData();
//for (var i = 0; i < fileList.length; i++) {
// fd.append('fileUpload' + i, fileList[i]);
//}
//var xhr = new XMLHttpRequest();
//xhr.open('POST', strPath, true);
//xhr.addEventListener("load", function () {
// FileTransferProgress.parentElement.setAttribute("hidden", "hidden");
// if (xhr.status === 200) {
// ShowMessage("File upload completed.");
// MainRc.RCBrowserSockets.SendSharedFileIDs(xhr.responseText);
// }
// else {
// ShowMessage("File upload failed.");
// }
//});
//xhr.addEventListener("error", () => {
// FileTransferProgress.parentElement.setAttribute("hidden", "hidden");
// ShowMessage("File upload failed.");
//});
//xhr.addEventListener("progress", function (e) {
// FileTransferProgress.value = isFinite(e.loaded / e.total) ? e.loaded / e.total : 0;
//});
//xhr.send(fd);
}
function closeAllHorizontalBars(exceptBarId) {
HorizontalBars.forEach(x => {

File diff suppressed because one or more lines are too long

View File

@ -56,11 +56,11 @@ var isMenuButtonDragging: boolean;
var startMenuDraggingY: number;
var startLongPressTimeout: number;
export function ApplyInputHandlers(sockets: RCBrowserSockets) {
export function ApplyInputHandlers() {
AudioButton.addEventListener("click", (ev) => {
AudioButton.classList.toggle("toggled");
var toggleOn = AudioButton.classList.contains("toggled");
sockets.SendToggleAudio(toggleOn);
MainRc.MessageSender.SendToggleAudio(toggleOn);
});
ChangeScreenButton.addEventListener("click", (ev) => {
closeAllHorizontalBars("screenSelectBar");
@ -74,7 +74,7 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
if (ClipboardTransferTextArea.value.length == 0) {
return;
}
sockets.SendClipboardTransfer(ClipboardTransferTextArea.value, ClipboardTransferTypeCheckbox.checked);
MainRc.MessageSender.SendClipboardTransfer(ClipboardTransferTextArea.value, ClipboardTransferTypeCheckbox.checked);
ClipboardTransferTextArea.blur();
PopupMessage("Clipboard sent!");
});
@ -87,7 +87,7 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
return;
}
closeAllHorizontalBars(null);
MainRc.RCBrowserSockets.SendCtrlAltDel();
MainRc.MessageSender.SendCtrlAltDel();
});
DisconnectButton.addEventListener("click", (ev) => {
ConnectButton.removeAttribute("disabled");
@ -124,10 +124,10 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
var button = ev.currentTarget as HTMLButtonElement;
button.classList.toggle("toggled");
if (button.classList.contains("toggled")) {
MainRc.RCBrowserSockets.SendToggleBlockInput(true);
MainRc.MessageSender.SendToggleBlockInput(true);
}
else {
MainRc.RCBrowserSockets.SendToggleBlockInput(false);
MainRc.MessageSender.SendToggleBlockInput(false);
}
});
InviteButton.addEventListener("click", (ev) => {
@ -174,10 +174,10 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
QualityBar.classList.toggle("open");
})
QualitySlider.addEventListener("change", (ev) => {
sockets.SendQualityChange(Number(QualitySlider.value));
MainRc.MessageSender.SendQualityChange(Number(QualitySlider.value));
});
AutoQualityAdjustCheckBox.addEventListener("change", ev => {
sockets.SendAutoQualityAdjust(AutoQualityAdjustCheckBox.checked);
MainRc.MessageSender.SendAutoQualityAdjust(AutoQualityAdjustCheckBox.checked);
});
ScreenViewer.addEventListener("pointermove", function (e) {
currentPointerDevice = e.pointerType;
@ -196,7 +196,7 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
lastPointerMove = Date.now();
var percentX = e.offsetX / ScreenViewer.clientWidth;
var percentY = e.offsetY / ScreenViewer.clientHeight;
sockets.SendMouseMove(percentX, percentY);
MainRc.MessageSender.SendMouseMove(percentX, percentY);
});
ScreenViewer.addEventListener("mousedown", function (e) {
if (currentPointerDevice == "touch") {
@ -208,7 +208,7 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
e.preventDefault();
var percentX = e.offsetX / ScreenViewer.clientWidth;
var percentY = e.offsetY / ScreenViewer.clientHeight;
sockets.SendMouseDown(e.button, percentX, percentY);
MainRc.MessageSender.SendMouseDown(e.button, percentX, percentY);
});
ScreenViewer.addEventListener("mouseup", function (e) {
if (currentPointerDevice == "touch") {
@ -220,7 +220,7 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
e.preventDefault();
var percentX = e.offsetX / ScreenViewer.clientWidth;
var percentY = e.offsetY / ScreenViewer.clientHeight;
sockets.SendMouseUp(e.button, percentX, percentY);
MainRc.MessageSender.SendMouseUp(e.button, percentX, percentY);
});
ScreenViewer.addEventListener("click", function (e) {
@ -235,7 +235,7 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
else if (currentPointerDevice == "touch" && currentTouchCount == 0) {
var percentX = e.offsetX / ScreenViewer.clientWidth;
var percentY = e.offsetY / ScreenViewer.clientHeight;
sockets.SendTap(percentX, percentY);
MainRc.MessageSender.SendTap(percentX, percentY);
}
});
@ -246,8 +246,8 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
startLongPressTimeout = window.setTimeout(() => {
var percentX = e.touches[0].pageX / ScreenViewer.clientWidth;
var percentY = e.touches[0].pageY / ScreenViewer.clientHeight;
sockets.SendMouseDown(2, percentX, percentY);
sockets.SendMouseUp(2, percentX, percentY);
MainRc.MessageSender.SendMouseDown(2, percentX, percentY);
MainRc.MessageSender.SendMouseUp(2, percentX, percentY);
}, 1000);
}
@ -311,7 +311,7 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
else if (isDragging) {
e.preventDefault();
e.stopPropagation();
sockets.SendMouseMove(percentX, percentY);
MainRc.MessageSender.SendMouseMove(percentX, percentY);
}
});
ScreenViewer.addEventListener("touchend", function (e) {
@ -323,8 +323,8 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
isDragging = true;
var percentX = (e.touches[0].pageX - ScreenViewer.getBoundingClientRect().left) / ScreenViewer.clientWidth;
var percentY = (e.touches[0].pageY - ScreenViewer.getBoundingClientRect().top) / ScreenViewer.clientHeight;
sockets.SendMouseMove(percentX, percentY);
sockets.SendMouseDown(0, percentX, percentY);
MainRc.MessageSender.SendMouseMove(percentX, percentY);
MainRc.MessageSender.SendMouseDown(0, percentX, percentY);
return;
}
@ -338,7 +338,7 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
if (isDragging) {
var percentX = (e.changedTouches[0].pageX - ScreenViewer.getBoundingClientRect().left) / ScreenViewer.clientWidth;
var percentY = (e.changedTouches[0].pageY - ScreenViewer.getBoundingClientRect().top) / ScreenViewer.clientHeight;
sockets.SendMouseUp(0, percentX, percentY);
MainRc.MessageSender.SendMouseUp(0, percentX, percentY);
}
isDragging = false;
@ -348,17 +348,17 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
});
ScreenViewer.addEventListener("wheel", function (e) {
e.preventDefault();
sockets.SendMouseWheel(e.deltaX, e.deltaY);
MainRc.MessageSender.SendMouseWheel(e.deltaX, e.deltaY);
});
TouchKeyboardTextArea.addEventListener("input", (ev) => {
if (TouchKeyboardTextArea.value.length == 1) {
sockets.SendKeyPress("Backspace");
MainRc.MessageSender.SendKeyPress("Backspace");
}
else if (TouchKeyboardTextArea.value.endsWith("\n")) {
sockets.SendKeyPress("Enter");
MainRc.MessageSender.SendKeyPress("Enter");
}
else if (TouchKeyboardTextArea.value.endsWith(" ")) {
sockets.SendKeyPress(" ");
MainRc.MessageSender.SendKeyPress(" ");
}
else {
var input = TouchKeyboardTextArea.value.trim().substr(1);
@ -366,13 +366,13 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
var character = input.charAt(i);
var sendShift = character.match(/[A-Z~!@#$%^&*()_+{}|<>?]/);
if (sendShift) {
sockets.SendKeyDown("Shift");
MainRc.MessageSender.SendKeyDown("Shift");
}
sockets.SendKeyPress(character);
MainRc.MessageSender.SendKeyPress(character);
if (sendShift) {
sockets.SendKeyUp("Shift");
MainRc.MessageSender.SendKeyUp("Shift");
}
}
}
@ -387,14 +387,14 @@ export function ApplyInputHandlers(sockets: RCBrowserSockets) {
return;
}
e.preventDefault();
sockets.SendKeyDown(e.key);
MainRc.MessageSender.SendKeyDown(e.key);
});
window.addEventListener("keyup", function (e) {
if (document.querySelector("input:focus") || document.querySelector("textarea:focus")) {
return;
}
e.preventDefault();
sockets.SendKeyUp(e.key);
MainRc.MessageSender.SendKeyUp(e.key);
});
window.ondragover = function (e) {
@ -499,35 +499,35 @@ export function UpdateDisplays(selectedDisplay: string, displayNames: string[])
}
function uploadFiles(fileList: FileList) {
ShowMessage("File upload started...");
FileTransferProgress.value = 0;
FileTransferProgress.parentElement.removeAttribute("hidden");
//ShowMessage("File upload started...");
//FileTransferProgress.value = 0;
//FileTransferProgress.parentElement.removeAttribute("hidden");
var strPath = "/API/FileSharing/";
var fd = new FormData();
for (var i = 0; i < fileList.length; i++) {
fd.append('fileUpload' + i, fileList[i]);
}
var xhr = new XMLHttpRequest();
xhr.open('POST', strPath, true);
xhr.addEventListener("load", function () {
FileTransferProgress.parentElement.setAttribute("hidden", "hidden");
if (xhr.status === 200) {
ShowMessage("File upload completed.");
MainRc.RCBrowserSockets.SendSharedFileIDs(xhr.responseText);
}
else {
ShowMessage("File upload failed.");
}
});
xhr.addEventListener("error", () => {
FileTransferProgress.parentElement.setAttribute("hidden", "hidden");
ShowMessage("File upload failed.");
});
xhr.addEventListener("progress", function (e) {
FileTransferProgress.value = isFinite(e.loaded / e.total) ? e.loaded / e.total : 0;
});
xhr.send(fd);
//var strPath = "/API/FileSharing/";
//var fd = new FormData();
//for (var i = 0; i < fileList.length; i++) {
// fd.append('fileUpload' + i, fileList[i]);
//}
//var xhr = new XMLHttpRequest();
//xhr.open('POST', strPath, true);
//xhr.addEventListener("load", function () {
// FileTransferProgress.parentElement.setAttribute("hidden", "hidden");
// if (xhr.status === 200) {
// ShowMessage("File upload completed.");
// MainRc.RCBrowserSockets.SendSharedFileIDs(xhr.responseText);
// }
// else {
// ShowMessage("File upload failed.");
// }
//});
//xhr.addEventListener("error", () => {
// FileTransferProgress.parentElement.setAttribute("hidden", "hidden");
// ShowMessage("File upload failed.");
//});
//xhr.addEventListener("progress", function (e) {
// FileTransferProgress.value = isFinite(e.loaded / e.total) ? e.loaded / e.total : 0;
//});
//xhr.send(fd);
}

View File

@ -1,9 +0,0 @@
using Remotely.Shared.Enums;
namespace Remotely.Shared.Models
{
public interface IBinaryDto
{
BinaryDtoType DtoType { get; }
}
}

View File

@ -0,0 +1,25 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class AudioSampleDto : BinaryDtoBase
{
public AudioSampleDto(byte[] audioSample)
{
Buffer = audioSample;
}
[DataMember(Name = "Buffer")]
public byte[] Buffer { get; }
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; } = BinaryDtoType.AudioSample;
}
}

View File

@ -0,0 +1,18 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class AutoQualityAdjustDto : BinaryDtoBase
{
[DataMember(Name = "IsOn")]
public bool IsOn { get; set; }
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; } = BinaryDtoType.AutoQualityAdjust;
}
}

View File

@ -0,0 +1,12 @@
using Remotely.Shared.Enums;
using System.Runtime.Serialization;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class BinaryDtoBase
{
[DataMember(Name = "DtoType")]
public BinaryDtoType DtoType { get; set; }
}
}

View File

@ -4,10 +4,10 @@ using System.Runtime.Serialization;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class CaptureFrameDto : IBinaryDto
public class CaptureFrameDto : BinaryDtoBase
{
[DataMember(Name = "DtoType")]
public BinaryDtoType DtoType { get; } = BinaryDtoType.CaptureFrame;
public new BinaryDtoType DtoType { get; } = BinaryDtoType.CaptureFrame;
[DataMember(Name = "EndOfFrame")]
public bool EndOfFrame { get; set; }

View File

@ -7,7 +7,7 @@ using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class ClipboardTextDto : IBinaryDto
public class ClipboardTextDto : BinaryDtoBase
{
public ClipboardTextDto(string clipboardText)
{
@ -19,6 +19,6 @@ namespace Remotely.Shared.Models.RtcDtos
[DataMember(Name = "DtoType")]
public BinaryDtoType DtoType { get; } = BinaryDtoType.ClipboardText;
public new BinaryDtoType DtoType { get; } = BinaryDtoType.ClipboardText;
}
}

View File

@ -0,0 +1,23 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class ClipboardTransferDto : BinaryDtoBase
{
[DataMember(Name = "Text")]
public string Text { get; set; }
[DataMember(Name = "TypeText")]
public bool TypeText { get; set; }
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; } = BinaryDtoType.ClipboardTransfer;
}
}

View File

@ -0,0 +1,18 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class KeyDownDto : BinaryDtoBase
{
[DataMember(Name = "Key")]
public string Key { get; set; }
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; } = BinaryDtoType.KeyDown;
}
}

View File

@ -0,0 +1,18 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class KeyPressDto : BinaryDtoBase
{
[DataMember(Name = "Key")]
public string Key { get; set; }
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; } = BinaryDtoType.KeyPress;
}
}

View File

@ -0,0 +1,18 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class KeyUpDto : BinaryDtoBase
{
[DataMember(Name = "Key")]
public string Key { get; set; }
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; } = BinaryDtoType.KeyUp;
}
}

View File

@ -7,7 +7,7 @@ using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class MachineNameDto : IBinaryDto
public class MachineNameDto : BinaryDtoBase
{
public MachineNameDto(string machineName)
{
@ -15,7 +15,7 @@ namespace Remotely.Shared.Models.RtcDtos
}
[DataMember(Name = "DtoType")]
public BinaryDtoType DtoType { get; } = BinaryDtoType.MachineName;
public new BinaryDtoType DtoType { get; } = BinaryDtoType.MachineName;
[DataMember(Name = "MachineName")]
public string MachineName { get; }

View File

@ -0,0 +1,24 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class MouseDownDto : BinaryDtoBase
{
[DataMember(Name = "Button")]
public int Button { get; set; }
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; } = BinaryDtoType.MouseDown;
[DataMember(Name = "PercentX")]
public double PercentX { get; set; }
[DataMember(Name = "PercentY")]
public double PercentY { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class MouseMoveDto : BinaryDtoBase
{
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; set; } = BinaryDtoType.MouseMove;
[DataMember(Name = "PercentX")]
public double PercentX { get; set; }
[DataMember(Name = "PercentY")]
public double PercentY { get; set; }
}
}

View File

@ -0,0 +1,24 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class MouseUpDto : BinaryDtoBase
{
[DataMember(Name = "Button")]
public int Button { get; set; }
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; } = BinaryDtoType.MouseUp;
[DataMember(Name = "PercentX")]
public double PercentX { get; set; }
[DataMember(Name = "PercentY")]
public double PercentY { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class MouseWheelDto : BinaryDtoBase
{
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; } = BinaryDtoType.MouseWheel;
[DataMember(Name = "DeltaX")]
public double DeltaX { get; set; }
[DataMember(Name = "DeltaY")]
public double DeltaY { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class QualityChangeDto : BinaryDtoBase
{
[DataMember(Name = "QualityLevel")]
public int QualityLevel { get; set; }
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; } = BinaryDtoType.QualityChange;
}
}

View File

@ -7,7 +7,7 @@ using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class ScreenDataDto : IBinaryDto
public class ScreenDataDto : BinaryDtoBase
{
public ScreenDataDto(string selectedScreen, string[] displayNames)
{
@ -20,7 +20,7 @@ namespace Remotely.Shared.Models.RtcDtos
[DataMember(Name = "DtoType")]
public BinaryDtoType DtoType { get; } = BinaryDtoType.ScreenData;
public new BinaryDtoType DtoType { get; } = BinaryDtoType.ScreenData;
[DataMember(Name = "SelectedScreen")]
public string SelectedScreen { get; }

View File

@ -7,7 +7,7 @@ using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class ScreenSizeDto : IBinaryDto
public class ScreenSizeDto : BinaryDtoBase
{
public ScreenSizeDto(int width, int height)
{
@ -22,6 +22,6 @@ namespace Remotely.Shared.Models.RtcDtos
public int Height { get; }
[DataMember(Name = "DtoType")]
public BinaryDtoType DtoType { get; } = BinaryDtoType.ScreenSize;
public new BinaryDtoType DtoType { get; } = BinaryDtoType.ScreenSize;
}
}

View File

@ -0,0 +1,18 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class SelectScreenDto : BinaryDtoBase
{
[DataMember(Name = "DisplayName")]
public string DisplayName { get; set; }
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; } = BinaryDtoType.SelectScreen;
}
}

View File

@ -0,0 +1,22 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class TapDto : BinaryDtoBase
{
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; } = BinaryDtoType.Tap;
[DataMember(Name = "PercentX")]
public double PercentX { get; set; }
[DataMember(Name = "PercentY")]
public double PercentY { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class ToggleAudioDto : BinaryDtoBase
{
[DataMember(Name = "ToggleOn")]
public bool ToggleOn { get; set; }
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; } = BinaryDtoType.ToggleAudio;
}
}

View File

@ -0,0 +1,18 @@
using Remotely.Shared.Enums;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Remotely.Shared.Models.RtcDtos
{
[DataContract]
public class ToggleBlockInputDto : BinaryDtoBase
{
[DataMember(Name = "ToggleOn")]
public bool ToggleOn { get; set; }
[DataMember(Name = "DtoType")]
public new BinaryDtoType DtoType { get; } = BinaryDtoType.ToggleBlockInput;
}
}