Add Quick Setup Qr Code

This commit is contained in:
Manuel Mayer
2024-05-10 11:22:02 +02:00
parent e285edf32b
commit b0fc380dfa
7 changed files with 227 additions and 154 deletions

View File

@@ -12,6 +12,7 @@
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageVersion Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="QRCoder" Version="1.5.1" />
<PackageVersion Include="sqlite-net-pcl" Version="1.8.116" />
<PackageVersion Include="System.Collections" Version="4.3.0" />
<PackageVersion Include="System.Drawing.Common" Version="8.0.4" />

View File

@@ -0,0 +1,20 @@
namespace SuchByte.MacroDeck.DataTypes.QrCode;
public class QuickConnectQrCodeData
{
public string InstanceName { get; set; }
public List<string> NetworkInterfaces { get; set; }
public int Port { get; set; }
public bool Ssl { get; set; }
public QuickConnectQrCodeData(string instanceName, List<string> networkInterfaces, int port, bool ssl)
{
InstanceName = instanceName;
NetworkInterfaces = networkInterfaces;
Port = port;
Ssl = ssl;
}
}

View File

@@ -59,6 +59,7 @@ namespace SuchByte.MacroDeck.GUI
lblVersion = new Label();
contentPanel = new BufferedPanel();
contentButtonPanel = new FlowLayoutPanel();
btnNotifications = new NotificationButton();
btnDeck = new ContentSelectorButton();
panel1 = new Panel();
btnExtensions = new ContentSelectorButton();
@@ -67,12 +68,9 @@ namespace SuchByte.MacroDeck.GUI
panel2 = new Panel();
btnSettings = new ContentSelectorButton();
lblNumClientsConnected = new Label();
label1 = new Label();
lblPort = new Label();
lblIpAddressHostname = new Label();
navigation = new RoundedPanel();
btnNotifications = new NotificationButton();
hosts = new RoundedComboBox();
qrCodeBox = new PictureBox();
label1 = new Label();
contentButtonPanel.SuspendLayout();
((ISupportInitialize)btnDeck).BeginInit();
((ISupportInitialize)btnExtensions).BeginInit();
@@ -80,6 +78,7 @@ namespace SuchByte.MacroDeck.GUI
((ISupportInitialize)btnVariables).BeginInit();
((ISupportInitialize)btnSettings).BeginInit();
navigation.SuspendLayout();
((ISupportInitialize)qrCodeBox).BeginInit();
SuspendLayout();
//
// lblSafeMode
@@ -89,29 +88,31 @@ namespace SuchByte.MacroDeck.GUI
//
// lblVersion
//
lblVersion.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
lblVersion.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
lblVersion.Font = new Font("Tahoma", 8.25F, FontStyle.Regular, GraphicsUnit.Point, 0);
lblVersion.ForeColor = Color.White;
lblVersion.Location = new Point(2, 603);
lblVersion.Location = new Point(1046, 613);
lblVersion.Margin = new Padding(9, 0, 9, 0);
lblVersion.Name = "lblVersion";
lblVersion.Size = new Size(328, 30);
lblVersion.Size = new Size(154, 20);
lblVersion.TabIndex = 3;
lblVersion.Text = "2.0.0";
lblVersion.TextAlign = ContentAlignment.MiddleLeft;
lblVersion.TextAlign = ContentAlignment.MiddleRight;
lblVersion.UseMnemonic = false;
//
// contentPanel
//
contentPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
contentPanel.Location = new Point(69, 94);
contentPanel.Location = new Point(65, 42);
contentPanel.Margin = new Padding(9, 4, 9, 4);
contentPanel.Name = "contentPanel";
contentPanel.Size = new Size(1131, 509);
contentPanel.Size = new Size(981, 591);
contentPanel.TabIndex = 4;
//
// contentButtonPanel
//
contentButtonPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
contentButtonPanel.Controls.Add(btnNotifications);
contentButtonPanel.Controls.Add(btnDeck);
contentButtonPanel.Controls.Add(panel1);
contentButtonPanel.Controls.Add(btnExtensions);
@@ -119,21 +120,45 @@ namespace SuchByte.MacroDeck.GUI
contentButtonPanel.Controls.Add(btnVariables);
contentButtonPanel.Controls.Add(panel2);
contentButtonPanel.FlowDirection = FlowDirection.TopDown;
contentButtonPanel.Location = new Point(8, 9);
contentButtonPanel.Location = new Point(8, 7);
contentButtonPanel.Margin = new Padding(0);
contentButtonPanel.Name = "contentButtonPanel";
contentButtonPanel.Size = new Size(45, 470);
contentButtonPanel.Size = new Size(45, 528);
contentButtonPanel.TabIndex = 5;
//
// btnNotifications
//
btnNotifications.BorderRadius = 8;
btnNotifications.Cursor = Cursors.Hand;
btnNotifications.FlatAppearance.BorderSize = 0;
btnNotifications.FlatStyle = FlatStyle.Flat;
btnNotifications.Font = new Font("Tahoma", 8F);
btnNotifications.ForeColor = Color.White;
btnNotifications.HoverColor = Color.Empty;
btnNotifications.Icon = Properties.Resources.Bell;
btnNotifications.Location = new Point(0, 4);
btnNotifications.Margin = new Padding(0, 4, 0, 4);
btnNotifications.Name = "btnNotifications";
btnNotifications.NotificationCount = 0;
btnNotifications.Progress = 0;
btnNotifications.ProgressColor = Color.FromArgb(0, 103, 205);
btnNotifications.Size = new Size(44, 44);
btnNotifications.TabIndex = 16;
btnNotifications.UseVisualStyleBackColor = true;
btnNotifications.UseWindowsAccentColor = false;
btnNotifications.Visible = false;
btnNotifications.WriteProgress = true;
btnNotifications.Click += BtnNotifications_Click;
//
// btnDeck
//
btnDeck.BackColor = Color.Transparent;
btnDeck.BackgroundImage = Properties.Resources.deck;
btnDeck.BackgroundImageLayout = ImageLayout.Stretch;
btnDeck.Cursor = Cursors.Hand;
btnDeck.Font = new Font("Tahoma", 9.75F, FontStyle.Regular, GraphicsUnit.Point);
btnDeck.Font = new Font("Tahoma", 9.75F);
btnDeck.ForeColor = Color.White;
btnDeck.Location = new Point(0, 0);
btnDeck.Location = new Point(0, 52);
btnDeck.Margin = new Padding(0, 0, 0, 6);
btnDeck.Name = "btnDeck";
btnDeck.Selected = false;
@@ -145,7 +170,7 @@ namespace SuchByte.MacroDeck.GUI
// panel1
//
panel1.BackColor = Color.Silver;
panel1.Location = new Point(0, 54);
panel1.Location = new Point(0, 106);
panel1.Margin = new Padding(0, 4, 0, 4);
panel1.Name = "panel1";
panel1.Size = new Size(66, 3);
@@ -157,9 +182,9 @@ namespace SuchByte.MacroDeck.GUI
btnExtensions.BackgroundImage = Properties.Resources.Package_Manager_icon;
btnExtensions.BackgroundImageLayout = ImageLayout.Stretch;
btnExtensions.Cursor = Cursors.Hand;
btnExtensions.Font = new Font("Tahoma", 9.75F, FontStyle.Regular, GraphicsUnit.Point);
btnExtensions.Font = new Font("Tahoma", 9.75F);
btnExtensions.ForeColor = Color.White;
btnExtensions.Location = new Point(0, 67);
btnExtensions.Location = new Point(0, 119);
btnExtensions.Margin = new Padding(0, 6, 0, 6);
btnExtensions.Name = "btnExtensions";
btnExtensions.Selected = false;
@@ -174,9 +199,9 @@ namespace SuchByte.MacroDeck.GUI
btnDeviceManager.BackgroundImage = Properties.Resources.device_manager;
btnDeviceManager.BackgroundImageLayout = ImageLayout.Stretch;
btnDeviceManager.Cursor = Cursors.Hand;
btnDeviceManager.Font = new Font("Tahoma", 9.75F, FontStyle.Regular, GraphicsUnit.Point);
btnDeviceManager.Font = new Font("Tahoma", 9.75F);
btnDeviceManager.ForeColor = Color.White;
btnDeviceManager.Location = new Point(0, 123);
btnDeviceManager.Location = new Point(0, 175);
btnDeviceManager.Margin = new Padding(0, 6, 0, 6);
btnDeviceManager.Name = "btnDeviceManager";
btnDeviceManager.Selected = false;
@@ -191,9 +216,9 @@ namespace SuchByte.MacroDeck.GUI
btnVariables.BackgroundImage = Properties.Resources.variables;
btnVariables.BackgroundImageLayout = ImageLayout.Stretch;
btnVariables.Cursor = Cursors.Hand;
btnVariables.Font = new Font("Tahoma", 12.75F, FontStyle.Regular, GraphicsUnit.Point);
btnVariables.Font = new Font("Tahoma", 12.75F);
btnVariables.ForeColor = Color.White;
btnVariables.Location = new Point(0, 179);
btnVariables.Location = new Point(0, 231);
btnVariables.Margin = new Padding(0, 6, 0, 6);
btnVariables.Name = "btnVariables";
btnVariables.Selected = false;
@@ -206,7 +231,7 @@ namespace SuchByte.MacroDeck.GUI
// panel2
//
panel2.BackColor = Color.Silver;
panel2.Location = new Point(0, 233);
panel2.Location = new Point(0, 285);
panel2.Margin = new Padding(0, 4, 0, 4);
panel2.Name = "panel2";
panel2.Size = new Size(66, 3);
@@ -219,9 +244,9 @@ namespace SuchByte.MacroDeck.GUI
btnSettings.BackgroundImage = Properties.Resources.settings;
btnSettings.BackgroundImageLayout = ImageLayout.Stretch;
btnSettings.Cursor = Cursors.Hand;
btnSettings.Font = new Font("Tahoma", 9.75F, FontStyle.Regular, GraphicsUnit.Point);
btnSettings.Font = new Font("Tahoma", 9.75F);
btnSettings.ForeColor = Color.White;
btnSettings.Location = new Point(8, 511);
btnSettings.Location = new Point(8, 541);
btnSettings.Margin = new Padding(12, 6, 12, 6);
btnSettings.Name = "btnSettings";
btnSettings.Selected = false;
@@ -233,59 +258,17 @@ namespace SuchByte.MacroDeck.GUI
// lblNumClientsConnected
//
lblNumClientsConnected.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
lblNumClientsConnected.Font = new Font("Tahoma", 9F, FontStyle.Regular, GraphicsUnit.Point);
lblNumClientsConnected.Font = new Font("Tahoma", 8.25F, FontStyle.Regular, GraphicsUnit.Point, 0);
lblNumClientsConnected.ForeColor = Color.White;
lblNumClientsConnected.Location = new Point(936, 606);
lblNumClientsConnected.Location = new Point(1046, 593);
lblNumClientsConnected.Margin = new Padding(9, 0, 9, 0);
lblNumClientsConnected.Name = "lblNumClientsConnected";
lblNumClientsConnected.Size = new Size(264, 27);
lblNumClientsConnected.Size = new Size(154, 20);
lblNumClientsConnected.TabIndex = 8;
lblNumClientsConnected.Text = "0 clients connected";
lblNumClientsConnected.TextAlign = ContentAlignment.MiddleRight;
lblNumClientsConnected.UseMnemonic = false;
//
// label1
//
label1.Anchor = AnchorStyles.Top | AnchorStyles.Right;
label1.AutoSize = true;
label1.Font = new Font("Tahoma", 12F, FontStyle.Regular, GraphicsUnit.Point);
label1.Location = new Point(1094, 44);
label1.Margin = new Padding(9, 0, 9, 0);
label1.Name = "label1";
label1.Size = new Size(15, 19);
label1.TabIndex = 10;
label1.Text = ":";
label1.UseMnemonic = false;
//
// lblPort
//
lblPort.Anchor = AnchorStyles.Top | AnchorStyles.Right;
lblPort.BackColor = Color.FromArgb(45, 45, 45);
lblPort.Font = new Font("Tahoma", 12F, FontStyle.Regular, GraphicsUnit.Point);
lblPort.ForeColor = Color.White;
lblPort.Location = new Point(1127, 37);
lblPort.Margin = new Padding(9, 0, 9, 0);
lblPort.Name = "lblPort";
lblPort.Size = new Size(69, 32);
lblPort.TabIndex = 11;
lblPort.Text = "8191";
lblPort.TextAlign = ContentAlignment.MiddleLeft;
lblPort.UseMnemonic = false;
//
// lblIpAddressHostname
//
lblIpAddressHostname.Anchor = AnchorStyles.Top | AnchorStyles.Right;
lblIpAddressHostname.Font = new Font("Tahoma", 9F, FontStyle.Regular, GraphicsUnit.Point);
lblIpAddressHostname.ForeColor = Color.White;
lblIpAddressHostname.Location = new Point(225, 42);
lblIpAddressHostname.Margin = new Padding(9, 0, 9, 0);
lblIpAddressHostname.Name = "lblIpAddressHostname";
lblIpAddressHostname.Size = new Size(468, 27);
lblIpAddressHostname.TabIndex = 13;
lblIpAddressHostname.Text = "IP address/hostname : Port";
lblIpAddressHostname.TextAlign = ContentAlignment.MiddleRight;
lblIpAddressHostname.UseMnemonic = false;
//
// navigation
//
navigation.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left;
@@ -295,50 +278,32 @@ namespace SuchByte.MacroDeck.GUI
navigation.Location = new Point(0, 42);
navigation.Margin = new Padding(0);
navigation.Name = "navigation";
navigation.Size = new Size(60, 561);
navigation.Size = new Size(60, 591);
navigation.TabIndex = 15;
//
// btnNotifications
// qrCodeBox
//
btnNotifications.BorderRadius = 8;
btnNotifications.Cursor = Cursors.Hand;
btnNotifications.FlatAppearance.BorderSize = 0;
btnNotifications.FlatStyle = FlatStyle.Flat;
btnNotifications.Font = new Font("Tahoma", 8F, FontStyle.Regular, GraphicsUnit.Point);
btnNotifications.ForeColor = Color.White;
btnNotifications.HoverColor = Color.Empty;
btnNotifications.Icon = Properties.Resources.Bell;
btnNotifications.Location = new Point(69, 42);
btnNotifications.Margin = new Padding(4);
btnNotifications.Name = "btnNotifications";
btnNotifications.NotificationCount = 0;
btnNotifications.Padding = new Padding(0, 4, 4, 0);
btnNotifications.Progress = 0;
btnNotifications.ProgressColor = Color.FromArgb(0, 103, 205);
btnNotifications.Size = new Size(44, 44);
btnNotifications.TabIndex = 16;
btnNotifications.UseVisualStyleBackColor = true;
btnNotifications.UseWindowsAccentColor = false;
btnNotifications.Visible = false;
btnNotifications.WriteProgress = true;
btnNotifications.Click += BtnNotifications_Click;
qrCodeBox.Anchor = AnchorStyles.Top | AnchorStyles.Right;
qrCodeBox.BackgroundImageLayout = ImageLayout.Stretch;
qrCodeBox.Location = new Point(1058, 66);
qrCodeBox.Name = "qrCodeBox";
qrCodeBox.Size = new Size(130, 130);
qrCodeBox.TabIndex = 17;
qrCodeBox.TabStop = false;
//
// hosts
// label1
//
hosts.Anchor = AnchorStyles.Top | AnchorStyles.Right;
hosts.BackColor = Color.FromArgb(65, 65, 65);
hosts.DropDownStyle = ComboBoxStyle.DropDownList;
hosts.Font = new Font("Tahoma", 9F, FontStyle.Regular, GraphicsUnit.Point);
hosts.Icon = null;
hosts.Location = new Point(706, 41);
hosts.Margin = new Padding(4);
hosts.Name = "hosts";
hosts.Padding = new Padding(12, 3, 12, 3);
hosts.SelectedIndex = -1;
hosts.SelectedItem = null;
hosts.Size = new Size(375, 28);
hosts.TabIndex = 17;
hosts.SelectedIndexChanged += Hosts_SelectedIndexChanged;
label1.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
label1.Font = new Font("Tahoma", 9.75F, FontStyle.Bold, GraphicsUnit.Point, 0);
label1.ForeColor = Color.White;
label1.Location = new Point(1046, 42);
label1.Margin = new Padding(9, 0, 9, 0);
label1.Name = "label1";
label1.Size = new Size(154, 20);
label1.TabIndex = 18;
label1.Text = "Quick Setup";
label1.TextAlign = ContentAlignment.MiddleCenter;
label1.UseMnemonic = false;
//
// MainWindow
//
@@ -346,12 +311,9 @@ namespace SuchByte.MacroDeck.GUI
AutoScaleMode = AutoScaleMode.Dpi;
BackColor = Color.FromArgb(45, 45, 45);
ClientSize = new Size(1200, 635);
Controls.Add(hosts);
Controls.Add(btnNotifications);
Controls.Add(navigation);
Controls.Add(lblIpAddressHostname);
Controls.Add(lblPort);
Controls.Add(label1);
Controls.Add(qrCodeBox);
Controls.Add(navigation);
Controls.Add(lblNumClientsConnected);
Controls.Add(contentPanel);
Controls.Add(lblVersion);
@@ -366,12 +328,9 @@ namespace SuchByte.MacroDeck.GUI
Controls.SetChildIndex(lblVersion, 0);
Controls.SetChildIndex(contentPanel, 0);
Controls.SetChildIndex(lblNumClientsConnected, 0);
Controls.SetChildIndex(label1, 0);
Controls.SetChildIndex(lblPort, 0);
Controls.SetChildIndex(lblIpAddressHostname, 0);
Controls.SetChildIndex(navigation, 0);
Controls.SetChildIndex(btnNotifications, 0);
Controls.SetChildIndex(hosts, 0);
Controls.SetChildIndex(qrCodeBox, 0);
Controls.SetChildIndex(label1, 0);
contentButtonPanel.ResumeLayout(false);
((ISupportInitialize)btnDeck).EndInit();
((ISupportInitialize)btnExtensions).EndInit();
@@ -379,8 +338,8 @@ namespace SuchByte.MacroDeck.GUI
((ISupportInitialize)btnVariables).EndInit();
((ISupportInitialize)btnSettings).EndInit();
navigation.ResumeLayout(false);
((ISupportInitialize)qrCodeBox).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
@@ -393,13 +352,11 @@ namespace SuchByte.MacroDeck.GUI
private ContentSelectorButton btnDeviceManager;
private Label lblNumClientsConnected;
private ContentSelectorButton btnVariables;
private Label label1;
private Label lblPort;
private Label lblIpAddressHostname;
private Panel panel1;
private Panel panel2;
private RoundedPanel navigation;
private NotificationButton btnNotifications;
private RoundedComboBox hosts;
private PictureBox qrCodeBox;
private Label label1;
}
}

