Add project files.

This commit is contained in:
nebula 2025-05-08 22:16:00 -05:00
parent 1308560b90
commit f0eee5fd98
70 changed files with 755 additions and 0 deletions

16
App.xaml Normal file
View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Application
x:Class="wakka.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:wakka">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- Other merged dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Other app resources here -->
</ResourceDictionary>
</Application.Resources>
</Application>

35
App.xaml.cs Normal file
View File

@ -0,0 +1,35 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using System.IO;
using WinUIEx;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace wakka
{
public partial class App : Application
{
public Window m_window;
public readonly static Windows.Storage.ApplicationDataContainer LocalSettingsData =
Windows.Storage.ApplicationData.Current.LocalSettings;
public readonly static Windows.Storage.StorageFolder LocalStroageData =
Windows.Storage.ApplicationData.Current.LocalFolder;
public App()
{
this.InitializeComponent();
}
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
m_window = new MainWindow();
m_window.SetWindowSize(width: 800, height: 600);
m_window.CenterOnScreen();
m_window.Activate();
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 891 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
Assets/StoreLogo.backup.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

44
Bink.cs Normal file
View File

@ -0,0 +1,44 @@
using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace wakka
{
public class BinkPost
{
[JsonPropertyName("user")]
public string? User { get; set; }
[JsonPropertyName("body")]
public string? Body { get; set; }
[JsonPropertyName("time")]
public long Time { get; set; }
public string TimeString { get; set; } = string.Empty;
}
public class Bink
{
private static SshConnection Ssh { get; set; } = new SshConnection();
public string RunBinkCommand(string command)
{
return Ssh.RunCommand($"town bink --{command}");
}
public List<BinkPost>? AllBinks()
{
return JsonSerializer.Deserialize<List<BinkPost>>(RunBinkCommand("dump"));
}
public List<BinkPost>? BinksBefore(long TimeStamp)
{
return JsonSerializer.Deserialize<List<BinkPost>>(RunBinkCommand("dump-before"));
}
public List<BinkPost>? BinksAfter(long TimeStamp)
{
return JsonSerializer.Deserialize<List<BinkPost>>(RunBinkCommand("dump-after"));
}
}
}

65
BinkPage.xaml Normal file
View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<Page
x:Class="wakka.BinkPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:wakka"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<CommandBar DefaultLabelPosition="Right" Grid.Row="0">
<AppBarButton Icon="Add" Label="Post" />
</CommandBar>
<ListView x:Name="binksListView" SelectionMode="None" Padding="5,10,5,10" Grid.Row="1">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:BinkPost">
<StackPanel MaxWidth="1000" CornerRadius="8" Padding="10,10,10,10" Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}" Margin="0,0,0,20">
<StackPanel Orientation="Horizontal">
<TextBlock Text="~"/>
<TextBlock Text="{x:Bind User}"/>
<TextBlock Margin="10,0,0,0" Foreground="{ThemeResource TextFillColorTertiaryBrush}" Text="{x:Bind TimeString}"/>
</StackPanel>
<TextBlock Margin="5,5,0,0" Text="{x:Bind Body}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>
<!--<Page
x:Class="wakka.BinkPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:wakka"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<CommandBar Background="Transparent" IsOpen="False" DefaultLabelPosition="Right">
<AppBarButton Icon="Add" Label="Post"/>
</CommandBar>
<ListView x:Name="binksListView" SelectionMode="None" Padding="5,10,5,10">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:BinkPost">
<StackPanel Padding="10,10,10,10" Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}" Margin="0,0,0,20">
<StackPanel Orientation="Horizontal">
<TextBlock Text="~"/>
<TextBlock Text="{x:Bind User}"/>
<TextBlock Margin="10,0,0,0" Foreground="{ThemeResource TextFillColorTertiaryBrush}" Text="{x:Bind TimeString}"/>
</StackPanel>
<TextBlock Margin="5,5,0,0" Text="{x:Bind Body}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Page>-->

47
BinkPage.xaml.cs Normal file
View File

