Browse Source

Implemented Discord's Rich Presence

CPKreuz 4 years ago
parent
commit
f9a455f7f7

+ 7 - 0
PixiEditor/Models/DataHolders/Document.cs

@@ -22,6 +22,8 @@ namespace PixiEditor.Models.DataHolders
         private int height;
         private int width;
 
+        private DateTime openedUtc = DateTime.UtcNow;
+
         public Document(int width, int height)
         {
             Width = width;
@@ -106,6 +108,11 @@ namespace PixiEditor.Models.DataHolders
             }
         }
 
+        public DateTime OpenedUTC
+        {
+            get => openedUtc;
+        }
+
         private Selection selection = new Selection(Array.Empty<Coordinates>());
 
         public Selection ActiveSelection

+ 12 - 0
PixiEditor/Models/UserPreferences/PreferencesSettings.cs

@@ -55,6 +55,11 @@ namespace PixiEditor.Models.UserPreferences
 
             Preferences[name] = value;
 
+            if (Callbacks.ContainsKey(name))
+            {
+                Callbacks[name].Invoke(value);
+            }
+
             Save();
         }
 
@@ -70,6 +75,13 @@ namespace PixiEditor.Models.UserPreferences
 
 #nullable enable
 
+        public static Dictionary<string, Action<object>> Callbacks { get; set; } = new Dictionary<string, Action<object>>();
+
+        public static void AddCallback(string setting, Action<object> action)
+        {
+            Callbacks.Add(setting, action);
+        }
+
         public static T? GetPreference<T>(string name)
         {
             return GetPreference(name, default(T));

+ 1 - 0
PixiEditor/PixiEditor.csproj

@@ -46,6 +46,7 @@
   </ItemGroup>
   <ItemGroup>
     <PackageReference Include="Dirkster.AvalonDock.Themes.VS2013" Version="4.50.0" />
+    <PackageReference Include="DiscordRichPresence" Version="1.0.175" />
     <PackageReference Include="Expression.Blend.Sdk">
       <Version>1.0.2</Version>
     </PackageReference>

+ 143 - 0
PixiEditor/ViewModels/SubViewModels/Main/DiscordViewModel.cs

@@ -0,0 +1,143 @@
+using DiscordRPC;
+using PixiEditor.Models.DataHolders;
+using PixiEditor.Models.UserPreferences;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PixiEditor.ViewModels.SubViewModels.Main
+{
+    public class DiscordViewModel : SubViewModel<ViewModelMain>
+    {
+        private DiscordRpcClient client;
+        private string clientId;
+        private Document currentDocument;
+
+        public bool Enabled
+        {
+            get => client != null;
+            set
+            {
+                if (Enabled != value)
+                {
+                    if (value)
+                    {
+                        Start();
+                    }
+                    else
+                    {
+                        Stop();
+                    }
+                }
+            }
+        }
+
+        public DiscordViewModel(ViewModelMain owner, string clientId)
+            : base(owner)
+        {
+            Owner.BitmapManager.DocumentChanged += DocumentChanged;
+            this.clientId = clientId;
+
+            Enabled = PreferencesSettings.GetPreference<bool>("EnableRichPresence");
+            PreferencesSettings.AddCallback("EnableRichPresence", x => Enabled = (bool)x);
+        }
+
+        public void Start()
+        {
+            client = new DiscordRpcClient(clientId);
+            client.OnReady += OnReady;
+            client.Initialize();
+        }
+
+        public void Stop()
+        {
+            client.ClearPresence();
+            client.Dispose();
+            client = null;
+        }
+
+        public void UpdatePresence(Document document)
+        {
+            RichPresence richPresence = new RichPresence
+            {
+                Assets = new Assets
+                {
+                    LargeImageKey = "editorlogo",
+                    LargeImageText = "You discovered PixiEditor's logo",
+                    SmallImageKey = "github",
+                    SmallImageText = "Download PixiEditor on GitHub (please)!"
+                }
+            };
+
+            if (document == null)
+            {
+                richPresence.WithTimestamps(new Timestamps(DateTime.UtcNow));
+                richPresence.Details = "Staring at absolutely";
+                richPresence.State = "nothing";
+            }
+            else
+            {
+                richPresence.WithTimestamps(new Timestamps(document.OpenedUTC));
+                richPresence.Details = $"Editing {document.Name}";
+
+                string state = $"{document.Width}x{document.Height}, ";
+
+                if (document.Layers.Count == 1)
+                {
+                    state += "1 Layer";
+                }
+                else
+                {
+                    state += $"{document.Layers.Count} Layers";
+                }
+
+                richPresence.State = state;
+            }
+
+            client.SetPresence(richPresence);
+        }
+
+        private void DocumentChanged(object sender, Models.Events.DocumentChangedEventArgs e)
+        {
+            if (currentDocument != null)
+            {
+                currentDocument.PropertyChanged -= DocumentPropertyChanged;
+                currentDocument.LayersChanged -= DocumentLayerChanged;
+            }
+
+            currentDocument = e.NewDocument;
+
+            if (currentDocument != null)
+            {
+                UpdatePresence(currentDocument);
+                currentDocument.PropertyChanged += DocumentPropertyChanged;
+                currentDocument.LayersChanged += DocumentLayerChanged;
+            }
+        }
+
+        private void DocumentLayerChanged(object sender, Models.Controllers.LayersChangedEventArgs e)
+        {
+            UpdatePresence(currentDocument);
+        }
+
+        private void DocumentPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+        {
+            if (e.PropertyName == "Name" || e.PropertyName == "Width" || e.PropertyName == "Height")
+            {
+                UpdatePresence(currentDocument);
+            }
+        }
+
+        private void OnReady(object sender, DiscordRPC.Message.ReadyMessage args)
+        {
+            UpdatePresence(Owner.BitmapManager.ActiveDocument);
+        }
+
+        ~DiscordViewModel()
+        {
+            Stop();
+        }
+    }
+}

+ 4 - 3
PixiEditor/ViewModels/SubViewModels/SubViewModel.cs

@@ -1,12 +1,13 @@
 namespace PixiEditor.ViewModels.SubViewModels
 {
-    public class SubViewModel<T> : ViewModelBase where T: ViewModelBase
+    public class SubViewModel<T> : ViewModelBase
+        where T : ViewModelBase
     {
         public T Owner { get; }
 
         public SubViewModel(T owner)
         {
             Owner = owner;
-        }        
+        }
     }
-}
+}