View File

@@ -58,7 +58,6 @@ public partial class MainWindow : Form
private void UpdateTranslation()
{
lblIpAddressHostname.Text = LanguageManager.Strings.IpAddressHostNamePort;
}
private void LanguageChanged(object? sender, EventArgs e)
@@ -115,7 +114,6 @@ public partial class MainWindow : Form
{
Application.DoEvents();
RefreshPluginsLabels();
LoadHosts();
if (MacroDeck.SafeMode)
{
@@ -138,6 +136,8 @@ public partial class MainWindow : Form
using var updateAvailableDialog = new UpdateAvailableDialog(updateApiVersionInfo);
updateAvailableDialog.ShowDialog();
}
this.qrCodeBox.BackgroundImage = QrCodeService.Instance.GetQuickSetupQrCode();
}
private void MainWindow_Load(object? sender, EventArgs e)
@@ -158,26 +158,6 @@ public partial class MainWindow : Form
CenterToScreen();
}
private void LoadHosts()
{
hosts.SelectedIndexChanged -= Hosts_SelectedIndexChanged;
foreach (var networkInterface in NetworkInterface.GetAllNetworkInterfaces())
{
var ipAddress = networkInterface
.GetIPProperties()
.UnicastAddresses
.FirstOrDefault(x => x.Address.AddressFamily == AddressFamily.InterNetwork)
?.Address
.ToString();
if (!string.IsNullOrWhiteSpace(ipAddress))
{
hosts.Items.Add(ipAddress);
}
}
hosts.Text = MacroDeck.Configuration.HostAddress;
hosts.SelectedIndexChanged += Hosts_SelectedIndexChanged;
}
private void NotificationsChanged(object? sender, EventArgs e)
{
btnNotifications.NotificationCount = NotificationManager.Notifications.Count;
@@ -254,7 +234,7 @@ public partial class MainWindow : Form
{
_notificationsList = new NotificationsList
{
Location = btnNotifications.Location with { Y = btnNotifications.Location.Y + btnNotifications.Height }
Location = btnNotifications.Location with { Y = btnNotifications.Location.Y + btnNotifications.Height, X = btnNotifications.Location.X + btnNotifications.Size.Width + 20 }
};
_notificationsList.OnCloseRequested += (_, _) =>
{
@@ -272,10 +252,4 @@ public partial class MainWindow : Form
_notificationsList.BringToFront();
}
}
private void Hosts_SelectedIndexChanged(object? sender, EventArgs e)
{
MacroDeck.Configuration.HostAddress = hosts.Text;
MacroDeck.Configuration.Save(ApplicationPaths.MainConfigFilePath);
}
}

