mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-26 07:28:45 -07:00
7d1ac82cf8
Set DORKNET_LOCAL_MANIFEST and/or DORKNET_LOCAL_RELEASES to point
the launcher at on-disk artifacts instead of the public repo:
- DORKNET_LOCAL_MANIFEST: full path to a versions.json file.
VersionsManifest.FetchAsync reads it from disk and skips the
GitHub round-trip.
- DORKNET_LOCAL_RELEASES: path to a directory laid out as
{root}/{version_key}/server/ + .../patcher/. EnsureServerAsync /
EnsurePatcherAsync return those paths in-place — no download,
no copy, no marker files.
Both are silent no-ops when unset / missing on disk, so it's safe
to leave them set permanently in a dev profile. When at least one
is active, the Settings view surfaces a "Dev overrides active"
panel listing the paths so it's obvious the launcher isn't using
the public manifest.
Lets contributors iterate on per-version branch changes against
the launcher UI without needing to tag a public Release.
703 lines
45 KiB
XML
703 lines
45 KiB
XML
<Window x:Class="DorkNet.Launcher.MainWindow"
|
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
Title="DorkNet"
|
|
Width="960" Height="700"
|
|
MinWidth="720" MinHeight="540"
|
|
WindowStartupLocation="CenterScreen"
|
|
Background="{StaticResource Bg}"
|
|
TextElement.Foreground="{StaticResource Ink}"
|
|
FontFamily="Segoe UI Variable, Segoe UI"
|
|
TextOptions.TextFormattingMode="Ideal"
|
|
TextOptions.TextRenderingMode="ClearType">
|
|
|
|
<!-- Soft radial-ish glow in the top-left corner of the window for
|
|
atmosphere. WPF doesn't have a true radial gradient on Background
|
|
without nested Border tricks, so we stack a linear-gradient
|
|
overlay on top of the solid Bg. -->
|
|
<Grid>
|
|
<Grid.Background>
|
|
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
|
|
<GradientStop Color="#2A1E48" Offset="0" />
|
|
<GradientStop Color="#16102A" Offset="0.6" />
|
|
<GradientStop Color="#16102A" Offset="1" />
|
|
</LinearGradientBrush>
|
|
</Grid.Background>
|
|
|
|
<Grid Margin="36,28">
|
|
<!-- View slots — only one Visible at a time; code-behind toggles. -->
|
|
|
|
<!-- ── Welcome screen ─────────────────────────────────────
|
|
Only shown on truly first launch. After "Get started"
|
|
the user enters the setup wizard; subsequent launches
|
|
skip straight to Setup or HostView/JoinView. -->
|
|
<StackPanel x:Name="WelcomeView" Visibility="Collapsed"
|
|
VerticalAlignment="Center" HorizontalAlignment="Center"
|
|
MaxWidth="520">
|
|
<TextBlock Text="DorkNet"
|
|
FontSize="72" FontWeight="Bold"
|
|
Foreground="{StaticResource WordmarkBrush}"
|
|
HorizontalAlignment="Center"
|
|
FontFamily="Segoe UI Variable, Segoe UI" />
|
|
<TextBlock Text="Play together on your own Rec Room server."
|
|
Foreground="{StaticResource Ink}"
|
|
FontSize="18"
|
|
HorizontalAlignment="Center" Margin="0,8,0,32"
|
|
TextAlignment="Center" />
|
|
|
|
<Border Style="{StaticResource Panel}"
|
|
Background="{StaticResource CardBg}" Padding="28,24"
|
|
Margin="0,0,0,28">
|
|
<StackPanel>
|
|
<StackPanel Orientation="Horizontal" Margin="0,0,0,14">
|
|
<TextBlock Text="✨" FontSize="20" Margin="0,0,12,0" />
|
|
<TextBlock Foreground="{StaticResource Ink}" FontSize="14"
|
|
VerticalAlignment="Center" TextWrapping="Wrap"
|
|
Text="Set up in about two minutes" />
|
|
</StackPanel>
|
|
<StackPanel Orientation="Horizontal" Margin="0,0,0,14">
|
|
<TextBlock Text="💸" FontSize="20" Margin="0,0,12,0" />
|
|
<TextBlock Foreground="{StaticResource Ink}" FontSize="14"
|
|
VerticalAlignment="Center" TextWrapping="Wrap"
|
|
Text="Host for free — no credit card, no subscription" />
|
|
</StackPanel>
|
|
<StackPanel Orientation="Horizontal">
|
|
<TextBlock Text="🎮" FontSize="20" Margin="0,0,12,0" />
|
|
<TextBlock Foreground="{StaticResource Ink}" FontSize="14"
|
|
VerticalAlignment="Center" TextWrapping="Wrap"
|
|
Text="Works with the regular Rec Room game — no rebuild needed" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<Button Style="{StaticResource PrimaryBtn}"
|
|
Content="Get started →"
|
|
Click="OnWelcomeContinue"
|
|
HorizontalAlignment="Center"
|
|
Padding="34,14" FontSize="15" />
|
|
|
|
<TextBlock Text="Not affiliated with Rec Room Inc. or Against Gravity."
|
|
HorizontalAlignment="Center"
|
|
Foreground="{StaticResource InkFaint}"
|
|
FontSize="11" Margin="0,28,0,0" />
|
|
</StackPanel>
|
|
|
|
<!-- ── Setup wizard ────────────────────────────────────────
|
|
Shown on first launch after Welcome. Walks through mode
|
|
pick, install location, server config + Photon. Once
|
|
the user finishes the last step, AppState.SetupComplete
|
|
flips and future launches go straight to HostView /
|
|
JoinView (which still hold the same fields for tweaks). -->
|
|
<Grid x:Name="SetupView" Visibility="Collapsed">
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto" />
|
|
<RowDefinition Height="*" />
|
|
<RowDefinition Height="Auto" />
|
|
</Grid.RowDefinitions>
|
|
|
|
<Grid Grid.Row="0" Margin="0,0,0,24">
|
|
<StackPanel Orientation="Horizontal">
|
|
<TextBlock Text="DorkNet" FontSize="22" FontWeight="Bold"
|
|
Foreground="{StaticResource WordmarkBrush}" />
|
|
<Border Style="{StaticResource StatusChip}" Margin="14,0,0,0"
|
|
VerticalAlignment="Center">
|
|
<TextBlock x:Name="SetupStepIndicator"
|
|
Text="STEP 1" FontSize="10"
|
|
FontWeight="Bold" Foreground="{StaticResource Brand}" />
|
|
</Border>
|
|
</StackPanel>
|
|
</Grid>
|
|
|
|
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto"
|
|
Padding="0,0,8,0">
|
|
<Grid>
|
|
<!-- Setup step 1: Host or Join? -->
|
|
<StackPanel x:Name="SetupStep1" Visibility="Visible">
|
|
<TextBlock Text="What do you want to do?" FontSize="26"
|
|
FontWeight="Bold" Margin="0,0,0,8" />
|
|
<TextBlock Text="Pick a mode. You can change this later under Settings."
|
|
Foreground="{StaticResource InkSoft}" FontSize="14"
|
|
Margin="0,0,0,28" />
|
|
|
|
<Grid MaxWidth="780" HorizontalAlignment="Left">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*" />
|
|
<ColumnDefinition Width="20" />
|
|
<ColumnDefinition Width="*" />
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<Button Grid.Column="0" Style="{StaticResource ChoiceCardBtn}"
|
|
Background="{StaticResource CardBgHost}"
|
|
Click="OnSetupPickHost">
|
|
<StackPanel>
|
|
<Border CornerRadius="14" Width="56" Height="56"
|
|
Background="#3D2B57" Margin="0,0,0,18"
|
|
HorizontalAlignment="Left">
|
|
<TextBlock Text="🛠" FontSize="32"
|
|
HorizontalAlignment="Center"
|
|
VerticalAlignment="Center" />
|
|
</Border>
|
|
<TextBlock Text="Host a server" FontSize="22"
|
|
FontWeight="Bold" Margin="0,0,0,10" />
|
|
<TextBlock Foreground="{StaticResource InkSoft}"
|
|
FontSize="13" TextWrapping="Wrap" LineHeight="20"
|
|
Text="Run a server for you and your friends. The launcher handles the tunnel, gives you a shareable join code." />
|
|
</StackPanel>
|
|
</Button>
|
|
|
|
<Button Grid.Column="2" Style="{StaticResource ChoiceCardBtn}"
|
|
Background="{StaticResource CardBgJoin}"
|
|
Click="OnSetupPickJoin">
|
|
<StackPanel>
|
|
<Border CornerRadius="14" Width="56" Height="56"
|
|
Background="#1C3C4A" Margin="0,0,0,18"
|
|
HorizontalAlignment="Left">
|
|
<TextBlock Text="🎮" FontSize="32"
|
|
HorizontalAlignment="Center"
|
|
VerticalAlignment="Center" />
|
|
</Border>
|
|
<TextBlock Text="Join a friend" FontSize="22"
|
|
FontWeight="Bold" Margin="0,0,0,10" />
|
|
<TextBlock Foreground="{StaticResource InkSoft}"
|
|
FontSize="13" TextWrapping="Wrap" LineHeight="20"
|
|
Text="You have a join code from someone. Paste it and the launcher fetches the matching patcher." />
|
|
</StackPanel>
|
|
</Button>
|
|
</Grid>
|
|
</StackPanel>
|
|
|
|
<!-- Setup step 2: Rec Room install -->
|
|
<StackPanel x:Name="SetupStep2" Visibility="Collapsed">
|
|
<TextBlock Text="Where's Rec Room installed?" FontSize="26"
|
|
FontWeight="Bold" Margin="0,0,0,8" />
|
|
<TextBlock Text="The launcher needs to find your Rec Room install folder. Pick the *_Data folder inside the install (e.g. Recroom_Release_Data)."
|
|
Foreground="{StaticResource InkSoft}" FontSize="14"
|
|
TextWrapping="Wrap" Margin="0,0,0,24" />
|
|
|
|
<Border x:Name="SetupDetectedBanner" Visibility="Collapsed"
|
|
Style="{StaticResource Panel}"
|
|
Background="{StaticResource CardBgJoin}"
|
|
Margin="0,0,0,16">
|
|
<StackPanel>
|
|
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
|
|
<TextBlock Text="✓" FontSize="18"
|
|
Foreground="{StaticResource Ok}"
|
|
Margin="0,0,10,0" />
|
|
<TextBlock Text="We found a Rec Room install"
|
|
FontSize="15" FontWeight="SemiBold"
|
|
VerticalAlignment="Center" />
|
|
</StackPanel>
|
|
<TextBlock x:Name="SetupDetectedPath"
|
|
Foreground="{StaticResource InkSoft}"
|
|
FontSize="12"
|
|
FontFamily="Cascadia Mono, Consolas"
|
|
TextWrapping="Wrap" Margin="28,0,0,0" />
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<DockPanel Margin="0,0,0,12">
|
|
<Button DockPanel.Dock="Right" Style="{StaticResource Btn}"
|
|
Content="Pick…" Click="OnPickRecRoom" Margin="8,0,0,0" />
|
|
<Border Background="{StaticResource BgDeeper}"
|
|
BorderBrush="{StaticResource BorderSoft}" BorderThickness="1"
|
|
CornerRadius="10" Padding="12,10">
|
|
<TextBlock x:Name="SetupRecRoomPath"
|
|
Text="(not picked)"
|
|
Foreground="{StaticResource InkSoft}"
|
|
TextTrimming="CharacterEllipsis" FontSize="13" />
|
|
</Border>
|
|
</DockPanel>
|
|
<TextBlock Foreground="{StaticResource InkFaint}" FontSize="11"
|
|
TextWrapping="Wrap"
|
|
Text="Don't have Rec Room installed yet? Grab it from the Rec Room website (or wherever you usually get it). DorkNet works with any official install." />
|
|
</StackPanel>
|
|
|
|
<!-- Setup step 3 (HOST only): Server name + WHO CAN JOIN -->
|
|
<StackPanel x:Name="SetupStep3" Visibility="Collapsed">
|
|
<TextBlock Text="Set up your server" FontSize="26"
|
|
FontWeight="Bold" Margin="0,0,0,8" />
|
|
<TextBlock Text="Name your server so friends know what they're joining."
|
|
Foreground="{StaticResource InkSoft}" FontSize="14"
|
|
Margin="0,0,0,24" />
|
|
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="SERVER NAME" />
|
|
<TextBox x:Name="SetupServerName" Margin="0,0,0,20"
|
|
LostFocus="OnSetupServerNameChanged" />
|
|
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="WHO CAN JOIN?" />
|
|
<StackPanel Margin="0,0,0,16">
|
|
<RadioButton x:Name="SetupHostInternet" GroupName="SetupHostingMode"
|
|
Content="Friends anywhere (internet via Cloudflare)"
|
|
IsChecked="True" Margin="0,0,0,6"
|
|
Checked="OnSetupHostingModeChanged"
|
|
Foreground="{StaticResource Ink}" />
|
|
<RadioButton x:Name="SetupHostLocal" GroupName="SetupHostingMode"
|
|
Content="Same WiFi only (no internet needed)"
|
|
Checked="OnSetupHostingModeChanged"
|
|
Foreground="{StaticResource Ink}" />
|
|
</StackPanel>
|
|
<TextBlock Foreground="{StaticResource InkFaint}" FontSize="11"
|
|
TextWrapping="Wrap"
|
|
Text="Cloudflare mode works for friends anywhere. Same-WiFi mode is fastest but only works for people on your local network." />
|
|
</StackPanel>
|
|
|
|
<!-- Setup step 4 (HOST only): Photon AppIds -->
|
|
<StackPanel x:Name="SetupStep4" Visibility="Collapsed">
|
|
<TextBlock Text="Connect your Photon account" FontSize="26"
|
|
FontWeight="Bold" Margin="0,0,0,8" />
|
|
<TextBlock TextWrapping="Wrap"
|
|
Foreground="{StaticResource InkSoft}" FontSize="14"
|
|
Margin="0,0,0,24"
|
|
Text="DorkNet needs your own Photon account (free, takes ~2 min) to handle in-room sync. Click the walkthrough below — it'll open the Photon website, tell you what to click, and bring you back here." />
|
|
|
|
<Button Style="{StaticResource PrimaryBtn}"
|
|
Content="Open setup walkthrough"
|
|
Click="OnOpenPhotonWizard"
|
|
HorizontalAlignment="Left" Margin="0,0,0,20" />
|
|
|
|
<Border Style="{StaticResource Panel}"
|
|
Background="{StaticResource BgDeeper}"
|
|
Margin="0,0,0,12">
|
|
<StackPanel>
|
|
<TextBlock Foreground="{StaticResource InkSoft}" FontSize="12"
|
|
Margin="0,0,0,8"
|
|
Text="Already have AppIds? Paste them here." />
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="REALTIME APPID" />
|
|
<TextBox x:Name="SetupPhotonAppId" Margin="0,0,0,12"
|
|
FontFamily="Cascadia Mono, Consolas" FontSize="12"
|
|
LostFocus="OnSetupPhotonChanged" />
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="VOICE APPID (OPTIONAL)" />
|
|
<TextBox x:Name="SetupPhotonVoiceAppId" Margin="0,0,0,0"
|
|
FontFamily="Cascadia Mono, Consolas" FontSize="12"
|
|
LostFocus="OnSetupPhotonChanged" />
|
|
</StackPanel>
|
|
</Border>
|
|
<TextBlock x:Name="SetupPhotonStatus"
|
|
Foreground="{StaticResource InkFaint}" FontSize="11"
|
|
Text="Realtime AppId required before you can host." />
|
|
</StackPanel>
|
|
|
|
<!-- Setup done: short confirmation card -->
|
|
<StackPanel x:Name="SetupStepDone" Visibility="Collapsed">
|
|
<TextBlock Text="You're all set! 🎉" FontSize="26"
|
|
FontWeight="Bold" Margin="0,0,0,12" />
|
|
<TextBlock TextWrapping="Wrap"
|
|
Foreground="{StaticResource Ink}" FontSize="14"
|
|
LineHeight="22"
|
|
Text="Setup's done. Hit Finish to open the main view — everything you just configured is saved, so you can hit Start hosting straight away." />
|
|
</StackPanel>
|
|
</Grid>
|
|
</ScrollViewer>
|
|
|
|
<!-- Footer nav -->
|
|
<Grid Grid.Row="2" Margin="0,20,0,0">
|
|
<Button x:Name="SetupBackBtn" HorizontalAlignment="Left"
|
|
Style="{StaticResource GhostBtn}"
|
|
Content="← Back" Click="OnSetupBack" Visibility="Collapsed" />
|
|
<Button x:Name="SetupNextBtn" HorizontalAlignment="Right"
|
|
Style="{StaticResource PrimaryBtn}"
|
|
Content="Next →" Click="OnSetupNext" Visibility="Collapsed" />
|
|
</Grid>
|
|
</Grid>
|
|
|
|
<!-- ── Host view ──────────────────────────────────────────── -->
|
|
<Grid x:Name="HostView" Visibility="Collapsed">
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto" />
|
|
<RowDefinition Height="*" />
|
|
</Grid.RowDefinitions>
|
|
|
|
<!-- Header bar with wordmark + view label + settings button -->
|
|
<Grid Grid.Row="0" Margin="0,0,0,28">
|
|
<StackPanel Orientation="Horizontal">
|
|
<TextBlock Text="DorkNet" FontSize="22" FontWeight="Bold"
|
|
Foreground="{StaticResource WordmarkBrush}" />
|
|
<Border Style="{StaticResource StatusChip}" Margin="14,0,0,0"
|
|
VerticalAlignment="Center">
|
|
<TextBlock Text="HOST MODE" FontSize="10"
|
|
FontWeight="Bold" Foreground="{StaticResource Brand}" />
|
|
</Border>
|
|
</StackPanel>
|
|
<Button HorizontalAlignment="Right" Style="{StaticResource GhostBtn}"
|
|
Content="Settings" Click="OnOpenSettings" />
|
|
</Grid>
|
|
|
|
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto"
|
|
Padding="0,0,8,0">
|
|
<StackPanel>
|
|
<!-- Setup panel -->
|
|
<Border Style="{StaticResource Panel}" Margin="0,0,0,16">
|
|
<StackPanel>
|
|
<TextBlock Style="{StaticResource SectionTitle}" Text="Setup" />
|
|
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="REC ROOM INSTALL" />
|
|
<DockPanel Margin="0,0,0,16">
|
|
<Button DockPanel.Dock="Right" Style="{StaticResource Btn}"
|
|
Content="Pick…" Click="OnPickRecRoom" Margin="8,0,0,0" />
|
|
<Border Background="{StaticResource BgDeeper}"
|
|
BorderBrush="{StaticResource BorderSoft}" BorderThickness="1"
|
|
CornerRadius="10" Padding="12,10">
|
|
<TextBlock x:Name="HostRecRoomPath"
|
|
Text="(not picked)"
|
|
Foreground="{StaticResource InkSoft}"
|
|
TextTrimming="CharacterEllipsis" FontSize="13" />
|
|
</Border>
|
|
</DockPanel>
|
|
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="SERVER NAME (SHOWN TO JOINERS)" />
|
|
<TextBox x:Name="ServerNameInput" Margin="0,0,0,16"
|
|
LostFocus="OnServerNameChanged" />
|
|
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="REC ROOM VERSION TO HOST FOR" />
|
|
<ComboBox x:Name="VersionSelect" Margin="0,0,0,16" />
|
|
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="WHO CAN JOIN?" />
|
|
<StackPanel Orientation="Horizontal">
|
|
<RadioButton x:Name="HostModeInternet" GroupName="HostingMode"
|
|
Content="Friends anywhere (internet via Cloudflare)"
|
|
IsChecked="True" Checked="OnHostingModeChanged"
|
|
Foreground="{StaticResource Ink}" />
|
|
<RadioButton x:Name="HostModeLocal" GroupName="HostingMode"
|
|
Content="Same WiFi only (no internet needed)"
|
|
Margin="22,0,0,0" Checked="OnHostingModeChanged"
|
|
Foreground="{StaticResource Ink}" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Photon panel -->
|
|
<Border Style="{StaticResource Panel}" Margin="0,0,0,16">
|
|
<StackPanel>
|
|
<Grid Margin="0,0,0,12">
|
|
<TextBlock Style="{StaticResource SectionTitle}"
|
|
Text="Photon AppIds" Margin="0" />
|
|
<Button HorizontalAlignment="Right" Style="{StaticResource Btn}"
|
|
Content="Setup walkthrough" Click="OnOpenPhotonWizard"
|
|
Padding="14,6" FontSize="12" />
|
|
</Grid>
|
|
<TextBlock Foreground="{StaticResource InkSoft}" FontSize="12"
|
|
Margin="0,0,0,12" TextWrapping="Wrap">
|
|
Photon Cloud powers in-room realtime sync. Free to register at
|
|
<Hyperlink NavigateUri="https://dashboard.photonengine.com"
|
|
Foreground="{StaticResource Brand}"
|
|
RequestNavigate="OnNavigate">dashboard.photonengine.com</Hyperlink>;
|
|
DorkNet never bundles one. First time? Click "Setup walkthrough" above.
|
|
</TextBlock>
|
|
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="REALTIME APPID" />
|
|
<TextBox x:Name="PhotonAppIdInput" Margin="0,0,0,12"
|
|
LostFocus="OnPhotonChanged" />
|
|
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="VOICE APPID (OPTIONAL)" />
|
|
<TextBox x:Name="PhotonVoiceAppIdInput" Margin="0,0,0,12"
|
|
LostFocus="OnPhotonChanged" />
|
|
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="CLOUD REGION" />
|
|
<ComboBox x:Name="PhotonRegionSelect"
|
|
SelectionChanged="OnPhotonChanged">
|
|
<ComboBoxItem Content="US" Tag="us" />
|
|
<ComboBoxItem Content="EU" Tag="eu" />
|
|
<ComboBoxItem Content="Asia" Tag="asia" />
|
|
<ComboBoxItem Content="Japan" Tag="jp" />
|
|
<ComboBoxItem Content="South America" Tag="sa" />
|
|
<ComboBoxItem Content="Korea" Tag="kr" />
|
|
<ComboBoxItem Content="India" Tag="in" />
|
|
<ComboBoxItem Content="Australia" Tag="au" />
|
|
</ComboBox>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Action area -->
|
|
<StackPanel Orientation="Horizontal" Margin="0,4,0,16">
|
|
<Button x:Name="HostStartBtn" Style="{StaticResource PrimaryBtn}"
|
|
Content="Start hosting" Click="OnHostStart" />
|
|
<Button x:Name="HostStopBtn" Style="{StaticResource Btn}"
|
|
Content="Stop" Click="OnHostStop"
|
|
Margin="10,0,0,0" Visibility="Collapsed" />
|
|
<Button x:Name="HostLaunchBtn" Style="{StaticResource TealBtn}"
|
|
Content="Launch Rec Room" Click="OnLaunchRecRoom"
|
|
Margin="10,0,0,0" Visibility="Collapsed" />
|
|
</StackPanel>
|
|
|
|
<!-- Progress steps — populated when the user hits
|
|
"Start hosting". Hidden until then so the
|
|
idle Host view stays clean. -->
|
|
<Border x:Name="HostStepsPanel" Style="{StaticResource Panel}"
|
|
Margin="0,0,0,16" Visibility="Collapsed">
|
|
<StackPanel>
|
|
<TextBlock Style="{StaticResource SectionTitle}" Text="Progress" />
|
|
<ItemsControl x:Name="HostStepsList"
|
|
ItemTemplate="{StaticResource StepRowTemplate}" />
|
|
<TextBlock x:Name="HostStatusText"
|
|
Foreground="{StaticResource InkSoft}"
|
|
TextWrapping="Wrap" FontSize="13"
|
|
Margin="0,4,0,0" />
|
|
<StackPanel x:Name="HostRetryPanel" Visibility="Collapsed"
|
|
Orientation="Horizontal" Margin="0,12,0,0">
|
|
<Button x:Name="HostRetryBtn" Style="{StaticResource PrimaryBtn}"
|
|
Content="Retry" Click="OnHostRetry" />
|
|
<Button Style="{StaticResource GhostBtn}"
|
|
Content="Get help"
|
|
Click="OnOpenTroubleshooting"
|
|
Margin="10,0,0,0" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Join code panel — appears once the host is up.
|
|
QR encodes the same code text; friends can
|
|
scan with a phone to grab it without typing. -->
|
|
<Border x:Name="JoinCodePanel" Visibility="Collapsed"
|
|
Style="{StaticResource Panel}"
|
|
Background="{StaticResource CardBgHost}">
|
|
<StackPanel>
|
|
<TextBlock Style="{StaticResource SectionTitle}"
|
|
Text="🎉 Share this with friends" />
|
|
|
|
<Grid>
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="Auto" />
|
|
<ColumnDefinition Width="*" />
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<Border Grid.Column="0" Background="White"
|
|
CornerRadius="10" Padding="8"
|
|
VerticalAlignment="Top"
|
|
Margin="0,0,16,0">
|
|
<Image x:Name="JoinCodeQrImage"
|
|
Width="180" Height="180"
|
|
RenderOptions.BitmapScalingMode="NearestNeighbor"
|
|
SnapsToDevicePixels="True"
|
|
UseLayoutRounding="True" />
|
|
</Border>
|
|
|
|
<StackPanel Grid.Column="1">
|
|
<TextBlock Style="{StaticResource FieldLabel}"
|
|
Text="JOIN CODE" />
|
|
<Border Background="{StaticResource BgDeeper}"
|
|
BorderBrush="{StaticResource Border}" BorderThickness="1"
|
|
CornerRadius="10" Padding="12,10">
|
|
<TextBox x:Name="JoinCodeText" IsReadOnly="True"
|
|
FontFamily="Cascadia Mono, Consolas" FontSize="12"
|
|
Background="Transparent" BorderThickness="0"
|
|
TextWrapping="Wrap" />
|
|
</Border>
|
|
|
|
<WrapPanel Margin="0,12,0,0">
|
|
<Button Style="{StaticResource PrimaryBtn}"
|
|
Content="Copy code" Click="OnCopyJoinCode" />
|
|
<Button Style="{StaticResource Btn}"
|
|
Content="Copy as message"
|
|
Click="OnCopyJoinCodeMessage"
|
|
Margin="10,0,0,0" />
|
|
<Button Style="{StaticResource Btn}"
|
|
Content="Email to friend"
|
|
Click="OnEmailJoinCode"
|
|
Margin="10,0,0,0" />
|
|
</WrapPanel>
|
|
|
|
<TextBlock Foreground="{StaticResource InkFaint}" FontSize="11"
|
|
TextWrapping="Wrap" Margin="0,12,0,0"
|
|
Text="Your friend opens DorkNet, picks "Join a friend", and pastes the code. The QR encodes the same text — handy for getting it onto a phone for forwarding." />
|
|
</StackPanel>
|
|
</Grid>
|
|
</StackPanel>
|
|
</Border>
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</Grid>
|
|
|
|
<!-- ── Join view ──────────────────────────────────────────── -->
|
|
<Grid x:Name="JoinView" Visibility="Collapsed">
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto" />
|
|
<RowDefinition Height="*" />
|
|
</Grid.RowDefinitions>
|
|
|
|
<Grid Grid.Row="0" Margin="0,0,0,28">
|
|
<StackPanel Orientation="Horizontal">
|
|
<TextBlock Text="DorkNet" FontSize="22" FontWeight="Bold"
|
|
Foreground="{StaticResource WordmarkBrush}" />
|
|
<Border Style="{StaticResource StatusChip}" Margin="14,0,0,0"
|
|
VerticalAlignment="Center">
|
|
<TextBlock Text="JOIN MODE" FontSize="10"
|
|
FontWeight="Bold" Foreground="{StaticResource Teal}" />
|
|
</Border>
|
|
</StackPanel>
|
|
<Button HorizontalAlignment="Right" Style="{StaticResource GhostBtn}"
|
|
Content="Settings" Click="OnOpenSettings" />
|
|
</Grid>
|
|
|
|
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto"
|
|
Padding="0,0,8,0">
|
|
<StackPanel>
|
|
<Border Style="{StaticResource Panel}" Margin="0,0,0,16">
|
|
<StackPanel>
|
|
<TextBlock Style="{StaticResource SectionTitle}" Text="Join code" />
|
|
|
|
<TextBlock Style="{StaticResource FieldLabel}"
|
|
Text="PASTE THE JOIN CODE YOUR HOST SHARED" />
|
|
<TextBox x:Name="JoinCodeInput"
|
|
AcceptsReturn="True" TextWrapping="Wrap"
|
|
Height="80" VerticalContentAlignment="Top"
|
|
FontFamily="Cascadia Mono, Consolas" FontSize="12"
|
|
TextChanged="OnJoinCodeInputChanged" />
|
|
<Button Style="{StaticResource Btn}"
|
|
Content="Preview" Click="OnDecodeJoinCode"
|
|
HorizontalAlignment="Left" Margin="0,10,0,0" />
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<Border x:Name="JoinPreviewBorder" Visibility="Collapsed"
|
|
Style="{StaticResource Panel}"
|
|
Background="{StaticResource CardBgJoin}"
|
|
Margin="0,0,0,16">
|
|
<StackPanel>
|
|
<TextBlock Style="{StaticResource SectionTitle}" Text="Server preview" />
|
|
<TextBlock x:Name="JoinPreviewText"
|
|
Foreground="{StaticResource Ink}"
|
|
TextWrapping="Wrap" FontSize="14" />
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<Border Style="{StaticResource Panel}" Margin="0,0,0,16">
|
|
<StackPanel>
|
|
<TextBlock Style="{StaticResource SectionTitle}" Text="Your Rec Room install" />
|
|
<TextBlock Style="{StaticResource FieldLabel}" Text="LOCATION" />
|
|
<DockPanel>
|
|
<Button DockPanel.Dock="Right" Style="{StaticResource Btn}"
|
|
Content="Pick…" Click="OnPickRecRoom" Margin="8,0,0,0" />
|
|
<Border Background="{StaticResource BgDeeper}"
|
|
BorderBrush="{StaticResource BorderSoft}" BorderThickness="1"
|
|
CornerRadius="10" Padding="12,10">
|
|
<TextBlock x:Name="JoinRecRoomPath"
|
|
Text="(not picked)"
|
|
Foreground="{StaticResource InkSoft}"
|
|
TextTrimming="CharacterEllipsis" FontSize="13" />
|
|
</Border>
|
|
</DockPanel>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<StackPanel Orientation="Horizontal" Margin="0,4,0,16">
|
|
<Button x:Name="JoinApplyBtn" Style="{StaticResource PrimaryBtn}"
|
|
Content="Patch" Click="OnJoinApply"
|
|
IsEnabled="False" />
|
|
<Button x:Name="JoinLaunchBtn" Style="{StaticResource TealBtn}"
|
|
Content="Launch Rec Room" Click="OnLaunchRecRoom"
|
|
Margin="10,0,0,0" Visibility="Collapsed" />
|
|
</StackPanel>
|
|
|
|
<Border x:Name="JoinStepsPanel" Style="{StaticResource Panel}"
|
|
Visibility="Collapsed">
|
|
<StackPanel>
|
|
<TextBlock Style="{StaticResource SectionTitle}" Text="Progress" />
|
|
<ItemsControl x:Name="JoinStepsList"
|
|
ItemTemplate="{StaticResource StepRowTemplate}" />
|
|
<TextBlock x:Name="JoinStatusText"
|
|
Foreground="{StaticResource InkSoft}"
|
|
TextWrapping="Wrap" FontSize="13"
|
|
Margin="0,4,0,0" />
|
|
<StackPanel x:Name="JoinRetryPanel" Visibility="Collapsed"
|
|
Orientation="Horizontal" Margin="0,12,0,0">
|
|
<Button x:Name="JoinRetryBtn" Style="{StaticResource PrimaryBtn}"
|
|
Content="Retry" Click="OnJoinRetry" />
|
|
<Button Style="{StaticResource GhostBtn}"
|
|
Content="Get help"
|
|
Click="OnOpenTroubleshooting"
|
|
Margin="10,0,0,0" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</Border>
|
|
</StackPanel>
|
|
</ScrollViewer>
|
|
</Grid>
|
|
|
|
<!-- ── Settings view ──────────────────────────────────────── -->
|
|
<Grid x:Name="SettingsView" Visibility="Collapsed">
|
|
<Grid.RowDefinitions>
|
|
<RowDefinition Height="Auto" />
|
|
<RowDefinition Height="*" />
|
|
</Grid.RowDefinitions>
|
|
|
|
<Grid Grid.Row="0" Margin="0,0,0,28">
|
|
<StackPanel Orientation="Horizontal">
|
|
<TextBlock Text="DorkNet" FontSize="22" FontWeight="Bold"
|
|
Foreground="{StaticResource WordmarkBrush}" />
|
|
<Border Style="{StaticResource StatusChip}" Margin="14,0,0,0"
|
|
VerticalAlignment="Center">
|
|
<TextBlock Text="SETTINGS" FontSize="10"
|
|
FontWeight="Bold" Foreground="{StaticResource Sunshine}" />
|
|
</Border>
|
|
</StackPanel>
|
|
<Button HorizontalAlignment="Right" Style="{StaticResource GhostBtn}"
|
|
Content="← Back" Click="OnBackFromSettings" />
|
|
</Grid>
|
|
|
|
<StackPanel Grid.Row="1">
|
|
<Border Style="{StaticResource Panel}" Margin="0,0,0,16">
|
|
<StackPanel>
|
|
<TextBlock Style="{StaticResource SectionTitle}" Text="Switch mode" />
|
|
<StackPanel Orientation="Horizontal">
|
|
<Button Style="{StaticResource Btn}"
|
|
Content="Host" Click="OnPickHost" />
|
|
<Button Style="{StaticResource Btn}"
|
|
Content="Join" Click="OnPickJoin"
|
|
Margin="10,0,0,0" />
|
|
<Button Style="{StaticResource GhostBtn}"
|
|
Content="Re-run setup" Click="OnRerunSetup"
|
|
Margin="10,0,0,0" />
|
|
</StackPanel>
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<Border Style="{StaticResource Panel}" Margin="0,0,0,16">
|
|
<StackPanel>
|
|
<TextBlock Style="{StaticResource SectionTitle}" Text="Cache locations" />
|
|
<TextBlock x:Name="CachePathsText"
|
|
Foreground="{StaticResource InkSoft}"
|
|
FontSize="12" TextWrapping="Wrap"
|
|
FontFamily="Cascadia Mono, Consolas" />
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<!-- Dev-mode overrides — visible only when at least one
|
|
env var is set so end users never see it. -->
|
|
<Border x:Name="LocalOverridesPanel" Visibility="Collapsed"
|
|
Style="{StaticResource Panel}" Margin="0,0,0,16"
|
|
Background="{StaticResource CardBgHost}">
|
|
<StackPanel>
|
|
<TextBlock Style="{StaticResource SectionTitle}"
|
|
Text="🛠 Dev overrides active" />
|
|
<TextBlock Foreground="{StaticResource InkSoft}" FontSize="12"
|
|
Margin="0,-6,0,8" TextWrapping="Wrap"
|
|
Text="The launcher is reading from local paths instead of GitHub. Unset DORKNET_LOCAL_MANIFEST / DORKNET_LOCAL_RELEASES to return to normal mode." />
|
|
<TextBlock x:Name="LocalOverridesText"
|
|
Foreground="{StaticResource Ink}"
|
|
FontSize="12" TextWrapping="Wrap"
|
|
FontFamily="Cascadia Mono, Consolas" />
|
|
</StackPanel>
|
|
</Border>
|
|
|
|
<Border Style="{StaticResource Panel}">
|
|
<StackPanel>
|
|
<TextBlock Style="{StaticResource SectionTitle}" Text="About" />
|
|
<TextBlock Foreground="{StaticResource InkSoft}" FontSize="13">
|
|
DorkNet Launcher v0.1 ·
|
|
<Hyperlink NavigateUri="https://github.com/DorkSquadRR/DorkNet"
|
|
Foreground="{StaticResource Brand}"
|
|
RequestNavigate="OnNavigate">github.com/DorkSquadRR/DorkNet</Hyperlink>
|
|
· AGPL-3.0
|
|
</TextBlock>
|
|
<TextBlock Foreground="{StaticResource InkFaint}" FontSize="11"
|
|
Margin="0,8,0,0">
|
|
Not affiliated with Rec Room Inc. or Against Gravity.
|
|
</TextBlock>
|
|
</StackPanel>
|
|
</Border>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Grid>
|
|
</Grid>
|
|
</Window>
|