@page "/" @rendermode @(new InteractiveWebAssemblyRenderMode(false)) @if (!_cryptoSupported) {

Start a transfer

} else { @if (_error is not null) { } @switch (Session.State) { case SessionState.Idle: case SessionState.Joining:

Start a transfer

Connect two browsers with a one-time code. Messages and files are encrypted on this device before they are sent.

Create a connection

Generates a one-time code. Share it with the person you want to exchange messages and files with.

@if (Load is { } load && IsServerFull) {

The server is full (@load.ActiveConnections/@load.MaxConnections connections in use@(load.QueuedClients > 0 ? $", {load.QueuedClients} waiting" : null)). You will be placed in a queue.

}

Join a connection

Enter the code you received.

  1. 01
    Create One side creates a connection and shares the code.
  2. 02
    Join The other side enters the code to connect.
  3. 03
    Verify & transfer Compare the safety code, then send messages and files.
break; case SessionState.Queued:

Waiting for a free slot

The server has reached its connection limit. Your connection is created automatically as soon as another one closes – keep this page open.

Queue

@Session.QueuePosition
@QueueAheadText Position in the queue
Waiting for a connection to close… @if (Load is { } queueLoad) { @queueLoad.ActiveConnections/@queueLoad.MaxConnections connections in use }
break; case SessionState.Waiting:

Share the code

Give this code to the person you want to connect with, for example by phone or messenger. It can only be used once.

Connection code

@foreach (var c in DisplayCode ?? string.Empty) { @c }
@(Session.IsPeerJoining ? "The other person joined. Securing the connection…" : "Waiting for the other person to join…") Expires in @RemainingTime
break; default: var connected = Session.State == SessionState.Connected; @if (connected) {

Connected

Code
@DisplayCode
Safety code
@Session.SafetyCode
Idle timeout · @DisplayFormat.Duration(Session.InactivityTimeout)
@RemainingTime left

Compare the safety code with your partner over another channel (e.g. by phone). If both codes match, nobody else – not even this server – can read your messages and files.

} else {

Disconnected

@Session.ClosedMessage @if (Session.HasPeer) { Received files stay available until you start a new connection. }
} @if (Session.HasPeer) {
@if (connected) {

Send

Ctrl + Enter to send
}

Transfers

@SentCount sent @ReceivedCount received
@* column-reverse keeps the log scrolled to the newest entry without any JavaScript. *@
@if (Session.Entries.Count == 0) {
Nothing transferred yet Messages and files are encrypted in your browser before they leave it.
} else {
    @foreach (var entry in Session.Entries) { @if (entry.Kind == ChatEntryKind.System) {
  1. @entry.Text
  2. } else { var outgoing = entry.Kind == ChatEntryKind.Outgoing;
  3. @(outgoing ? "Sent" : "Received")
    @if (entry.IsFile) {
    @entry.FileName
    @if (entry.IsRiskyFile) {
    This file type can run programs or scripts on your device. Only open it if you know the sender and expected this file.
    } @if (entry.Error is not null) {
    @entry.Error
    } else if (entry.IsTransferring) {
    } } else {
    @entry.Text
    }
    @if (!entry.IsFile) { } else if (entry.Error is not null) { Failed } else if (entry.IsTransferring) { @entry.ProgressPercent% } else if (entry.DownloadUrl is not null) { Save @entry.FileName } else { @(outgoing ? "Sent" : "Received") }
  4. } }
}
} break; } }