+ 12 - 0
PixiEditor/ViewModels/SubViewModels/UserPreferences/SettingsViewModel.cs

@@ -58,6 +58,18 @@ namespace PixiEditor.ViewModels.SubViewModels.UserPreferences
             }
         }
 
+        private bool enableRichPresence = PreferencesSettings.GetPreference<bool>(nameof(EnableRichPresence));
+
+        public bool EnableRichPresence
+        {
+            get => enableRichPresence;
+            set
+            {
+                enableRichPresence = value;
+                RaiseAndUpdatePreference(nameof(EnableRichPresence), value);
+            }
+        }
+
         public void RaiseAndUpdatePreference<T>(string name, T value)
         {
             RaisePropertyChanged(name);

+ 3 - 0
PixiEditor/ViewModels/ViewModelMain.cs

@@ -57,6 +57,8 @@ namespace PixiEditor.ViewModels
 
         public MiscViewModel MiscSubViewModel { get; set; }
 
+        public DiscordViewModel DiscordViewModel { get; set; }
+
         public BitmapManager BitmapManager { get; set; }
 
         public PixelChangesController ChangesController { get; set; }
@@ -89,6 +91,7 @@ namespace PixiEditor.ViewModels
             ColorsSubViewModel = new ColorsViewModel(this);
             DocumentSubViewModel = new DocumentViewModel(this);
             MiscSubViewModel = new MiscViewModel(this);
+            DiscordViewModel = new DiscordViewModel(this, "764168193685979138");
 
             ShortcutController = new ShortcutController
             {

+ 11 - 0
PixiEditor/Views/Dialogs/SettingsWindow.xaml

@@ -46,6 +46,8 @@
                     Command="{Binding SelectCategoryCommand}" CommandParameter="General">General</Button>
             <Button Style="{StaticResource AccentDarkRoundButton}" Margin="10 5 10 5" 
                     Command="{Binding SelectCategoryCommand}" CommandParameter="Updates">Updates</Button>
+            <Button Style="{StaticResource AccentDarkRoundButton}" Margin="10 5 10 5" 
+                    Command="{Binding SelectCategoryCommand}" CommandParameter="Discord">Discord</Button>
         </StackPanel>
         <Grid Grid.Row="1" Grid.Column="1" Background="{StaticResource AccentColor}">
             <Grid Visibility="{Binding SelectedCategory, Converter={StaticResource EqualityBoolToVisibilityConverter},
@@ -74,6 +76,15 @@
                     </StackPanel>
                 </StackPanel>
             </Grid>
+            <Grid Visibility="{Binding SelectedCategory, Converter={StaticResource EqualityBoolToVisibilityConverter},
+            ConverterParameter='Discord'}">
+                <StackPanel Orientation="Vertical">
+                    <Label Style="{StaticResource Header1}" Content="Rich Presence"/>
+                    <StackPanel Orientation="Vertical" Margin="50 0 50 0">
+                        <CheckBox IsChecked="{Binding SettingsSubViewModel.EnableRichPresence}" Content="Enable"/>
+                    </StackPanel>
+                </StackPanel>
+            </Grid>
         </Grid>
     </Grid>
 </Window>