View File

@@ -1,4 +1,64 @@
<root>
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">

View File

@@ -49,6 +49,7 @@
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="Microsoft.Win32.Registry" />
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="QRCoder" />
<PackageReference Include="sqlite-net-pcl" />
<PackageReference Include="System.Collections" />
<PackageReference Include="System.Drawing.Common" />

View File

@@ -0,0 +1,60 @@
using System.IO;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text.Json;
using QRCoder;
using SuchByte.MacroDeck.DataTypes.QrCode;
using SuchByte.MacroDeck.Logging;
namespace SuchByte.MacroDeck.Services;
public class QrCodeService
{
public static readonly QrCodeService Instance = new();
private byte[]? _quickSetupQrCode;
public Image GetQuickSetupQrCode()
{
if (_quickSetupQrCode is not null)
{
return FromSavedBytes();
}
var networkInterfaces = new List<string>();
try
{
networkInterfaces.AddRange(NetworkInterface.GetAllNetworkInterfaces()
.Select(adapter => adapter.GetIPProperties()
.UnicastAddresses.FirstOrDefault(x => x.Address.AddressFamily == AddressFamily.InterNetwork)
?.Address.ToString())
.Where(address => !string.IsNullOrWhiteSpace(address) && address != "127.0.0.1"));
}
catch (Exception ex)
{
MacroDeckLogger.Warning($"Error while searching for network interfaces\n{ex.Message}");
}
var data = new QuickConnectQrCodeData(Environment.MachineName,
networkInterfaces,
MacroDeck.Configuration.HostPort,
MacroDeck.Configuration.EnableSsl);
var dataJson = JsonSerializer.Serialize(data);
var dataBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(dataJson));
var qrCodeLink = $"https://macro-deck.app/quick-setup/{dataBase64}";
using var qrGenerator = new QRCodeGenerator();
using var qrCodeData = qrGenerator.CreateQrCode(qrCodeLink, QRCodeGenerator.ECCLevel.L);
using var qrCode = new BitmapByteQRCode(qrCodeData);
_quickSetupQrCode = qrCode.GetGraphic(20);
return FromSavedBytes();
Image FromSavedBytes()
{
using var ms = new MemoryStream(_quickSetupQrCode);
return Image.FromStream(ms);
}
}
}