mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-26 07:28:45 -07:00
3039bebc6c
The single HostStatusText/JoinStatusText line gave no sense of where the user was in the flow. Replaced with a step list: - StartupStep model (INotifyPropertyChanged) tracks Title, State (Pending/Active/Done/Failed), Detail, optional Progress 0..1 - ItemsControl + DataTemplate in App.xaml renders each step as a status bullet (empty ring -> filled brand -> green check -> red X), with conditional detail line + restyled mini progress bar - StartupFlow.NewHostFlow / NewJoinFlow build the canonical 5-step host and 2-step join lists; host flow swaps the tunnel step label for LocalNetwork mode - OnHostStart / OnJoinApply advance steps via StartStep/CompleteStep/ FailStep helpers and route progress callbacks to UpdateStepProgress so each download phase has its own bar - Errors mark the active step Failed with the message inline, leaving the rest of the list visible so the user sees where it broke
429 lines
26 KiB
XML
429 lines
26 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. -->
|
|
|
|
<!-- ── First-run wizard ───────────────────────────────────── -->
|
|
<StackPanel x:Name="FirstRunView" Visibility="Visible"
|
|
VerticalAlignment="Center">
|
|
<StackPanel HorizontalAlignment="Center" Margin="0,0,0,40">
|
|
<TextBlock Text="DorkNet"
|
|
FontSize="56" 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 InkSoft}"
|
|
FontSize="16"
|
|
HorizontalAlignment="Center" Margin="0,6,0,0" />
|
|
</StackPanel>
|
|
|
|
<Grid Margin="40,0" MaxWidth="780" HorizontalAlignment="Center">
|
|
<Grid.ColumnDefinitions>
|
|
<ColumnDefinition Width="*" />
|
|
<ColumnDefinition Width="20" />
|
|
<ColumnDefinition Width="*" />
|
|
</Grid.ColumnDefinitions>
|
|
|
|
<Button Grid.Column="0" Style="{StaticResource ChoiceCardBtn}"
|
|
Background="{StaticResource CardBgHost}"
|
|
Click="OnPickHost">
|
|
<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. Pick a Rec Room version, the launcher downloads the matching server, opens a tunnel, and hands you a shareable join code." />
|
|
<Border Margin="0,18,0,0" CornerRadius="8"
|
|
Background="{StaticResource Brand}" Padding="14,8"
|
|
HorizontalAlignment="Left">
|
|
<TextBlock Text="Get started →" Foreground="White"
|
|
FontWeight="SemiBold" FontSize="13" />
|
|
</Border>
|
|
</StackPanel>
|
|
</Button>
|
|
|
|
<Button Grid.Column="2" Style="{StaticResource ChoiceCardBtn}"
|
|
Background="{StaticResource CardBgJoin}"
|
|
Click="OnPickJoin">
|
|
<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="Paste a join code from your host, point at your Rec Room install. The launcher fetches the matching patcher and gets you connected." />
|
|
<Border Margin="0,18,0,0" CornerRadius="8"
|
|
Background="{StaticResource Teal}" Padding="14,8"
|
|
HorizontalAlignment="Left">
|
|
<TextBlock Text="Get started →" Foreground="#0E0A1F"
|
|
FontWeight="SemiBold" FontSize="13" />
|
|
</Border>
|
|
</StackPanel>
|
|
</Button>
|
|
</Grid>
|
|
|
|
<TextBlock Text="You can switch modes anytime under Settings."
|
|
HorizontalAlignment="Center"
|
|
Foreground="{StaticResource InkFaint}"
|
|
FontSize="12" Margin="0,32,0,0" />
|
|
</StackPanel>
|
|
|
|
<!-- ── 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>
|
|
<TextBlock Style="{StaticResource SectionTitle}" Text="Photon AppIds" />
|
|
<TextBlock Foreground="{StaticResource InkSoft}" FontSize="12"
|
|
Margin="0,-8,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.
|
|
</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>
|
|
</Border>
|
|
|
|
<!-- Join code -->
|
|
<Border x:Name="JoinCodePanel" Visibility="Collapsed"
|
|
Style="{StaticResource Panel}"
|
|
Background="{StaticResource CardBgHost}">
|
|
<StackPanel>
|
|
<TextBlock Style="{StaticResource SectionTitle}"
|
|
Text="🎉 Share this with friends" />
|
|
<DockPanel>
|
|
<Button DockPanel.Dock="Right" Style="{StaticResource PrimaryBtn}"
|
|
Content="Copy" Click="OnCopyJoinCode" Margin="10,0,0,0" />
|
|
<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>
|
|
</DockPanel>
|
|
<TextBlock Foreground="{StaticResource InkFaint}" FontSize="11"
|
|
Text="Paste this in their DorkNet launcher's Join screen."
|
|
Margin="0,8,0,0" />
|
|
</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>
|
|
</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" />
|
|
</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>
|
|
|
|
<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>
|