@ -0,0 +1,47 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace wakka
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class BinkPage : Page
{
private readonly ObservableCollection<BinkPost> Binks = [];
private static SshConnection Ssh { get; set; } = new SshConnection();
public BinkPage()
{
this.InitializeComponent();
var Bink = new Bink();
var BinkList = Bink.AllBinks();
if (BinkList != null)
{
foreach (var bink in BinkList)
{
var date = DateTimeOffset.FromUnixTimeSeconds(bink.Time / 1000000000).DateTime.ToLocalTime();
bink.TimeString = date.ToString("HH:mm (dddd, MMMM dd, yyyy)");
Binks.Add(bink);
}
}
binksListView.ItemsSource = Binks;
}
}
}

14
MainWindow.xaml Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="wakka.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:wakka"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="wakka">
<Frame x:Name="rootFrame"/>
</Window>

55
MainWindow.xaml.cs Normal file
View File

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using Windows.Foundation;
using Windows.Foundation.Collections;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace wakka
{
/// <summary>
/// An empty window that can be used on its own or navigated to within a Frame.
/// </summary>
///
public sealed partial class MainWindow : Window
{
private static SshConnection Ssh { get; set; } = new SshConnection();
public Frame RootFrame;
public MainWindow()
{
this.InitializeComponent();
this.AppWindow.MoveAndResize(new Windows.Graphics.RectInt32(100, 100, 854, 480));
Ssh.DeleteSshKey();
RootFrame = rootFrame;
if (Ssh.KeyExists() & (string)App.LocalSettingsData.Values["username"] != null)
{
Ssh.InitializeConnection((string)App.LocalSettingsData.Values["username"]);
RootFrame.Content = new NavigationPage();
}
else
{
RootFrame.Content = new StartupSshPage();
}
}
//private void myButton_Click(object sender, RoutedEventArgs e)
//{
// myButton.Content = "Clicked";
//}
}
}

20
NavigationPage.xaml Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Page
x:Class="wakka.NavigationPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:wakka"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<NavigationView x:Name="navigationView" OpenPaneLength="200" IsPaneOpen="False">
<NavigationView.MenuItems>
<NavigationViewItem Icon="World" IsSelected="True" Content="Bink" x:Name="binkPageNav" />
<NavigationViewItem Icon="Comment" IsSelected="False" Content="BBJ" />
<NavigationViewItem Icon="Library" IsSelected="False" Content="Feels" />
</NavigationView.MenuItems>
<Frame x:Name="navigationFrame"/>
</NavigationView>
</Page>

32
NavigationPage.xaml.cs Normal file
View File

@ -0,0 +1,32 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Data;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Navigation;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace wakka
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class NavigationPage : Page
{
public NavigationPage()
{
this.InitializeComponent();
navigationFrame.Content = new BinkPage();
}
}
}

51
Package.appxmanifest Normal file
View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity
Name="8edc9fec-3276-4986-bbf6-5074643d2fdc"
Publisher="CN=helix"
Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="8edc9fec-3276-4986-bbf6-5074643d2fdc" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>wakka</DisplayName>
<PublisherDisplayName>helix</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="wakka"
Description="wakka"
BackgroundColor="transparent"
Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square71x71Logo="Assets\SmallTile.png" Square310x310Logo="Assets\LargeTile.png"/>
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

View File

@ -0,0 +1,10 @@
{
"profiles": {
"wakka (Package)": {
"commandName": "MsixPackage"
},
"wakka (Unpackaged)": {
"commandName": "Project"
}
}
}

76
SshConnection.cs Normal file
View File

@ -0,0 +1,76 @@
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using Renci.SshNet;
using Renci.SshNet.Common;
using System;
using System.IO;
namespace wakka
{
public class SshConnection
{
public static string User { get; set; } = string.Empty;
public static SshClient? Client { get; set; } = null;
public readonly static string SshKeyPath = Path.Combine(App.LocalStroageData.Path, "key");
public static PrivateKeyFile? Key { get; set; } = null;
public static string? PublicKey { get; set; } = null;
public bool KeyExists() => File.Exists(SshKeyPath);
public void InitializeConnection(string user)
{
if (!File.Exists(SshKeyPath) || user == string.Empty)
{
throw new InvalidOperationException("No SSH key or user is empty");
}
else
{
User = user;
Key = new PrivateKeyFile(SshKeyPath);
Client = new SshClient("tilde.town", User, Key);
try
{
Client.Connect();
}
catch (SshAuthenticationException)
{
Key = null;
throw;
}
}
}
public string RunCommand(string command)
{
if (Client == null || !Client.IsConnected)
{
throw new InvalidOperationException("SSH client is not connected.");
}
var rc = Client.RunCommand(command);
return rc.Result;
}
public string CreateSshKey()
{
var keygen = new SshKeyGenerator.SshKeyGenerator(2048);
var privateKey = keygen.ToPrivateKey();
File.WriteAllText(SshKeyPath, privateKey);
return keygen.ToRfcPublicKey("wakka");
}
public void DeleteSshKey()
{
if (File.Exists(SshKeyPath))
{
File.Delete(SshKeyPath);
}
}
}
}

