Blog/Components/Pages/Send.razor 2.8 K · 79 lines · raw · history

1 @page "/Send"
2 @using System.Text.Json
3 @using Blog.Services
4 @using Microsoft.Extensions.Options
5 @inject IOptions<SendOptions> Options
6
7 <PageTitle>Send</PageTitle>
8 <script type="module" src="@Assets["Components/Pages/Send.razor.js"]"></script>
9
10 <main>
11 <h1>Send</h1>
12
13 <p>
14 Send a file to another browser. Open this page in both, pair them with the link or the
15 code, and the file goes straight from one to the other.
16 </p>
17
18 @* The ICE servers are configuration, so the page carries them rather than the script
19 hard-coding them. A data attribute rather than a <script type="application/json"> block:
20 Razor HTML-encodes element content, and attribute encoding round-trips through JSON.parse. *@
21 <div id="ice" data-servers="@IceServers" hidden></div>
22
23 <Panel Legend="Connection">
24 <p id="state">Starting…</p>
25
26 @* Put away once the room has its two browsers: the link is no use to a third. *@
27 <div id="pairing">
28 <div class="flex-row">
29 <label for="link">Link</label>
30 <input type="text" id="link" readonly/>
31 <button type="button" id="copy">Copy</button>
32 </div>
33
34 <p>…or read out the code: <strong id="code"></strong></p>
35
36 <div id="qrcode"></div>
37 </div>
38
39 <form id="joinForm" class="flex-row">
40 <label for="joinCode">Been given a code?</label>
41 <input type="text" id="joinCode" placeholder="ABCD-EFGH-JKMN" autocomplete="off"
42 spellcheck="false"/>
43 <button type="submit">Join</button>
44 </form>
45 </Panel>
46
47 <Panel Legend="Sending">
48 <div id="drop" class="dropzone">
49 <input type="file" id="files" multiple disabled/>
50 <p>…or drop files here.</p>
51 </div>
52 <ul id="outgoing" class="transfers"></ul>
53 </Panel>
54
55 <Panel Legend="Received">
56 <ul id="incoming" class="transfers"></ul>
57 <p id="nothingYet">Nothing yet.</p>
58 </Panel>
59
60 <Panel Legend="How this works">
61 <p>
62 <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API"
63 rel="external noreferrer">WebRTC</a> is the browser's own way of opening a
64 connection straight to another browser. The two ends swap what they know about how
65 to reach each other, settle on a route, and from then on talk directly — on a shared
66 network, over the local one. The file is read off disk in chunks and written down
67 that connection.
68 </p>
69 </Panel>
70
71 <Log/>
72 </main>
73
74 @code {
75
76 /// <summary>The configured STUN/TURN URLs, as a JSON array for <c>RTCPeerConnection</c>.</summary>
77 private string IceServers => JsonSerializer.Serialize(Options.Value.IceServers);
78
79 }