mirror of
https://github.com/terrymacdonald/DisplayMagician.git
synced 2024-08-30 18:32:20 +00:00
Fully working Windows Toast
This commit is contained in:
parent
e53f76f0ce
commit
b5d6f3f680
@ -31,8 +31,12 @@ namespace DisplayMagician
|
||||
// Parse the query string (using NuGet package QueryString.NET)
|
||||
QueryString args = QueryString.Parse(invokedArgs);
|
||||
|
||||
foreach (QueryStringParameter myArg in args)
|
||||
{
|
||||
if (myArg.Name.Equals("action",StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
// See what action is being requested
|
||||
switch (args["action"])
|
||||
switch (args["action"].ToLowerInvariant())
|
||||
{
|
||||
// Open the image
|
||||
case "open":
|
||||
@ -72,6 +76,8 @@ namespace DisplayMagician
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ namespace DisplayMagician {
|
||||
internal static class Program
|
||||
{
|
||||
internal static string AppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "DisplayMagician");
|
||||
public static string AppStartupPath = Application.StartupPath;
|
||||
public static string AppIconPath = Path.Combine(Program.AppDataPath, $"Icons");
|
||||
public static string AppProfilePath = Path.Combine(Program.AppDataPath, $"Profiles");
|
||||
public static string AppShortcutPath = Path.Combine(Program.AppDataPath, $"Shortcuts");
|
||||
@ -39,6 +40,7 @@ namespace DisplayMagician {
|
||||
public static string AppSteamIconFilename = Path.Combine(AppIconPath, @"Steam.ico");
|
||||
public static string AppUplayIconFilename = Path.Combine(AppIconPath, @"Uplay.ico");
|
||||
public static string AppEpicIconFilename = Path.Combine(AppIconPath, @"Epic.ico");
|
||||
public static bool AppToastActivated = false;
|
||||
public static bool WaitingForGameToExit = false;
|
||||
public static ProgramSettings AppProgramSettings;
|
||||
public static MainForm AppMainForm;
|
||||
@ -133,7 +135,11 @@ namespace DisplayMagician {
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
|
||||
|
||||
var app = new CommandLineApplication();
|
||||
var app = new CommandLineApplication
|
||||
{
|
||||
AllowArgumentSeparator = true,
|
||||
UnrecognizedArgumentHandling = UnrecognizedArgumentHandling.StopParsingAndCollect,
|
||||
};
|
||||
|
||||
//app.Name = "HeliosDM+";
|
||||
//app.Name = Assembly.GetEntryAssembly().GetName().Name;
|
||||
@ -210,6 +216,22 @@ namespace DisplayMagician {
|
||||
app.OnExecute(() =>
|
||||
{
|
||||
|
||||
// Add a workaround to handle the weird way that Windows tell us that DisplayMagician
|
||||
// was started from a Notification Toast when closed (Windows 10)
|
||||
// Due to the way that CommandLineUtils library works we need to handle this as
|
||||
// 'Remaining Arguments'
|
||||
if (app.RemainingArguments != null && app.RemainingArguments.Count > 0)
|
||||
{
|
||||
foreach (string myArg in app.RemainingArguments)
|
||||
{
|
||||
if (myArg.Equals("-ToastActivated"))
|
||||
{
|
||||
Program.AppToastActivated = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Console.WriteLine("Starting Normally...");
|
||||
StartUpApplication();
|
||||
return 0;
|
||||
|
BIN
DisplayMagician/Resources/applogo.png
Normal file
BIN
DisplayMagician/Resources/applogo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
@ -2,6 +2,7 @@
|
||||
using DisplayMagician.GameLibraries;
|
||||
using DisplayMagician.InterProcess;
|
||||
using DisplayMagicianShared;
|
||||
using Microsoft.Toolkit.Uwp.Notifications;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -14,6 +15,8 @@ using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Windows.Data.Xml.Dom;
|
||||
using Windows.UI.Notifications;
|
||||
|
||||
namespace DisplayMagician
|
||||
{
|
||||
@ -567,7 +570,6 @@ namespace DisplayMagician
|
||||
notifyIcon = new NotifyIcon
|
||||
{
|
||||
Icon = Properties.Resources.DisplayMagician,
|
||||
//Text = string.Format("DisplayMagician: Waiting for the Game {} to exit...", steamGameToRun.Name),
|
||||
Visible = true
|
||||
};
|
||||
Application.DoEvents();
|
||||
@ -592,6 +594,7 @@ namespace DisplayMagician
|
||||
Application.DoEvents();
|
||||
}
|
||||
|
||||
|
||||
// Now start the main game, and wait if we have to
|
||||
if (shortcutToUse.Category.Equals(ShortcutCategory.Application))
|
||||
{
|
||||
@ -654,11 +657,29 @@ namespace DisplayMagician
|
||||
}
|
||||
Application.DoEvents();
|
||||
|
||||
// Now we want to tell the user we're running an application!
|
||||
// Construct the Windows toast content
|
||||
ToastContentBuilder tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo("notify=runningApplication", ToastActivationType.Foreground)
|
||||
.AddText($"Running {processNameToLookFor} Shortcut", hintMaxLines: 1)
|
||||
.AddText($"Waiting for all {processNameToLookFor} windows to exit...");
|
||||
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
ToastContent toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
var doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
// And create the toast notification
|
||||
var toast = new ToastNotification(doc);
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show this notification
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
// Wait an extra few seconds to give the application time to settle down
|
||||
Thread.Sleep(2000);
|
||||
|
||||
// if we have things to monitor, then we should start to wait for them
|
||||
Console.WriteLine($"Waiting for application {processNameToLookFor} to exit.");
|
||||
Console.WriteLine($"Waiting for all {processNameToLookFor} windows to exit.");
|
||||
logger.Debug($"ShortcutRepository/RunShortcut - waiting for application {processNameToLookFor} to exit.");
|
||||
if (processesToMonitor.Count > 0)
|
||||
{
|
||||
@ -734,6 +755,24 @@ namespace DisplayMagician
|
||||
notifyIcon.Text = $"DisplayMagician: Running {steamGameToRun.Name.Substring(0, 41)}...";
|
||||
Application.DoEvents();
|
||||
|
||||
// Now we want to tell the user we're running a game!
|
||||
// Construct the Windows toast content
|
||||
ToastContentBuilder tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo("notify=runningSteamGame", ToastActivationType.Foreground)
|
||||
.AddText($"Running {shortcutToUse.GameName} Shortcut", hintMaxLines: 1)
|
||||
.AddText($"Waiting for the Steam Game {shortcutToUse.GameName} to exit...");
|
||||
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
ToastContent toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
var doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
// And create the toast notification
|
||||
var toast = new ToastNotification(doc);
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show this notification
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
// Wait 5 seconds for the game process to spawn
|
||||
Thread.Sleep(5000);
|
||||
// Wait for the game to exit
|
||||
@ -807,6 +846,24 @@ namespace DisplayMagician
|
||||
notifyIcon.Text = $"DisplayMagician: Running {uplayGameToRun.Name.Substring(0, 41)}...";
|
||||
Application.DoEvents();
|
||||
|
||||
// Now we want to tell the user we're running a game!
|
||||
// Construct the Windows toast content
|
||||
ToastContentBuilder tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo("notify=runningUplayGame", ToastActivationType.Foreground)
|
||||
.AddText($"Running {shortcutToUse.GameName} Shortcut", hintMaxLines: 1)
|
||||
.AddText($"Waiting for the Uplay Game {shortcutToUse.GameName} to exit...");
|
||||
//.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
ToastContent toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
var doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
// And create the toast notification
|
||||
var toast = new ToastNotification(doc);
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
// And then show this notification
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
// Wait 5 seconds for the game process to spawn
|
||||
Thread.Sleep(5000);
|
||||
|
||||
@ -854,6 +911,32 @@ namespace DisplayMagician
|
||||
Application.DoEvents();
|
||||
}
|
||||
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
|
||||
// Only replace the notification if we're minimised
|
||||
if (Program.AppProgramSettings.MinimiseOnStart)
|
||||
{
|
||||
// Remind the user that DisplayMagician is running the in background
|
||||
// Construct the toast content
|
||||
ToastContentBuilder tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo("notify=minimiseStart&action=open", ToastActivationType.Foreground)
|
||||
.AddText("DisplayMagician is minimised", hintMaxLines: 1)
|
||||
.AddButton("Open", ToastActivationType.Background, "notify=minimiseStart&action=open");
|
||||
ToastContent toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
var doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
|
||||
// And create the toast notification
|
||||
var toast = new ToastNotification(doc);
|
||||
toast.SuppressPopup = true;
|
||||
|
||||
// And then show it
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
}
|
||||
|
||||
|
||||
// Stop the pre-started startPrograms that we'd started earlier
|
||||
if (startProgramsToStop.Count > 0)
|
||||
{
|
||||
|
13
DisplayMagician/UIForms/MainForm.Designer.cs
generated
13
DisplayMagician/UIForms/MainForm.Designer.cs
generated
@ -31,7 +31,6 @@
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
|
||||
this.btn_toast = new System.Windows.Forms.Button();
|
||||
this.btn_settings = new System.Windows.Forms.Button();
|
||||
this.lbl_create_profile = new System.Windows.Forms.Label();
|
||||
this.btn_setup_display_profiles = new System.Windows.Forms.Button();
|
||||
@ -72,7 +71,6 @@
|
||||
//
|
||||
// splitContainer1.Panel1
|
||||
//
|
||||
this.splitContainer1.Panel1.Controls.Add(this.btn_toast);
|
||||
this.splitContainer1.Panel1.Controls.Add(this.btn_settings);
|
||||
this.splitContainer1.Panel1.Controls.Add(this.lbl_create_profile);
|
||||
this.splitContainer1.Panel1.Controls.Add(this.btn_setup_display_profiles);
|
||||
@ -88,16 +86,6 @@
|
||||
this.splitContainer1.Panel2.Controls.Add(this.pb_game_shortcut);
|
||||
this.splitContainer1.TabStop = false;
|
||||
//
|
||||
// btn_toast
|
||||
//
|
||||
resources.ApplyResources(this.btn_toast, "btn_toast");
|
||||
this.btn_toast.FlatAppearance.MouseDownBackColor = System.Drawing.Color.IndianRed;
|
||||
this.btn_toast.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Brown;
|
||||
this.btn_toast.ForeColor = System.Drawing.Color.White;
|
||||
this.btn_toast.Name = "btn_toast";
|
||||
this.btn_toast.UseVisualStyleBackColor = true;
|
||||
this.btn_toast.Click += new System.EventHandler(this.btn_toast_Click);
|
||||
//
|
||||
// btn_settings
|
||||
//
|
||||
resources.ApplyResources(this.btn_settings, "btn_settings");
|
||||
@ -315,6 +303,5 @@
|
||||
private System.Windows.Forms.Label lbl_create_profile;
|
||||
private System.Windows.Forms.Label lbl_create_shortcut;
|
||||
private System.Windows.Forms.Button btn_settings;
|
||||
private System.Windows.Forms.Button btn_toast;
|
||||
}
|
||||
}
|
@ -54,9 +54,9 @@ namespace DisplayMagician.UIForms
|
||||
// Remind the user that DisplayMagician is running the in background
|
||||
// Construct the toast content
|
||||
ToastContentBuilder tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo("notify=minimiseStart", ToastActivationType.Foreground)
|
||||
.AddText("DisplayMagician has started minimised!", hintMaxLines: 1)
|
||||
.AddButton("Open DisplayMagician", ToastActivationType.Background, "notify=minimiseStart&action=open");
|
||||
.AddToastActivationInfo("notify=minimiseStart&action=open", ToastActivationType.Foreground)
|
||||
.AddText("DisplayMagician is minimised", hintMaxLines: 1)
|
||||
.AddButton("Open", ToastActivationType.Background, "notify=minimiseStart&action=open");
|
||||
ToastContent toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
var doc = new XmlDocument();
|
||||
@ -65,8 +65,12 @@ namespace DisplayMagician.UIForms
|
||||
// And create the toast notification
|
||||
var toast = new ToastNotification(doc);
|
||||
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
|
||||
// And then show it
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -131,6 +135,9 @@ namespace DisplayMagician.UIForms
|
||||
// And create the toast notification
|
||||
var toast = new ToastNotification(doc);
|
||||
|
||||
// Remove any other Notifications from us
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.History.Clear();
|
||||
|
||||
// And then show it
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
}
|
||||
@ -448,24 +455,5 @@ namespace DisplayMagician.UIForms
|
||||
cb_minimise_notification_area.Checked = false;
|
||||
}
|
||||
|
||||
private void btn_toast_Click(object sender, EventArgs e)
|
||||
{
|
||||
// Construct the toast content
|
||||
ToastContentBuilder tcBuilder = new ToastContentBuilder()
|
||||
.AddToastActivationInfo("notify=runningGame", ToastActivationType.Foreground)
|
||||
.AddText("This is the notification title!", hintMaxLines: 1)
|
||||
.AddText("This is the description")
|
||||
.AddButton("Stop", ToastActivationType.Background, "notify=runningGame&action=stop");
|
||||
ToastContent toastContent = tcBuilder.Content;
|
||||
// Make sure to use Windows.Data.Xml.Dom
|
||||
var doc = new XmlDocument();
|
||||
doc.LoadXml(toastContent.GetContent());
|
||||
|
||||
// And create the toast notification
|
||||
var toast = new ToastNotification(doc);
|
||||
|
||||
// And then show it
|
||||
DesktopNotifications.DesktopNotificationManagerCompat.CreateToastNotifier().Show(toast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,39 +132,6 @@
|
||||
<data name="splitContainer1.Orientation" type="System.Windows.Forms.Orientation, System.Windows.Forms">
|
||||
<value>Horizontal</value>
|
||||
</data>
|
||||
<data name="btn_toast.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top</value>
|
||||
</data>
|
||||
<data name="btn_toast.FlatStyle" type="System.Windows.Forms.FlatStyle, System.Windows.Forms">
|
||||
<value>Flat</value>
|
||||
</data>
|
||||
<data name="btn_toast.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
|
||||
<value>NoControl</value>
|
||||
</data>
|
||||
<data name="btn_toast.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>364, 12</value>
|
||||
</data>
|
||||
<data name="btn_toast.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>75, 23</value>
|
||||
</data>
|
||||
<data name="btn_toast.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name="btn_toast.Text" xml:space="preserve">
|
||||
<value>Show Toast</value>
|
||||
</data>
|
||||
<data name=">>btn_toast.Name" xml:space="preserve">
|
||||
<value>btn_toast</value>
|
||||
</data>
|
||||
<data name=">>btn_toast.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>btn_toast.Parent" xml:space="preserve">
|
||||
<value>splitContainer1.Panel1</value>
|
||||
</data>
|
||||
<data name=">>btn_toast.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="btn_settings.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
@ -193,7 +160,7 @@
|
||||
<value>splitContainer1.Panel1</value>
|
||||
</data>
|
||||
<data name=">>btn_settings.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="lbl_create_profile.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>None</value>
|
||||
@ -226,7 +193,7 @@
|
||||
<value>splitContainer1.Panel1</value>
|
||||
</data>
|
||||
<data name=">>lbl_create_profile.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="btn_setup_display_profiles.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>None</value>
|
||||
@ -259,7 +226,7 @@
|
||||
<value>splitContainer1.Panel1</value>
|
||||
</data>
|
||||
<data name=">>btn_setup_display_profiles.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="pb_display_profile.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
@ -10807,7 +10774,7 @@
|
||||
<value>splitContainer1.Panel1</value>
|
||||
</data>
|
||||
<data name=">>pb_display_profile.ZOrder" xml:space="preserve">
|
||||
<value>4</value>
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>splitContainer1.Panel1.Name" xml:space="preserve">
|
||||
<value>splitContainer1.Panel1</value>
|
||||
@ -10834,7 +10801,7 @@
|
||||
<value>NoControl</value>
|
||||
</data>
|
||||
<data name="lbl_create_shortcut.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>220, 237</value>
|
||||
<value>220, 239</value>
|
||||
</data>
|
||||
<data name="lbl_create_shortcut.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>343, 22</value>
|
||||
@ -10873,7 +10840,7 @@
|
||||
<value>NoControl</value>
|
||||
</data>
|
||||
<data name="cb_minimise_notification_area.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>234, 354</value>
|
||||
<value>234, 357</value>
|
||||
</data>
|
||||
<data name="cb_minimise_notification_area.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>332, 20</value>
|
||||
@ -10906,7 +10873,7 @@
|
||||
<value>Microsoft Sans Serif, 9.75pt</value>
|
||||
</data>
|
||||
<data name="lbl_version.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>12, 355</value>
|
||||
<value>12, 358</value>
|
||||
</data>
|
||||
<data name="lbl_version.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>25, 16</value>
|
||||
@ -10942,7 +10909,7 @@
|
||||
<value>Microsoft Sans Serif, 21.75pt</value>
|
||||
</data>
|
||||
<data name="btn_setup_game_shortcuts.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>212, 164</value>
|
||||
<value>212, 166</value>
|
||||
</data>
|
||||
<data name="btn_setup_game_shortcuts.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>360, 50</value>
|
||||
@ -10975,7 +10942,7 @@
|
||||
<value>NoControl</value>
|
||||
</data>
|
||||
<data name="btn_exit.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>700, 351</value>
|
||||
<value>700, 354</value>
|
||||
</data>
|
||||
<data name="btn_exit.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>75, 23</value>
|
||||
@ -63407,7 +63374,7 @@
|
||||
<value>Exit DisplayMagician</value>
|
||||
</data>
|
||||
<data name="mainContextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>219, 148</value>
|
||||
<value>219, 126</value>
|
||||
</data>
|
||||
<data name="mainContextMenuStrip.Text" xml:space="preserve">
|
||||
<value>Text</value>
|
||||
|
BIN
Icon3-AppLogo.afphoto
Normal file
BIN
Icon3-AppLogo.afphoto
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user