26
StartupSshPage.xaml Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<Page
x:Class="wakka.StartupSshPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:wakka"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid MaxWidth="400" HorizontalAlignment="Center" CornerRadius="8" VerticalAlignment="Center" Background="{ThemeResource CardBackgroundFillColorSecondaryBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Margin="20,20,20,0" Source="/Assets/StoreLogo.png" />
<TextBlock FontSize="20" Grid.Row="1" Margin="20,5,20,0" VerticalAlignment="Center" HorizontalAlignment="Center" Text="wakka"/>
<TextBox Width="200" Grid.Row="2" Margin="20,20,20,20" x:Name="usernameTextBox" TextChanged="OnTextChanged" PlaceholderText="Username..."/>
<Button Width="200" Grid.Row="3" Margin="20,0,20,20" x:Name="sshKeySelectButton" Content="Select Private Key File" Click="SelectPrivateKey"/>
<Button Width="200" Grid.Row="4" Margin="20,0,20,20" x:Name="sshKeyCreateButton" Content="Create New Key" Click="CreateSshKey"/>
<Button Width="200" Grid.Row="5" Margin="20,0,20,20" x:Name="sshConnectButton" Click="AttemptConnection" Content="Connect"/>
</Grid>
</Page>

122
StartupSshPage.xaml.cs Normal file
View File

@ -0,0 +1,122 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Renci.SshNet.Common;
using System;
using System.Threading.Tasks;
using Windows.ApplicationModel.DataTransfer;
using Windows.Storage;
using Windows.Storage.Pickers;
using WinRT.Interop;
using static System.Net.Mime.MediaTypeNames;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace wakka
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class StartupSshPage : Page
{
private static SshConnection Ssh { get; set; } = new SshConnection();
public StartupSshPage()
{
this.InitializeComponent();
string? userName = (string)App.LocalSettingsData.Values["username"];
if (userName == null || userName.Trim() == string.Empty)
{
sshConnectButton.IsEnabled = false;
}
else
{
usernameTextBox.Text = (string)App.LocalSettingsData.Values["username"];
}
if (Ssh.KeyExists())
{
sshKeySelectButton.Content = "SSH Key Set!";
//sshKeySelectButton.Click = Sele
}
}
private async void SelectPrivateKey(object sender, RoutedEventArgs e)
{
var picker = new FileOpenPicker();
picker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
picker.FileTypeFilter.Add("*");
picker.ViewMode = PickerViewMode.List;
var currentWindow = (App.Current as App)?.m_window;
if (currentWindow != null)
{
InitializeWithWindow.Initialize(picker, WindowNative.GetWindowHandle(currentWindow));
StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
var SourcePath = file.Path;
var DestinationPath = SshConnection.SshKeyPath;
await file.CopyAsync(App.LocalStroageData, "key", NameCollisionOption.ReplaceExisting);
sshKeySelectButton.Content = "SSH Key Set!";
}
}
}
private void CreateSshKey(object sender, RoutedEventArgs e)
{
var publicKey = Ssh.CreateSshKey();
if (publicKey != null)
{
var dataPackage = new DataPackage();
dataPackage.SetText(publicKey);
Clipboard.SetContent(dataPackage);
sshKeyCreateButton.Content = "Public key copied!";
}
}
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
App.LocalSettingsData.Values["username"] = usernameTextBox.Text;
if (usernameTextBox.Text.Trim() == string.Empty)
{
sshConnectButton.IsEnabled = false;
}
else
{
sshConnectButton.IsEnabled = true;
}
}
private async void DisplayConnectionErrorDialog ()
{
var dialog = new ContentDialog
{
Title = "SSH Authentication Error",
Content = "Username or SSH key are incorrect.",
CloseButtonText = "Close"
};
dialog.XamlRoot = this.XamlRoot;
await dialog.ShowAsync();
}
private void AttemptConnection(object sender, RoutedEventArgs e)
{
try
{
Ssh.InitializeConnection((string)App.LocalSettingsData.Values["username"]);
var mainWindow = (App.Current as App)?.m_window;
if (mainWindow != null)
{
mainWindow.Content = new NavigationPage();
}
}
catch (SshAuthenticationException)
{
sshKeySelectButton.Content = "Select New SSH Key";
DisplayConnectionErrorDialog();
}
}
}
}

Binary file not shown.

19
app.manifest Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="wakka.app"/>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- The ID below informs the system that this application is compatible with OS features first introduced in Windows 10.
It is necessary to support features in unpackaged applications, for example the custom titlebar implementation.
For more info see https://docs.microsoft.com/windows/apps/windows-app-sdk/use-windows-app-sdk-run-time#declare-os-compatibility-in-your-application-manifest -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>
</assembly>

80
wakka.csproj Normal file
View File

@ -0,0 +1,80 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<RootNamespace>wakka</RootNamespace>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>x86;x64;ARM64</Platforms>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
<PublishProfile>win-$(Platform).pubxml</PublishProfile>
<UseWinUI>true</UseWinUI>
<EnableMsixTooling>true</EnableMsixTooling>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Remove="BinkPage.xaml" />
<None Remove="NavigationPage.xaml" />
</ItemGroup>
<ItemGroup>
<Content Include="Assets\SplashScreen.scale-200.png" />
<Content Include="Assets\LockScreenLogo.scale-200.png" />
<Content Include="Assets\Square150x150Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<ItemGroup>
<Manifest Include="$(ApplicationManifest)" />
</ItemGroup>
<!--
Defining the "Msix" ProjectCapability here allows the Single-project MSIX Packaging
Tools extension to be activated for this project even if the Windows App SDK Nuget
package has not yet been restored.
-->
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
<ProjectCapability Include="Msix" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.3916" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250401001" />
<PackageReference Include="SSH.NET" Version="2025.0.0" />
<PackageReference Include="SshKeyGenerator" Version="1.1.51" />
<PackageReference Include="WinUIEx" Version="2.5.1" />
</ItemGroup>
<ItemGroup>
<Page Update="NavigationPage.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="StartupSshPage.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="BinkPage.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<!--
Defining the "HasPackageAndPublishMenuAddedByProject" property here allows the Solution
Explorer "Package and Publish" context menu entry to be enabled for this project even if
the Windows App SDK Nuget package has not yet been restored.
-->
<PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
<HasPackageAndPublishMenu>true</HasPackageAndPublishMenu>
</PropertyGroup>
<!-- Publish Properties -->
<PropertyGroup>
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
<PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
<PublishTrimmed Condition="'$(Configuration)' == 'Debug'">False</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed>
</PropertyGroup>
</Project>

43
wakka.sln Normal file
View File

@ -0,0 +1,43 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35931.197 d17.13
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wakka", "wakka.csproj", "{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Debug|ARM64.ActiveCfg = Debug|ARM64
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Debug|ARM64.Build.0 = Debug|ARM64
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Debug|ARM64.Deploy.0 = Debug|ARM64
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Debug|x64.ActiveCfg = Debug|x64
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Debug|x64.Build.0 = Debug|x64
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Debug|x64.Deploy.0 = Debug|x64
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Debug|x86.ActiveCfg = Debug|x86
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Debug|x86.Build.0 = Debug|x86
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Debug|x86.Deploy.0 = Debug|x86
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Release|ARM64.ActiveCfg = Release|ARM64
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Release|ARM64.Build.0 = Release|ARM64
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Release|ARM64.Deploy.0 = Release|ARM64
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Release|x64.ActiveCfg = Release|x64
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Release|x64.Build.0 = Release|x64
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Release|x64.Deploy.0 = Release|x64
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Release|x86.ActiveCfg = Release|x86
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Release|x86.Build.0 = Release|x86
{76B27B27-FF94-4A02-8BC3-56A3AFCE40B5}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E3A4A5CF-C10B-44EA-A3FB-E4D7046D0EE3}
EndGlobalSection
EndGlobal