diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/BetterLyrics.WinUI3 (Package).wapproj b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/BetterLyrics.WinUI3 (Package).wapproj
index fcbc5b7..bb19ab6 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/BetterLyrics.WinUI3 (Package).wapproj
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/BetterLyrics.WinUI3 (Package).wapproj
@@ -40,15 +40,16 @@
10.0.17763.0
net8.0-windows$(TargetPlatformVersion);$(AssetTargetFallback)
zh-CN
- false
+ True
..\BetterLyrics.WinUI3\BetterLyrics.WinUI3.csproj
False
SHA256
- True
+ False
True
x86|x64|arm64
True
0
+ BetterLyrics.WinUI3 %28Package%29_TemporaryKey.pfx
Always
@@ -80,6 +81,7 @@
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Package.appxmanifest b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Package.appxmanifest
index 3add04e..ee9c2f6 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Package.appxmanifest
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3 (Package)/Package.appxmanifest
@@ -10,7 +10,7 @@
+ Version="1.0.0.0" />
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml
index 651e4b9..0258d61 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml
@@ -16,12 +16,8 @@
-
- #80000000
-
-
- #80FFFFFF
-
+
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs
index b00ee70..853f48b 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/App.xaml.cs
@@ -7,7 +7,17 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.Windows.ApplicationModel.Resources;
+using System.IO;
using System.Text;
+using System;
+using Microsoft.Extensions.Logging;
+using Serilog;
+using Windows.ApplicationModel.Core;
+using Serilog.Core;
+using BetterLyrics.WinUI3.Models;
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using Microsoft.Windows.AppLifecycle;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
@@ -17,11 +27,14 @@ namespace BetterLyrics.WinUI3 {
/// Provides application-specific behavior to supplement the default Application class.
///
public partial class App : Application {
- public static App Current => (App)Application.Current;
+
+ private readonly ILogger _logger;
+
+ public static new App Current => (App)Application.Current;
public MainWindow? MainWindow { get; private set; }
public MainWindow? SettingsWindow { get; set; }
- public static ResourceLoader ResourceLoader = new();
+ public static ResourceLoader? ResourceLoader { get; private set; }
public static DispatcherQueue DispatcherQueue => DispatcherQueue.GetForCurrentThread();
@@ -31,18 +44,32 @@ namespace BetterLyrics.WinUI3 {
///
public App() {
this.InitializeComponent();
+
+ App.ResourceLoader = new ResourceLoader();
+
+ Helper.AppInfo.EnsureDirectories();
+ ConfigureServices();
+
+ _logger = Ioc.Default.GetService>()!;
+
+ UnhandledException += App_UnhandledException;
}
- ///
- /// Invoked when the application is launched.
- ///
- /// Details about the launch request and process.
- protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) {
+ private static void ConfigureServices() {
+
+ Log.Logger = new LoggerConfiguration()
+ .MinimumLevel.Debug()
+ .WriteTo.File(Helper.AppInfo.LogFilePattern, rollingInterval: RollingInterval.Day)
+ .CreateLogger();
// Register services
Ioc.Default.ConfigureServices(
new ServiceCollection()
.AddSingleton(DispatcherQueue.GetForCurrentThread())
+ .AddLogging(loggingBuilder => {
+ loggingBuilder.ClearProviders();
+ loggingBuilder.AddSerilog();
+ })
// Services
.AddSingleton()
.AddSingleton()
@@ -50,6 +77,18 @@ namespace BetterLyrics.WinUI3 {
.AddSingleton()
.AddSingleton()
.BuildServiceProvider());
+ }
+
+ private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e) {
+ _logger.LogError(e.Exception, "App_UnhandledException");
+ e.Handled = true;
+ }
+
+ ///
+ /// Invoked when the application is launched.
+ ///
+ /// Details about the launch request and process.
+ protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) {
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/TestMusic.mp3 b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/TestMusic.mp3
new file mode 100644
index 0000000..29bf4b4
Binary files /dev/null and b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Assets/TestMusic.mp3 differ
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/BetterLyrics.WinUI3.csproj b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/BetterLyrics.WinUI3.csproj
index 5b27302..c0f4842 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/BetterLyrics.WinUI3.csproj
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/BetterLyrics.WinUI3.csproj
@@ -1,48 +1,68 @@
-
- WinExe
- net8.0-windows10.0.26100.0
- 10.0.17763.0
- BetterLyrics.WinUI3
- app.manifest
- x86;x64;ARM64
- win-x86;win-x64;win-arm64
- true
- enable
-
+
+ WinExe
+ net8.0-windows10.0.26100.0
+ 10.0.19041.0
+ BetterLyrics.WinUI3
+ app.manifest
+ x86;x64;ARM64
+ win-x86;win-x64;win-arm64
+ true
+ enable
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Never
+
+
+ Never
+
+
+
+
+
+ False
+ True
+ False
+ True
+ 10.0.19041.0
+
+
+
+ $(DefineConstants);DISABLE_XAML_GENERATED_MAIN
+
-
-
- False
- True
- False
- True
- 10.0.19041.0
-
\ No newline at end of file
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AnimationHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AnimationHelper.cs
index e407c98..6b7d0a4 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AnimationHelper.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AnimationHelper.cs
@@ -4,41 +4,10 @@ using System;
namespace BetterLyrics.WinUI3.Helper {
- ///
- /// Edited based on: https://stackoverflow.com/a/25236507/11048731
- ///
- public class AnimationHelper : DependencyObject {
- public static int GetAnimationDuration(DependencyObject obj) {
- return (int)obj.GetValue(AnimationDurationProperty);
- }
-
- public static void SetAnimationDuration(DependencyObject obj, int value) {
- obj.SetValue(AnimationDurationProperty, value);
- }
-
- // Using a DependencyProperty as the backing store for AnimationDuration.
- // This enables animation, styling, binding, etc...
- public static readonly DependencyProperty AnimationDurationProperty =
- DependencyProperty.RegisterAttached("AnimationDuration", typeof(int),
- typeof(AnimationHelper), new PropertyMetadata(0,
- OnAnimationDurationChanged));
-
- private static void OnAnimationDurationChanged(DependencyObject d,
- DependencyPropertyChangedEventArgs e) {
- FrameworkElement element = d as FrameworkElement;
-
- var ms = (int)e.NewValue;
-
- if (ms < 0) return;
-
- var key = "LyricsLineCharGradientInTextBlock";
- foreach (var timeline in (element.Resources[key] as Storyboard).Children) {
- foreach (var keyFrame in (timeline as DoubleAnimationUsingKeyFrames).KeyFrames) {
- (keyFrame as LinearDoubleKeyFrame).KeyTime =
- KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(ms));
- }
- }
- }
+ public static class AnimationHelper {
+ public const int StackedNotificationsShowingDuration = 3900;
+ public const int StoryboardDefaultDuration = 200;
+ public const int DebounceDefaultDuration = 200;
}
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AppInfo.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AppInfo.cs
new file mode 100644
index 0000000..f2632d6
--- /dev/null
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/AppInfo.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BetterLyrics.WinUI3.Helper {
+ using System;
+ using System.IO;
+ using Windows.ApplicationModel;
+ using Windows.Storage;
+
+ public static class AppInfo {
+ // App Metadata
+ public const string AppName = "BetterLyrics";
+ public const string AppDisplayName = "Better Lyrics";
+ public const string AppAuthor = "Zhe Fang";
+ public const string GithubUrl = "https://github.com/jayfunc/BetterLyrics";
+ public static string AppVersion {
+ get {
+ var version = Package.Current.Id.Version;
+ return $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}";
+ }
+ }
+
+ // Environment Info
+ public static bool IsDebug =>
+#if DEBUG
+ true;
+#else
+ false;
+#endif
+
+ // Base Folders
+ private static string LocalFolder => ApplicationData.Current.LocalFolder.Path;
+ private static string CacheFolder => ApplicationData.Current.LocalCacheFolder.Path;
+ public static string AssetsFolder => Path.Combine(AppContext.BaseDirectory, "Assets");
+
+ // Data Files
+ private static string DatabaseFileName => "database.db";
+ public static string DatabasePath => Path.Combine(LocalFolder, DatabaseFileName);
+
+ public static string LogDirectory => Path.Combine(CacheFolder, "logs");
+ public static string LogFilePattern => Path.Combine(LogDirectory, "log-.txt");
+
+ private static string TestMusicFileName => "TestMusic.mp3";
+ public static string TestMusicPath => Path.Combine(AssetsFolder, TestMusicFileName);
+
+ public static void EnsureDirectories() {
+ Directory.CreateDirectory(LogDirectory);
+ Directory.CreateDirectory(LocalFolder);
+ }
+ }
+
+}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ColorThief.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ColorThief.cs
index 61139a8..17f7457 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ColorThief.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/ColorThief.cs
@@ -4,26 +4,21 @@ using System.Linq;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
-namespace BetterLyrics.WinUI3.Helper
-{
+namespace BetterLyrics.WinUI3.Helper {
///
/// Color map
///
- internal class CMap
- {
+ internal class CMap {
private readonly List vboxes = new List();
- private List palette;
+ private List? palette;
- public void Push(VBox box)
- {
+ public void Push(VBox box) {
palette = null;
vboxes.Add(box);
}
- public List GeneratePalette()
- {
- if (palette == null)
- {
+ public List GeneratePalette() {
+ if (palette == null) {
palette = (from vBox in vboxes
let rgb = vBox.Avg(false)
let color = FromRgb(rgb[0], rgb[1], rgb[2])
@@ -33,33 +28,27 @@ namespace BetterLyrics.WinUI3.Helper
return palette;
}
- public int Size()
- {
+ public int Size() {
return vboxes.Count;
}
- public int[] Map(int[] color)
- {
- foreach (var vbox in vboxes.Where(vbox => vbox.Contains(color)))
- {
+ public int[]? Map(int[] color) {
+ foreach (var vbox in vboxes.Where(vbox => vbox.Contains(color))) {
return vbox.Avg(false);
}
return Nearest(color);
}
- public int[] Nearest(int[] color)
- {
+ public int[]? Nearest(int[] color) {
var d1 = double.MaxValue;
- int[] pColor = null;
+ int[]? pColor = null;
- foreach (var t in vboxes)
- {
+ foreach (var t in vboxes) {
var vbColor = t.Avg(false);
var d2 = Math.Sqrt(Math.Pow(color[0] - vbColor[0], 2)
+ Math.Pow(color[1] - vbColor[1], 2)
+ Math.Pow(color[2] - vbColor[2], 2));
- if (d2 < d1)
- {
+ if (d2 < d1) {
d1 = d2;
pColor = vbColor;
}
@@ -67,27 +56,23 @@ namespace BetterLyrics.WinUI3.Helper
return pColor;
}
- public VBox FindColor(double targetLuma, double minLuma, double maxLuma, double targetSaturation, double minSaturation, double maxSaturation)
- {
- VBox max = null;
+ public VBox FindColor(double targetLuma, double minLuma, double maxLuma, double targetSaturation, double minSaturation, double maxSaturation) {
+ VBox? max = null;
double maxValue = 0;
var highestPopulation = vboxes.Select(p => p.Count(false)).Max();
- foreach (var swatch in vboxes)
- {
+ foreach (var swatch in vboxes) {
var avg = swatch.Avg(false);
var hsl = FromRgb(avg[0], avg[1], avg[2]).ToHsl();
var sat = hsl.S;
var luma = hsl.L;
if (sat >= minSaturation && sat <= maxSaturation &&
- luma >= minLuma && luma <= maxLuma)
- {
+ luma >= minLuma && luma <= maxLuma) {
var thisValue = Mmcq.CreateComparisonValue(sat, targetSaturation, luma, targetLuma,
swatch.Count(false), highestPopulation);
- if (max == null || thisValue > maxValue)
- {
+ if (max == null || thisValue > maxValue) {
max = swatch;
maxValue = thisValue;
}
@@ -97,10 +82,8 @@ namespace BetterLyrics.WinUI3.Helper
return max;
}
- public Color FromRgb(int red, int green, int blue)
- {
- var color = new Color
- {
+ public Color FromRgb(int red, int green, int blue) {
+ var color = new Color {
A = 255,
R = (byte)red,
G = (byte)green,
@@ -114,8 +97,7 @@ namespace BetterLyrics.WinUI3.Helper
///
/// Defines a color in RGB space.
///
- public struct Color
- {
+ public struct Color {
///
/// Get or Set the Alpha component value for sRGB.
///
@@ -140,8 +122,7 @@ namespace BetterLyrics.WinUI3.Helper
/// Get HSL color.
///
///
- public HslColor ToHsl()
- {
+ public HslColor ToHsl() {
const double toDouble = 1.0 / 255;
var r = toDouble * R;
var g = toDouble * G;
@@ -152,20 +133,14 @@ namespace BetterLyrics.WinUI3.Helper
double h1;
// ReSharper disable CompareOfFloatsByEqualityOperator
- if (chroma == 0)
- {
+ if (chroma == 0) {
h1 = 0;
- }
- else if (max == r)
- {
+ } else if (max == r) {
h1 = (g - b) / chroma % 6;
- }
- else if (max == g)
- {
+ } else if (max == g) {
h1 = 2 + (b - r) / chroma;
- }
- else //if (max == b)
- {
+ } else //if (max == b)
+ {
h1 = 4 + (r - g) / chroma;
}
@@ -180,20 +155,16 @@ namespace BetterLyrics.WinUI3.Helper
// ReSharper restore CompareOfFloatsByEqualityOperator
}
- public string ToHexString()
- {
+ public string ToHexString() {
return "#" + R.ToString("X2") + G.ToString("X2") + B.ToString("X2");
}
- public string ToHexAlphaString()
- {
+ public string ToHexAlphaString() {
return "#" + A.ToString("X2") + R.ToString("X2") + G.ToString("X2") + B.ToString("X2");
}
- public override string ToString()
- {
- if (A == 255)
- {
+ public override string ToString() {
+ if (A == 255) {
return ToHexString();
}
@@ -204,8 +175,7 @@ namespace BetterLyrics.WinUI3.Helper
///
/// Defines a color in Hue/Saturation/Lightness (HSL) space.
///
- public struct HslColor
- {
+ public struct HslColor {
///
/// The Alpha/opacity in 0..1 range.
///
@@ -227,8 +197,7 @@ namespace BetterLyrics.WinUI3.Helper
public double S;
}
- internal static class Mmcq
- {
+ internal static class Mmcq {
public const int Sigbits = 5;
public const int Rshift = 8 - Sigbits;
public const int Mult = 1 << Rshift;
@@ -242,8 +211,7 @@ namespace BetterLyrics.WinUI3.Helper
private static readonly VBoxComparer ComparatorProduct = new VBoxComparer();
private static readonly VBoxCountComparer ComparatorCount = new VBoxCountComparer();
- public static int GetColorIndex(int r, int g, int b)
- {
+ public static int GetColorIndex(int r, int g, int b) {
return (r << (2 * Sigbits)) + (g << Sigbits) + b;
}
@@ -252,12 +220,10 @@ namespace BetterLyrics.WinUI3.Helper
///
/// The pixels.
/// Histo (1-d array, giving the number of pixels in each quantized region of color space), or null on error.
- private static int[] GetHisto(IEnumerable pixels)
- {
+ private static int[] GetHisto(IEnumerable pixels) {
var histo = new int[Histosize];
- foreach (var pixel in pixels)
- {
+ foreach (var pixel in pixels) {
var rval = pixel[0] >> Rshift;
var gval = pixel[1] >> Rshift;
var bval = pixel[2] >> Rshift;
@@ -267,45 +233,34 @@ namespace BetterLyrics.WinUI3.Helper
return histo;
}
- private static VBox VboxFromPixels(IList pixels, int[] histo)
- {
+ private static VBox VboxFromPixels(IList pixels, int[] histo) {
int rmin = 1000000, rmax = 0;
int gmin = 1000000, gmax = 0;
int bmin = 1000000, bmax = 0;
// find min/max
var numPixels = pixels.Count;
- for (var i = 0; i < numPixels; i++)
- {
+ for (var i = 0; i < numPixels; i++) {
var pixel = pixels[i];
var rval = pixel[0] >> Rshift;
var gval = pixel[1] >> Rshift;
var bval = pixel[2] >> Rshift;
- if (rval < rmin)
- {
+ if (rval < rmin) {
rmin = rval;
- }
- else if (rval > rmax)
- {
+ } else if (rval > rmax) {
rmax = rval;
}
- if (gval < gmin)
- {
+ if (gval < gmin) {
gmin = gval;
- }
- else if (gval > gmax)
- {
+ } else if (gval > gmax) {
gmax = gval;
}
- if (bval < bmin)
- {
+ if (bval < bmin) {
bmin = bval;
- }
- else if (bval > bmax)
- {
+ } else if (bval > bmax) {
bmax = bval;
}
}
@@ -313,13 +268,11 @@ namespace BetterLyrics.WinUI3.Helper
return new VBox(rmin, rmax, gmin, gmax, bmin, bmax, histo);
}
- private static VBox[] DoCut(char color, VBox vbox, IList partialsum, IList lookaheadsum, int total)
- {
+ private static VBox[] DoCut(char color, VBox vbox, IList partialsum, IList lookaheadsum, int total) {
int vboxDim1;
int vboxDim2;
- switch (color)
- {
+ switch (color) {
case 'r':
vboxDim1 = vbox.R1;
vboxDim2 = vbox.R2;
@@ -334,10 +287,8 @@ namespace BetterLyrics.WinUI3.Helper
break;
}
- for (var i = vboxDim1; i <= vboxDim2; i++)
- {
- if (partialsum[i] > total / 2)
- {
+ for (var i = vboxDim1; i <= vboxDim2; i++) {
+ if (partialsum[i] > total / 2) {
var vbox1 = vbox.Clone();
var vbox2 = vbox.Clone();
@@ -349,19 +300,16 @@ namespace BetterLyrics.WinUI3.Helper
: Math.Max(vboxDim1, Math.Abs(Convert.ToInt32(i - 1 - left / 2.0)));
// avoid 0-count boxes
- while (d2 < 0 || partialsum[d2] <= 0)
- {
+ while (d2 < 0 || partialsum[d2] <= 0) {
d2++;
}
var count2 = lookaheadsum[d2];
- while (count2 == 0 && d2 > 0 && partialsum[d2 - 1] > 0)
- {
+ while (count2 == 0 && d2 > 0 && partialsum[d2 - 1] > 0) {
count2 = lookaheadsum[--d2];
}
// set dimensions
- switch (color)
- {
+ switch (color) {
case 'r':
vbox1.R2 = d2;
vbox2.R1 = d2 + 1;
@@ -383,15 +331,12 @@ namespace BetterLyrics.WinUI3.Helper
throw new Exception("VBox can't be cut");
}
- private static VBox[] MedianCutApply(IList histo, VBox vbox)
- {
- if (vbox.Count(false) == 0)
- {
+ private static VBox?[]? MedianCutApply(IList histo, VBox vbox) {
+ if (vbox.Count(false) == 0) {
return null;
}
- if (vbox.Count(false) == 1)
- {
- return new[] { vbox.Clone(), null };
+ if (vbox.Count(false) == 1) {
+ return [vbox.Clone(), null];
}
// only one pixel, no split
@@ -405,29 +350,23 @@ namespace BetterLyrics.WinUI3.Helper
var total = 0;
var partialsum = new int[VboxLength];
// -1 = not set / 0 = 0
- for (var l = 0; l < partialsum.Length; l++)
- {
+ for (var l = 0; l < partialsum.Length; l++) {
partialsum[l] = -1;
}
// -1 = not set / 0 = 0
var lookaheadsum = new int[VboxLength];
- for (var l = 0; l < lookaheadsum.Length; l++)
- {
+ for (var l = 0; l < lookaheadsum.Length; l++) {
lookaheadsum[l] = -1;
}
int i, j, k, sum, index;
- if (maxw == rw)
- {
- for (i = vbox.R1; i <= vbox.R2; i++)
- {
+ if (maxw == rw) {
+ for (i = vbox.R1; i <= vbox.R2; i++) {
sum = 0;
- for (j = vbox.G1; j <= vbox.G2; j++)
- {
- for (k = vbox.B1; k <= vbox.B2; k++)
- {
+ for (j = vbox.G1; j <= vbox.G2; j++) {
+ for (k = vbox.B1; k <= vbox.B2; k++) {
index = GetColorIndex(i, j, k);
sum += histo[index];
}
@@ -435,16 +374,11 @@ namespace BetterLyrics.WinUI3.Helper
total += sum;
partialsum[i] = total;
}
- }
- else if (maxw == gw)
- {
- for (i = vbox.G1; i <= vbox.G2; i++)
- {
+ } else if (maxw == gw) {
+ for (i = vbox.G1; i <= vbox.G2; i++) {
sum = 0;
- for (j = vbox.R1; j <= vbox.R2; j++)
- {
- for (k = vbox.B1; k <= vbox.B2; k++)
- {
+ for (j = vbox.R1; j <= vbox.R2; j++) {
+ for (k = vbox.B1; k <= vbox.B2; k++) {
index = GetColorIndex(j, i, k);
sum += histo[index];
}
@@ -452,16 +386,12 @@ namespace BetterLyrics.WinUI3.Helper
total += sum;
partialsum[i] = total;
}
- }
- else /* maxw == bw */
- {
- for (i = vbox.B1; i <= vbox.B2; i++)
- {
+ } else /* maxw == bw */
+ {
+ for (i = vbox.B1; i <= vbox.B2; i++) {
sum = 0;
- for (j = vbox.R1; j <= vbox.R2; j++)
- {
- for (k = vbox.G1; k <= vbox.G2; k++)
- {
+ for (j = vbox.R1; j <= vbox.R2; j++) {
+ for (k = vbox.G1; k <= vbox.G2; k++) {
index = GetColorIndex(j, k, i);
sum += histo[index];
}
@@ -471,10 +401,8 @@ namespace BetterLyrics.WinUI3.Helper
}
}
- for (i = 0; i < VboxLength; i++)
- {
- if (partialsum[i] != -1)
- {
+ for (i = 0; i < VboxLength; i++) {
+ if (partialsum[i] != -1) {
lookaheadsum[i] = total - partialsum[i];
}
}
@@ -492,16 +420,13 @@ namespace BetterLyrics.WinUI3.Helper
/// The target.
/// The histo.
/// vbox1 not defined; shouldn't happen!
- private static void Iter(List lh, IComparer comparator, int target, IList histo)
- {
+ private static void Iter(List lh, IComparer comparator, int target, IList histo) {
var ncolors = 1;
var niters = 0;
- while (niters < MaxIterations)
- {
+ while (niters < MaxIterations) {
var vbox = lh[lh.Count - 1];
- if (vbox.Count(false) == 0)
- {
+ if (vbox.Count(false) == 0) {
lh.Sort(comparator);
niters++;
continue;
@@ -511,39 +436,33 @@ namespace BetterLyrics.WinUI3.Helper
// do the cut
var vboxes = MedianCutApply(histo, vbox);
- var vbox1 = vboxes[0];
- var vbox2 = vboxes[1];
+ var vbox1 = vboxes?[0];
+ var vbox2 = vboxes?[1];
- if (vbox1 == null)
- {
+ if (vbox1 == null) {
throw new Exception(
"vbox1 not defined; shouldn't happen!");
}
lh.Add(vbox1);
- if (vbox2 != null)
- {
+ if (vbox2 != null) {
lh.Add(vbox2);
ncolors++;
}
lh.Sort(comparator);
- if (ncolors >= target)
- {
+ if (ncolors >= target) {
return;
}
- if (niters++ > MaxIterations)
- {
+ if (niters++ > MaxIterations) {
return;
}
}
}
- public static CMap Quantize(byte[][] pixels, int maxcolors)
- {
+ public static CMap Quantize(byte[][] pixels, int maxcolors) {
// short-circuit
- if (pixels.Length == 0 || maxcolors < 2 || maxcolors > 256)
- {
+ if (pixels.Length == 0 || maxcolors < 2 || maxcolors > 256) {
return null;
}
@@ -571,28 +490,24 @@ namespace BetterLyrics.WinUI3.Helper
// calculate the actual colors
var cmap = new CMap();
- foreach (var vb in pq)
- {
+ foreach (var vb in pq) {
cmap.Push(vb);
}
return cmap;
}
- public static double CreateComparisonValue(double saturation, double targetSaturation, double luma, double targetLuma, int population, int highestPopulation)
- {
+ public static double CreateComparisonValue(double saturation, double targetSaturation, double luma, double targetLuma, int population, int highestPopulation) {
return WeightedMean(InvertDiff(saturation, targetSaturation), WeightSaturation,
InvertDiff(luma, targetLuma), WeightLuma,
population / (double)highestPopulation, WeightPopulation);
}
- private static double WeightedMean(params double[] values)
- {
+ private static double WeightedMean(params double[] values) {
double sum = 0;
double sumWeight = 0;
- for (var i = 0; i < values.Length; i += 2)
- {
+ for (var i = 0; i < values.Length; i += 2) {
var value = values[i];
var weight = values[i + 1];
@@ -603,16 +518,13 @@ namespace BetterLyrics.WinUI3.Helper
return sum / sumWeight;
}
- private static double InvertDiff(double value, double targetValue)
- {
+ private static double InvertDiff(double value, double targetValue) {
return 1 - Math.Abs(value - targetValue);
}
}
- public class QuantizedColor
- {
- public QuantizedColor(Color color, int population)
- {
+ public class QuantizedColor {
+ public QuantizedColor(Color color, int population) {
Color = color;
Population = population;
IsDark = CalculateYiqLuma(color) < 128;
@@ -622,8 +534,7 @@ namespace BetterLyrics.WinUI3.Helper
public int Population { get; private set; }
public bool IsDark { get; private set; }
- public int CalculateYiqLuma(Color color)
- {
+ public int CalculateYiqLuma(Color color) {
return Convert.ToInt32(Math.Round((299 * color.R + 587 * color.G + 114 * color.B) / 1000f));
}
}
@@ -631,8 +542,7 @@ namespace BetterLyrics.WinUI3.Helper
///
/// 3D color space box.
///
- internal class VBox
- {
+ internal class VBox {
private readonly int[] histo;
private int[] avg;
public int B1;
@@ -644,8 +554,7 @@ namespace BetterLyrics.WinUI3.Helper
public int R2;
private int? volume;
- public VBox(int r1, int r2, int g1, int g2, int b1, int b2, int[] histo)
- {
+ public VBox(int r1, int r2, int g1, int g2, int b1, int b2, int[] histo) {
R1 = r1;
R2 = r2;
G1 = g1;
@@ -656,31 +565,24 @@ namespace BetterLyrics.WinUI3.Helper
this.histo = histo;
}
- public int Volume(bool force)
- {
- if (volume == null || force)
- {
+ public int Volume(bool force) {
+ if (volume == null || force) {
volume = (R2 - R1 + 1) * (G2 - G1 + 1) * (B2 - B1 + 1);
}
return volume.Value;
}
- public int Count(bool force)
- {
- if (count == null || force)
- {
+ public int Count(bool force) {
+ if (count == null || force) {
var npix = 0;
int i;
- for (i = R1; i <= R2; i++)
- {
+ for (i = R1; i <= R2; i++) {
int j;
- for (j = G1; j <= G2; j++)
- {
+ for (j = G1; j <= G2; j++) {
int k;
- for (k = B1; k <= B2; k++)
- {
+ for (k = B1; k <= B2; k++) {
var index = Mmcq.GetColorIndex(i, j, k);
npix += histo[index];
}
@@ -693,15 +595,12 @@ namespace BetterLyrics.WinUI3.Helper
return count.Value;
}
- public VBox Clone()
- {
+ public VBox Clone() {
return new VBox(R1, R2, G1, G2, B1, B2, histo);
}
- public int[] Avg(bool force)
- {
- if (avg == null || force)
- {
+ public int[] Avg(bool force) {
+ if (avg == null || force) {
var ntot = 0;
var rsum = 0;
@@ -710,14 +609,11 @@ namespace BetterLyrics.WinUI3.Helper
int i;
- for (i = R1; i <= R2; i++)
- {
+ for (i = R1; i <= R2; i++) {
int j;
- for (j = G1; j <= G2; j++)
- {
+ for (j = G1; j <= G2; j++) {
int k;
- for (k = B1; k <= B2; k++)
- {
+ for (k = B1; k <= B2; k++) {
var histoindex = Mmcq.GetColorIndex(i, j, k);
var hval = histo[histoindex];
ntot += hval;
@@ -728,16 +624,13 @@ namespace BetterLyrics.WinUI3.Helper
}
}
- if (ntot > 0)
- {
+ if (ntot > 0) {
avg = new[]
{
Math.Abs(rsum / ntot), Math.Abs(gsum / ntot),
Math.Abs(bsum / ntot)
};
- }
- else
- {
+ } else {
avg = new[]
{
Math.Abs(Mmcq.Mult * (R1 + R2 + 1) / 2),
@@ -750,8 +643,7 @@ namespace BetterLyrics.WinUI3.Helper
return avg;
}
- public bool Contains(int[] pixel)
- {
+ public bool Contains(int[] pixel) {
var rval = pixel[0] >> Mmcq.Rshift;
var gval = pixel[1] >> Mmcq.Rshift;
var bval = pixel[2] >> Mmcq.Rshift;
@@ -760,20 +652,16 @@ namespace BetterLyrics.WinUI3.Helper
}
}
- internal class VBoxCountComparer : IComparer
- {
- public int Compare(VBox x, VBox y)
- {
+ internal class VBoxCountComparer : IComparer {
+ public int Compare(VBox x, VBox y) {
var a = x.Count(false);
var b = y.Count(false);
return a < b ? -1 : (a > b ? 1 : 0);
}
}
- internal class VBoxComparer : IComparer
- {
- public int Compare(VBox x, VBox y)
- {
+ internal class VBoxComparer : IComparer {
+ public int Compare(VBox x, VBox y) {
var aCount = x.Count(false);
var bCount = y.Count(false);
var aVolume = x.Volume(false);
@@ -786,20 +674,17 @@ namespace BetterLyrics.WinUI3.Helper
}
}
- public class ColorThief
- {
+ public class ColorThief {
public const int DefaultColorCount = 5;
public const int DefaultQuality = 10;
public const bool DefaultIgnoreWhite = true;
public const int ColorDepth = 4;
- private CMap GetColorMap(byte[][] pixelArray, int colorCount)
- {
+ private CMap GetColorMap(byte[][] pixelArray, int colorCount) {
// Send array to quantize function which clusters values using median
// cut algorithm
- if (colorCount > 0)
- {
+ if (colorCount > 0) {
--colorCount;
}
@@ -807,13 +692,11 @@ namespace BetterLyrics.WinUI3.Helper
return cmap;
}
- private byte[][] ConvertPixels(byte[] pixels, int pixelCount, int quality, bool ignoreWhite)
- {
+ private byte[][] ConvertPixels(byte[] pixels, int pixelCount, int quality, bool ignoreWhite) {
var expectedDataLength = pixelCount * ColorDepth;
- if (expectedDataLength != pixels.Length)
- {
+ if (expectedDataLength != pixels.Length) {
throw new ArgumentException("(expectedDataLength = "
+ expectedDataLength + ") != (pixels.length = "
+ pixels.Length + ")");
@@ -830,8 +713,7 @@ namespace BetterLyrics.WinUI3.Helper
var numUsedPixels = 0;
var pixelArray = new byte[numRegardedPixels][];
- for (var i = 0; i < pixelCount; i += quality)
- {
+ for (var i = 0; i < pixelCount; i += quality) {
var offset = i * ColorDepth;
var b = pixels[offset];
var g = pixels[offset + 1];
@@ -839,8 +721,7 @@ namespace BetterLyrics.WinUI3.Helper
var a = pixels[offset + 3];
// If pixel is mostly opaque and not white
- if (a >= 125 && !(ignoreWhite && r > 250 && g > 250 && b > 250))
- {
+ if (a >= 125 && !(ignoreWhite && r > 250 && g > 250 && b > 250)) {
pixelArray[numUsedPixels] = new[] { r, g, b };
numUsedPixels++;
}
@@ -864,12 +745,10 @@ namespace BetterLyrics.WinUI3.Helper
///
/// if set to true [ignore white].
///
- public async Task GetColor(BitmapDecoder sourceImage, int quality = DefaultQuality, bool ignoreWhite = DefaultIgnoreWhite)
- {
+ public async Task GetColor(BitmapDecoder sourceImage, int quality = DefaultQuality, bool ignoreWhite = DefaultIgnoreWhite) {
var palette = await GetPalette(sourceImage, 3, quality, ignoreWhite);
- var dominantColor = new QuantizedColor(new Color
- {
+ var dominantColor = new QuantizedColor(new Color {
A = Convert.ToByte(palette.Average(a => a.Color.A)),
R = Convert.ToByte(palette.Average(a => a.Color.R)),
G = Convert.ToByte(palette.Average(a => a.Color.G)),
@@ -893,29 +772,24 @@ namespace BetterLyrics.WinUI3.Helper
/// if set to true [ignore white].
///
/// true
- public async Task> GetPalette(BitmapDecoder sourceImage, int colorCount = DefaultColorCount, int quality = DefaultQuality, bool ignoreWhite = DefaultIgnoreWhite)
- {
+ public async Task> GetPalette(BitmapDecoder sourceImage, int colorCount = DefaultColorCount, int quality = DefaultQuality, bool ignoreWhite = DefaultIgnoreWhite) {
var pixelArray = await GetPixelsFast(sourceImage, quality, ignoreWhite);
var cmap = GetColorMap(pixelArray, colorCount);
- if (cmap != null)
- {
+ if (cmap != null) {
var colors = cmap.GeneratePalette();
return colors;
}
return new List();
}
- private async Task GetIntFromPixel(BitmapDecoder decoder)
- {
+ private async Task GetIntFromPixel(BitmapDecoder decoder) {
var pixelsData = await decoder.GetPixelDataAsync();
var pixels = pixelsData.DetachPixelData();
return pixels;
}
- private async Task GetPixelsFast(BitmapDecoder sourceImage, int quality, bool ignoreWhite)
- {
- if (quality < 1)
- {
+ private async Task GetPixelsFast(BitmapDecoder sourceImage, int quality, bool ignoreWhite) {
+ if (quality < 1) {
quality = DefaultQuality;
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/DatabaseHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/DatabaseHelper.cs
deleted file mode 100644
index 7bad089..0000000
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/DatabaseHelper.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using BetterLyrics.WinUI3.Models;
-using SQLite;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace BetterLyrics.WinUI3.Helper {
- public class DatabaseHelper {
- private static SQLiteConnection _database;
-
- public static SQLiteConnection InitializeDatabase() {
- string dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "MusicMetadataIndex.db");
- _database = new SQLiteConnection(dbPath);
- _database.CreateTable(); // Create table if it doesn't exist
- return _database;
- }
- }
-}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/VisualHelper.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/VisualHelper.cs
index e87aabf..d82e4d8 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/VisualHelper.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Helper/VisualHelper.cs
@@ -16,16 +16,16 @@ namespace BetterLyrics.WinUI3.Helper {
///
///
public static List FindVisualChildren(DependencyObject depObj) where T : DependencyObject {
- List list = new List();
+ List list = [];
if (depObj != null) {
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) {
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
- if (child != null && child is T) {
- list.Add((T)child);
+ if (child != null && child is T t) {
+ list.Add(t);
}
List childItems = FindVisualChildren(child);
- if (childItems != null && childItems.Count() > 0) {
+ if (childItems != null && childItems.Count > 0) {
foreach (var item in childItems) {
list.Add(item);
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/MainWindow.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/MainWindow.xaml.cs
index db5dd00..ca8442e 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/MainWindow.xaml.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/MainWindow.xaml.cs
@@ -1,26 +1,18 @@
-using System;
-using System.Diagnostics;
-using System.Threading.Tasks;
using BetterLyrics.WinUI3.Helper;
using BetterLyrics.WinUI3.Messages;
using BetterLyrics.WinUI3.Services.Settings;
-using BetterLyrics.WinUI3.ViewModels;
using BetterLyrics.WinUI3.Views;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.WinUI.Behaviors;
using DevWinUI;
-using Microsoft.UI;
-using Microsoft.UI.Composition;
-using Microsoft.UI.Composition.SystemBackdrops;
+using Microsoft.Graphics.Canvas.UI.Xaml;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
-using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Media.Animation;
using Microsoft.UI.Xaml.Navigation;
-using WinRT;
-using WinRT.Interop;
+using System;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
@@ -33,14 +25,14 @@ namespace BetterLyrics.WinUI3 {
private readonly OverlappedPresenter _presenter;
- private SettingsService _settingsService;
+ private readonly SettingsService _settingsService;
public static StackedNotificationsBehavior? StackedNotificationsBehavior { get; private set; }
public MainWindow() {
this.InitializeComponent();
- _settingsService = Ioc.Default.GetService();
+ _settingsService = Ioc.Default.GetService()!;
RootGrid.RequestedTheme = (ElementTheme)_settingsService.Theme;
SystemBackdrop = SystemBackdropHelper.CreateSystemBackdrop((BackdropType)_settingsService.BackdropType);
@@ -72,14 +64,9 @@ namespace BetterLyrics.WinUI3 {
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
- private void BackButton_Click(object sender, RoutedEventArgs e) {
- if (RootFrame.CanGoBack) {
- RootFrame.GoBack();
- }
- }
-
private void CloseButton_Click(object sender, RoutedEventArgs e) {
if (RootFrame.CurrentSourcePageType == typeof(MainPage)) {
+ ((RootFrame.Content as MainPage)!.FindChild("LyricsCanvas") as CanvasAnimatedControl)!.Paused = true;
App.Current.Exit();
} else if (RootFrame.CurrentSourcePageType == typeof(SettingsPage)) {
App.Current.SettingsWindow!.AppWindow.Hide();
@@ -133,7 +120,7 @@ namespace BetterLyrics.WinUI3 {
}
private void RootFrame_Navigated(object sender, NavigationEventArgs e) {
- AppWindow.Title = Title = App.ResourceLoader.GetString($"{e.SourcePageType.Name}Title");
+ AppWindow.Title = Title = App.ResourceLoader!.GetString($"{e.SourcePageType.Name}Title");
}
private void AOTButton_Click(object sender, RoutedEventArgs e) {
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/SystemBackdropChangedMessage.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/SystemBackdropChangedMessage.cs
index 86e3da9..8eba17a 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/SystemBackdropChangedMessage.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/SystemBackdropChangedMessage.cs
@@ -7,8 +7,6 @@ using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Messages {
- public class SystemBackdropChangedMessage : ValueChangedMessage {
- public SystemBackdropChangedMessage(BackdropType value) : base(value) {
- }
+ public class SystemBackdropChangedMessage(BackdropType value) : ValueChangedMessage(value) {
}
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/ThemeChangedMessage.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/ThemeChangedMessage.cs
index d573786..dede073 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/ThemeChangedMessage.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Messages/ThemeChangedMessage.cs
@@ -7,8 +7,6 @@ using System.Text;
using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Messages {
- public class ThemeChangedMessage : ValueChangedMessage {
- public ThemeChangedMessage(ElementTheme value) : base(value) {
- }
+ public class ThemeChangedMessage(ElementTheme value) : ValueChangedMessage(value) {
}
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MetadataIndex.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MetadataIndex.cs
index 8e31171..6bf7529 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MetadataIndex.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MetadataIndex.cs
@@ -1,15 +1,10 @@
using SQLite;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace BetterLyrics.WinUI3.Models {
public class MetadataIndex {
[PrimaryKey]
- public string Path { get; set; }
- public string Title { get; set; }
- public string Artist { get; set; }
+ public string? Path { get; set; }
+ public string? Title { get; set; }
+ public string? Artist { get; set; }
}
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MusicFolder.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MusicFolder.cs
deleted file mode 100644
index 53af245..0000000
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Models/MusicFolder.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using CommunityToolkit.Mvvm.ComponentModel;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace BetterLyrics.WinUI3.Models {
- public partial class MusicFolder : ObservableObject {
- [ObservableProperty]
- private string _path;
-
- public bool IsValid => Directory.Exists(Path);
-
- public MusicFolder(string path) {
- Path = path;
- }
- }
-}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Program.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Program.cs
new file mode 100644
index 0000000..8d94a64
--- /dev/null
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Program.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.UI.Dispatching;
+using Microsoft.UI.Xaml;
+using Microsoft.Windows.AppLifecycle;
+
+namespace BetterLyrics.WinUI3 {
+ public class Program {
+ [STAThread]
+ static int Main(string[] args) {
+ WinRT.ComWrappersSupport.InitializeComWrappers();
+ bool isRedirect = DecideRedirection();
+
+ if (!isRedirect) {
+ Application.Start((p) => {
+ var context = new DispatcherQueueSynchronizationContext(
+ DispatcherQueue.GetForCurrentThread());
+ SynchronizationContext.SetSynchronizationContext(context);
+ _ = new App();
+ });
+ }
+
+ return 0;
+ }
+
+ private static bool DecideRedirection() {
+ bool isRedirect = false;
+ AppActivationArguments args = AppInstance.GetCurrent().GetActivatedEventArgs();
+ ExtendedActivationKind kind = args.Kind;
+ AppInstance keyInstance = AppInstance.FindOrRegisterForKey(Helper.AppInfo.AppName);
+
+ if (keyInstance.IsCurrent) {
+ keyInstance.Activated += OnActivated;
+ } else {
+ isRedirect = true;
+ RedirectActivationTo(args, keyInstance);
+ }
+
+ return isRedirect;
+ }
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ private static extern IntPtr CreateEvent(
+ IntPtr lpEventAttributes, bool bManualReset,
+ bool bInitialState, string lpName);
+
+ [DllImport("kernel32.dll")]
+ private static extern bool SetEvent(IntPtr hEvent);
+
+ [DllImport("ole32.dll")]
+ private static extern uint CoWaitForMultipleObjects(
+ uint dwFlags, uint dwMilliseconds, ulong nHandles,
+ IntPtr[] pHandles, out uint dwIndex);
+
+ [DllImport("user32.dll")]
+ static extern bool SetForegroundWindow(IntPtr hWnd);
+
+ private static IntPtr redirectEventHandle = IntPtr.Zero;
+
+ // Do the redirection on another thread, and use a non-blocking
+ // wait method to wait for the redirection to complete.
+ public static void RedirectActivationTo(AppActivationArguments args,
+ AppInstance keyInstance) {
+ redirectEventHandle = CreateEvent(IntPtr.Zero, true, false, null);
+ Task.Run(() => {
+ keyInstance.RedirectActivationToAsync(args).AsTask().Wait();
+ SetEvent(redirectEventHandle);
+ });
+
+ uint CWMO_DEFAULT = 0;
+ uint INFINITE = 0xFFFFFFFF;
+ _ = CoWaitForMultipleObjects(
+ CWMO_DEFAULT, INFINITE, 1,
+ [redirectEventHandle], out uint handleIndex);
+
+ // Bring the window to the foreground
+ Process process = Process.GetProcessById((int)keyInstance.ProcessId);
+ SetForegroundWindow(process.MainWindowHandle);
+ }
+
+ private static void OnActivated(object sender, AppActivationArguments args) {
+ ExtendedActivationKind kind = args.Kind;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs
index 93cb845..22eecf0 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Database/DatabaseService.cs
@@ -19,20 +19,18 @@ namespace BetterLyrics.WinUI3.Services.Database {
private readonly CharsetDetector _charsetDetector = new();
public DatabaseService() {
- string dbPath = Path.Combine(
- Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
- "MusicMetadataIndex.db"
- );
- _connection = new SQLiteConnection(dbPath);
- _connection.CreateTable();
+ _connection = new SQLiteConnection(Helper.AppInfo.DatabasePath);
+ if (_connection.GetTableInfo("MetadataIndex").Count == 0) {
+ _connection.CreateTable();
+ }
}
- public async Task RebuildMusicMetadataIndexDatabaseAsync(IList musicFolders) {
+ public async Task RebuildMusicMetadataIndexDatabaseAsync(IList paths) {
await Task.Run(() => {
_connection.DeleteAll();
- foreach (var localMusicFolder in musicFolders) {
- if (localMusicFolder.IsValid) {
- foreach (var file in Directory.GetFiles(localMusicFolder.Path)) {
+ foreach (var path in paths) {
+ if (Directory.Exists(path)) {
+ foreach (var file in Directory.GetFiles(path)) {
var fileExtension = Path.GetExtension(file);
var track = new Track(file);
_connection.Insert(new MetadataIndex {
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs
index 34dd146..ce7b7bb 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Services/Settings/SettingsService.cs
@@ -1,29 +1,16 @@
-using ATL;
-using BetterLyrics.WinUI3.Helper;
-using BetterLyrics.WinUI3.Messages;
-using BetterLyrics.WinUI3.Models;
-using BetterLyrics.WinUI3.Services.Database;
+using BetterLyrics.WinUI3.Messages;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using DevWinUI;
-using Microsoft.UI.Composition.SystemBackdrops;
using Microsoft.UI.Xaml;
-using Microsoft.UI.Xaml.Controls.Primitives;
-using Microsoft.UI.Xaml.Media;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
-using System.Data.Common;
-using System.Diagnostics;
-using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
-using System.Text;
-using System.Threading.Tasks;
using Windows.Globalization;
using Windows.Storage;
-using Windows.System;
namespace BetterLyrics.WinUI3.Services.Settings {
public partial class SettingsService : ObservableObject {
@@ -34,7 +21,7 @@ namespace BetterLyrics.WinUI3.Services.Settings {
}
[ObservableProperty]
- private bool _isRebuildingLyricsIndexDatabase;
+ private bool _isRebuildingLyricsIndexDatabase = false;
// Theme
public int Theme {
@@ -46,19 +33,10 @@ namespace BetterLyrics.WinUI3.Services.Settings {
}
// Music
- private ObservableCollection _musicLibraries;
+ private ObservableCollection _musicLibraries;
- public ObservableCollection MusicLibraries {
+ public ObservableCollection MusicLibraries {
get {
- if (_musicLibraries == null) {
- var list = JsonConvert.DeserializeObject>(
- Get(SettingsKeys.MusicLibraries, SettingsDefaultValues.MusicLibraries)
- );
-
- _musicLibraries = new ObservableCollection(list);
- _musicLibraries.CollectionChanged += (_, _) => SaveMusicLibraries();
- }
-
return _musicLibraries;
}
set {
@@ -157,24 +135,26 @@ namespace BetterLyrics.WinUI3.Services.Settings {
set => Set(SettingsKeys.IsLyricsDynamicGlowEffectEnabled, value);
}
-
private readonly ApplicationDataContainer _localSettings;
- private readonly DatabaseService _databaseService;
- public SettingsService(DatabaseService databaseService) {
+ public SettingsService() {
_localSettings = ApplicationData.Current.LocalSettings;
- _databaseService = databaseService;
+
+ _musicLibraries = [.. JsonConvert.DeserializeObject>(
+ Get(SettingsKeys.MusicLibraries, SettingsDefaultValues.MusicLibraries)!)!];
+
+ _musicLibraries.CollectionChanged += (_, _) => SaveMusicLibraries();
}
- private T Get(string key, T defaultValue = default) {
- if (_localSettings.Values.TryGetValue(key, out object value)) {
+ private T? Get(string key, T? defaultValue = default) {
+ if (_localSettings.Values.TryGetValue(key, out object? value)) {
return (T)Convert.ChangeType(value, typeof(T));
}
return defaultValue;
}
- private void Set(string key, T value, [CallerMemberName] string propertyName = null) {
+ private void Set(string key, T value, [CallerMemberName] string? propertyName = null) {
_localSettings.Values[key] = value;
OnPropertyChanged(propertyName);
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw
index 51d29da..ee989b9 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/en-US/Resources.resw
@@ -126,6 +126,9 @@
Open in file explorer
+
+ Open in file explorer
+
Remove from app
@@ -322,7 +325,7 @@
Setup lyrics database now
- Hover on the bottom left corner and then click to open settings page
+ Hover on the bottom left corner and then click to open settings page
Hover on the bottom area to show it
@@ -339,4 +342,16 @@
No music playing now
+
+ Developer options
+
+
+ Play test music
+
+
+ Play using system player
+
+
+ Log
+
\ No newline at end of file
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-CN/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-CN/Resources.resw
index 3872a6b..72c633c 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-CN/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-CN/Resources.resw
@@ -126,6 +126,9 @@
在文件资源管理器中打开
+
+ 在文件资源管理器中打开
+
从应用中移除
@@ -339,4 +342,16 @@
当前没有正在播放的音乐
+
+ 开发者选项
+
+
+ 播放测试音乐
+
+
+ 使用系统播放器播放
+
+
+ 日志
+
\ No newline at end of file
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-TW/Resources.resw b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-TW/Resources.resw
index a4cd688..84dea11 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-TW/Resources.resw
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Strings/zh-TW/Resources.resw
@@ -126,6 +126,9 @@
在檔案總管中開啟
+
+ 在檔案總管中開啟
+
從應用程式中移除
@@ -339,4 +342,16 @@
目前沒有正在播放的音樂
+
+ 開發者選項
+
+
+ 播放測試音樂
+
+
+ 使用系統播放器播放
+
+
+ 紀錄
+
\ No newline at end of file
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MainViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MainViewModel.cs
index 13ec1f7..1461dd4 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MainViewModel.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/MainViewModel.cs
@@ -1,6 +1,7 @@
using ATL;
using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Services.Database;
+using BetterLyrics.WinUI3.Services.Settings;
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.UI.Xaml;
@@ -17,7 +18,7 @@ using Windows.UI;
using static ATL.LyricsInfo;
namespace BetterLyrics.WinUI3.ViewModels {
- public partial class MainViewModel : ObservableObject {
+ public partial class MainViewModel(DatabaseService databaseService) : ObservableObject {
[ObservableProperty]
private bool _isAnyMusicSessionExisted = false;
@@ -46,17 +47,18 @@ namespace BetterLyrics.WinUI3.ViewModels {
[ObservableProperty]
private bool _lyricsExisted = false;
- private Helper.ColorThief _colorThief = new();
+ private readonly Helper.ColorThief _colorThief = new();
- private readonly DatabaseService _databaseService;
-
- public MainViewModel(DatabaseService databaseService) {
- _databaseService = databaseService;
- }
+ private readonly DatabaseService _databaseService = databaseService;
public List GetLyrics(Track? track) {
List result = [];
- var lyricsPhrases = track?.Lyrics.SynchronizedLyrics;
+
+ if (track == null) {
+ return result;
+ }
+
+ var lyricsPhrases = track.Lyrics.SynchronizedLyrics;
if (lyricsPhrases?.Count > 0) {
if (lyricsPhrases[0].TimestampMs > 0) {
@@ -100,7 +102,7 @@ namespace BetterLyrics.WinUI3.ViewModels {
}
- public async Task<(List, SoftwareBitmap?, uint, uint)> SetSongInfoAsync(GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps, ICanvasAnimatedControl control) {
+ public async Task<(List, SoftwareBitmap?, uint, uint)> SetSongInfoAsync(GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps) {
SoftwareBitmap? coverSoftwareBitmap = null;
uint coverImagePixelWidth = 0;
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SettingsViewModel.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SettingsViewModel.cs
index c0f69e2..acbfb79 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SettingsViewModel.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/ViewModels/SettingsViewModel.cs
@@ -2,37 +2,26 @@
using BetterLyrics.WinUI3.Services.Database;
using BetterLyrics.WinUI3.Services.Settings;
using CommunityToolkit.Mvvm.ComponentModel;
-using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Input;
-using Microsoft.UI.Xaml;
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
-using Windows.ApplicationModel;
using Windows.ApplicationModel.Core;
using Windows.Storage.Pickers;
using Windows.System;
using WinRT.Interop;
namespace BetterLyrics.WinUI3.ViewModels {
- public partial class SettingsViewModel : ObservableObject {
+ public partial class SettingsViewModel(DatabaseService databaseService, SettingsService settingsService) : ObservableObject {
- private readonly DatabaseService _databaseService;
+ private readonly DatabaseService _databaseService = databaseService;
[ObservableProperty]
- private SettingsService _settingsService;
+ private SettingsService _settingsService = settingsService;
[ObservableProperty]
- private string _version;
-
- public SettingsViewModel(DatabaseService databaseService, SettingsService settingsService) {
- _databaseService = databaseService;
- _settingsService = settingsService;
-
- var version = Package.Current.Id.Version;
- Version = $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}";
- }
+ private string _version = Helper.AppInfo.AppVersion;
[RelayCommand]
private async Task RebuildLyricsIndexDatabaseAsync() {
@@ -41,14 +30,13 @@ namespace BetterLyrics.WinUI3.ViewModels {
SettingsService.IsRebuildingLyricsIndexDatabase = false;
}
- [RelayCommand]
- private async Task RemoveFolderAsync(MusicFolder musicFolder) {
- SettingsService.MusicLibraries.Remove(musicFolder);
+ public async Task RemoveFolderAsync(string path) {
+ SettingsService.MusicLibraries.Remove(path);
await RebuildLyricsIndexDatabaseAsync();
}
[RelayCommand]
- private async Task AddFolderAsync() {
+ private async Task SelectAndAddFolderAsync() {
var picker = new FolderPicker();
picker.FileTypeFilter.Add("*");
@@ -58,35 +46,44 @@ namespace BetterLyrics.WinUI3.ViewModels {
var folder = await picker.PickSingleFolderAsync();
+ App.Current.SettingsWindow!.AppWindow.MoveInZOrderAtTop();
+
if (folder != null) {
- string path = folder.Path;
- bool existed = SettingsService.MusicLibraries.Count((x) => x.Path == path) > 0;
- if (existed) {
- MainWindow.StackedNotificationsBehavior?.Show(App.ResourceLoader.GetString("SettingsPagePathExistedInfo"), 3900);
- } else {
- SettingsService.MusicLibraries.Add(new MusicFolder(path));
- await RebuildLyricsIndexDatabaseAsync();
- }
+ await AddFolderAsync(folder.Path);
}
}
- [RelayCommand]
- private async Task LaunchProjectGitHubPageAsync() {
- await Launcher.LaunchUriAsync(new Uri("https://github.com/jayfunc/BetterLyrics"));
+ private async Task AddFolderAsync(string path) {
+ bool existed = SettingsService.MusicLibraries.Any((x) => x == path);
+ if (existed) {
+ MainWindow.StackedNotificationsBehavior?.Show(App.ResourceLoader!.GetString("SettingsPagePathExistedInfo"),
+ Helper.AnimationHelper.StackedNotificationsShowingDuration);
+ } else {
+ SettingsService.MusicLibraries.Add(path);
+ await RebuildLyricsIndexDatabaseAsync();
+ }
}
[RelayCommand]
- private void OpenFolderInFileExplorer(MusicFolder musicFolder) {
+ private static async Task LaunchProjectGitHubPageAsync() {
+ await Launcher.LaunchUriAsync(new Uri(Helper.AppInfo.GithubUrl));
+ }
+
+ private static void OpenFolderInFileExplorer(string path) {
Process.Start(new ProcessStartInfo {
FileName = "explorer.exe",
- Arguments = musicFolder.Path,
+ Arguments = path,
UseShellExecute = true
});
}
+ public static void OpenMusicFolder(string path) {
+ OpenFolderInFileExplorer(path);
+ }
+
[RelayCommand]
- private void RestartApp() {
+ private static void RestartApp() {
// The restart will be executed immediately.
AppRestartFailureReason failureReason =
Microsoft.Windows.AppLifecycle.AppInstance.Restart("");
@@ -104,5 +101,19 @@ namespace BetterLyrics.WinUI3.ViewModels {
}
}
+ [RelayCommand]
+ private async Task PlayTestingMusicTask() {
+ await AddFolderAsync(Helper.AppInfo.AssetsFolder);
+ Process.Start(new ProcessStartInfo {
+ FileName = Helper.AppInfo.TestMusicPath,
+ UseShellExecute = true
+ });
+ }
+
+ [RelayCommand]
+ private static void OpenLogFolder() {
+ OpenFolderInFileExplorer(Helper.AppInfo.LogDirectory);
+ }
+
}
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MainPage.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MainPage.xaml
index 17510da..6bcedc7 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MainPage.xaml
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/MainPage.xaml
@@ -32,6 +32,7 @@
@@ -111,32 +112,40 @@
-
+ Grid.ColumnSpan="3">
+
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -157,179 +166,142 @@
-
+ x:Name="CoverArea"
+ Grid.Row="1"
+ SizeChanged="CoverArea_SizeChanged">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
+
-
+
-
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
(MainViewModel)DataContext;
- private SettingsService _settingsService;
+ private readonly SettingsService _settingsService;
private List _lyricsLines = [];
@@ -48,29 +50,27 @@ namespace BetterLyrics.WinUI3.Views {
private float _coverBitmapRotateAngle = 0f;
private float _coverScaleFactor = 1;
- private float _coverRotateSpeed = 0.003f;
+ private readonly float _coverRotateSpeed = 0.003f;
private float _lyricsGlowEffectAngle = 0f;
- private float _lyricsGlowEffectSpeed = 0.01f;
+ private readonly float _lyricsGlowEffectSpeed = 0.01f;
- private float _lyricsGlowEffectMinBlurAmount = 0f;
- private float _lyricsGlowEffectMaxBlurAmount = 6f;
+ private readonly float _lyricsGlowEffectMinBlurAmount = 0f;
+ private readonly float _lyricsGlowEffectMaxBlurAmount = 6f;
- private int _animationDurationMs = 200;
-
- private DispatcherQueueTimer _queueTimer;
+ private readonly DispatcherQueueTimer _queueTimer;
private TimeSpan _currentTime = TimeSpan.Zero;
- private float _defaultOpacity = 0.3f;
- private float _highlightedOpacity = 1.0f;
+ private readonly float _defaultOpacity = 0.3f;
+ private readonly float _highlightedOpacity = 1.0f;
- private float _defaultScale = 0.95f;
- private float _highlightedScale = 1.0f;
+ private readonly float _defaultScale = 0.95f;
+ private readonly float _highlightedScale = 1.0f;
- private int _lineEnteringDurationMs = 800;
- private int _lineExitingDurationMs = 800;
- private int _lineScrollDurationMs = 800;
+ private readonly int _lineEnteringDurationMs = 800;
+ private readonly int _lineExitingDurationMs = 800;
+ private readonly int _lineScrollDurationMs = 800;
private float _lastTotalYScroll = 0.0f;
private float _totalYScroll = 0.0f;
@@ -78,7 +78,7 @@ namespace BetterLyrics.WinUI3.Views {
private double _lyricsAreaWidth = 0.0f;
private double _lyricsAreaHeight = 0.0f;
- private double _lyricsCanvasRightMargin = 36;
+ private readonly double _lyricsCanvasRightMargin = 36;
private double _lyricsCanvasLeftMargin = 0;
private double _lyricsCanvasMaxTextWidth = 0;
@@ -86,7 +86,6 @@ namespace BetterLyrics.WinUI3.Views {
private int _endVisibleLineIndex = -1;
private bool _forceToScroll = false;
- private bool _isRelayoutLyricsNeeded = false;
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
@@ -95,9 +94,13 @@ namespace BetterLyrics.WinUI3.Views {
private Color _lyricsColor;
+ private readonly ILogger _logger;
+
public MainPage() {
this.InitializeComponent();
+ _logger = Ioc.Default.GetService>()!;
+
SetLyricsColor();
_settingsService = Ioc.Default.GetService()!;
@@ -134,6 +137,7 @@ namespace BetterLyrics.WinUI3.Views {
}
break;
case nameof(_settingsService.Theme):
+ await Task.Delay(1);
SetLyricsColor();
break;
default:
@@ -152,7 +156,7 @@ namespace BetterLyrics.WinUI3.Views {
}
private void SetLyricsColor() {
- _lyricsColor = ((SolidColorBrush)TitleTextBlock.Foreground).Color;
+ _lyricsColor = ((SolidColorBrush)LyricsCanvas.Foreground).Color;
}
private async void InitMediaManager() {
@@ -163,14 +167,14 @@ namespace BetterLyrics.WinUI3.Views {
SessionManager_CurrentSessionChanged(_sessionManager, null);
}
- private void CurrentSession_TimelinePropertiesChanged(GlobalSystemMediaTransportControlsSession sender, TimelinePropertiesChangedEventArgs args) {
+ private void CurrentSession_TimelinePropertiesChanged(GlobalSystemMediaTransportControlsSession? sender, TimelinePropertiesChangedEventArgs? args) {
if (sender == null) {
_currentTime = TimeSpan.Zero;
return;
}
_currentTime = sender.GetTimelineProperties().Position;
- // Debug.WriteLine(_currentTime);
+ // _logger.LogDebug(_currentTime);
}
///
@@ -178,7 +182,7 @@ namespace BetterLyrics.WinUI3.Views {
///
///
///
- private void CurrentSession_PlaybackInfoChanged(GlobalSystemMediaTransportControlsSession sender, PlaybackInfoChangedEventArgs args) {
+ private void CurrentSession_PlaybackInfoChanged(GlobalSystemMediaTransportControlsSession? sender, PlaybackInfoChangedEventArgs? args) {
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () => {
if (sender == null) {
LyricsCanvas.Paused = true;
@@ -186,7 +190,7 @@ namespace BetterLyrics.WinUI3.Views {
}
var playbackState = sender.GetPlaybackInfo().PlaybackStatus;
- Debug.WriteLine(playbackState);
+ _logger.LogDebug(playbackState.ToString());
switch (playbackState) {
case GlobalSystemMediaTransportControlsSessionPlaybackStatus.Closed:
@@ -214,12 +218,12 @@ namespace BetterLyrics.WinUI3.Views {
}
- private void SessionManager_SessionsChanged(GlobalSystemMediaTransportControlsSessionManager sender, SessionsChangedEventArgs args) {
- Debug.WriteLine("SessionManager_SessionsChanged");
+ private void SessionManager_SessionsChanged(GlobalSystemMediaTransportControlsSessionManager sender, SessionsChangedEventArgs? args) {
+ _logger.LogDebug("SessionManager_SessionsChanged");
}
- private void SessionManager_CurrentSessionChanged(GlobalSystemMediaTransportControlsSessionManager sender, CurrentSessionChangedEventArgs args) {
- Debug.WriteLine("SessionManager_CurrentSessionChanged");
+ private void SessionManager_CurrentSessionChanged(GlobalSystemMediaTransportControlsSessionManager sender, CurrentSessionChangedEventArgs? args) {
+ _logger.LogDebug("SessionManager_CurrentSessionChanged");
// Unregister events associated with the previous session
if (_currentSession != null) {
_currentSession.MediaPropertiesChanged -= CurrentSession_MediaPropertiesChanged;
@@ -244,9 +248,9 @@ namespace BetterLyrics.WinUI3.Views {
///
///
///
- private void CurrentSession_MediaPropertiesChanged(GlobalSystemMediaTransportControlsSession sender, MediaPropertiesChangedEventArgs args) {
+ private void CurrentSession_MediaPropertiesChanged(GlobalSystemMediaTransportControlsSession? sender, MediaPropertiesChangedEventArgs? args) {
_queueTimer.Debounce(() => {
- Debug.WriteLine("CurrentSession_MediaPropertiesChanged");
+ _logger.LogDebug("CurrentSession_MediaPropertiesChanged");
_dispatcherQueue.TryEnqueue(DispatcherQueuePriority.High, async () => {
GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps = null;
@@ -261,13 +265,14 @@ namespace BetterLyrics.WinUI3.Views {
ViewModel.IsAnyMusicSessionExisted = _currentSession != null;
ViewModel.AboutToUpdateUI = true;
- await Task.Delay(_animationDurationMs);
+ await Task.Delay(AnimationHelper.StoryboardDefaultDuration);
- (_lyricsLines, _coverSoftwareBitmap, _coverImagePixelWidth, _coverImagePixelHeight) = await ViewModel.SetSongInfoAsync(mediaProps, LyricsCanvas);
+ (_lyricsLines, _coverSoftwareBitmap, _coverImagePixelWidth, _coverImagePixelHeight) = await ViewModel.SetSongInfoAsync(mediaProps);
// Force to show lyrics and scroll to current line even if the music is not playing
LyricsCanvas.Paused = false;
await ForceToScrollToCurrentPlayingLineAsync();
+ await Task.Delay(1);
// Detect and recover the music state
CurrentSession_PlaybackInfoChanged(_currentSession, null);
CurrentSession_TimelinePropertiesChanged(_currentSession, null);
@@ -275,17 +280,17 @@ namespace BetterLyrics.WinUI3.Views {
ViewModel.AboutToUpdateUI = false;
if (_lyricsLines.Count == 0) {
- Grid.SetColumnSpan(SongInfoStackPanel, 3);
+ Grid.SetColumnSpan(SongInfoInnerGrid, 3);
} else {
- Grid.SetColumnSpan(SongInfoStackPanel, 1);
+ Grid.SetColumnSpan(SongInfoInnerGrid, 1);
}
});
- }, TimeSpan.FromMilliseconds(200));
+ }, TimeSpan.FromMilliseconds(AnimationHelper.DebounceDefaultDuration));
}
- private async void RootGrid_SizeChanged(object sender, SizeChangedEventArgs e) {
+ private async void RootGrid_SizeChanged(object? sender, SizeChangedEventArgs? e) {
//_queueTimer.Debounce(async () => {
_lyricsAreaHeight = LyricsGrid.ActualHeight;
@@ -315,7 +320,7 @@ namespace BetterLyrics.WinUI3.Views {
// Draw (dynamic) cover image as the very first layer
if (_settingsService.IsCoverOverlayEnabled && _coverSoftwareBitmap != null) {
- DrawCoverImage(sender, ds, _settingsService.IsDynamicCoverOverlay);
+ DrawCoverImage(sender, ds);
}
// Lyrics only layer
@@ -450,7 +455,7 @@ namespace BetterLyrics.WinUI3.Views {
// Scale
ds.Transform = Matrix3x2.CreateScale(line.Scale, new Vector2(centerX, centerY)) * Matrix3x2.CreateTranslation(0, _totalYScroll);
- //Debug.WriteLine(_totalYScroll);
+ // _logger.LogDebug(_totalYScroll);
ds.DrawTextLayout(line.TextLayout, position, Colors.Transparent);
@@ -460,7 +465,7 @@ namespace BetterLyrics.WinUI3.Views {
}
- private void DrawCoverImage(ICanvasAnimatedControl control, CanvasDrawingSession ds, bool dynamic) {
+ private void DrawCoverImage(ICanvasAnimatedControl control, CanvasDrawingSession ds) {
ds.Transform = Matrix3x2.CreateRotation(_coverBitmapRotateAngle, control.Size.ToVector2() * 0.5f);
@@ -518,7 +523,7 @@ namespace BetterLyrics.WinUI3.Views {
}
- if (_lyricsLines.LastOrDefault()?.TextLayout == null || _isRelayoutLyricsNeeded) {
+ if (_lyricsLines.LastOrDefault()?.TextLayout == null) {
LayoutLyrics();
}
@@ -542,7 +547,7 @@ namespace BetterLyrics.WinUI3.Views {
}
private Tuple GetVisibleLyricsLineIndexBoundaries() {
- //Debug.WriteLine($"{_startVisibleLineIndex} {_endVisibleLineIndex}");
+ // _logger.LogDebug($"{_startVisibleLineIndex} {_endVisibleLineIndex}");
return new Tuple(_startVisibleLineIndex, _endVisibleLineIndex);
}
@@ -725,11 +730,20 @@ namespace BetterLyrics.WinUI3.Views {
}
private void SettingsButton_Click(object sender, RoutedEventArgs e) {
- if (App.Current.SettingsWindow == null) {
- App.Current.SettingsWindow = new MainWindow();
- App.Current.SettingsWindow!.Navigate(typeof(SettingsPage));
+ if (App.Current.SettingsWindow is null) {
+ var settingsWindow = new MainWindow();
+ settingsWindow.Navigate(typeof(SettingsPage));
+ App.Current.SettingsWindow = settingsWindow;
}
- App.Current.SettingsWindow.AppWindow.Show();
+
+ var appWindow = App.Current.SettingsWindow.AppWindow;
+
+ if (appWindow.Presenter is OverlappedPresenter presenter) {
+ presenter.Restore();
+ }
+
+ appWindow.Show();
+ appWindow.MoveInZOrderAtTop();
}
private void WelcomeTeachingTip_Closed(TeachingTip sender, TeachingTipClosedEventArgs args) {
@@ -751,5 +765,9 @@ namespace BetterLyrics.WinUI3.Views {
private void InitDatabaseTeachingTip_Closed(TeachingTip sender, TeachingTipClosedEventArgs args) {
_settingsService.IsFirstRun = false;
}
+
+ private void CoverArea_SizeChanged(object sender, SizeChangedEventArgs e) {
+ CoverImageGrid.Width = CoverImageGrid.Height = Math.Min(CoverArea.ActualWidth, CoverArea.ActualHeight);
+ }
}
}
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml
index d072322..20453d3 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml
@@ -10,7 +10,6 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:CommunityToolkit.WinUI"
xmlns:vm="using:BetterLyrics.WinUI3.ViewModels"
- x:Name="RootPage"
NavigationCacheMode="Required"
mc:Ignorable="d">
@@ -29,54 +28,21 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ Click="SettingsPageOpenPathButton_Click"
+ Tag="{Binding}" />
+ Click="SettingsPageRemovePathButton_Click"
+ Tag="{Binding}" />
@@ -110,11 +76,8 @@
-
-
+
+
@@ -359,6 +322,16 @@
HeaderIcon="{ui:FontIcon Glyph=}"
IsClickEnabled="True" />
+
+
+
+
+
+
+
+
+
+
diff --git a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml.cs b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml.cs
index 4f1a991..df2be29 100644
--- a/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml.cs
+++ b/BetterLyrics.WinUI3/BetterLyrics.WinUI3/Views/SettingsPage.xaml.cs
@@ -1,27 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices.WindowsRuntime;
-using Windows.Foundation;
-using Windows.Foundation.Collections;
-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 ABI.System;
-using Windows.System;
using BetterLyrics.WinUI3.ViewModels;
using CommunityToolkit.Mvvm.DependencyInjection;
-using System.Diagnostics;
-using WinRT.Interop;
-using Windows.Storage.Pickers;
-using BetterLyrics.WinUI3.Models;
-using Microsoft.Windows.ApplicationModel.Resources;
-using BetterLyrics.WinUI3.Services.Settings;
+using Microsoft.UI.Xaml;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
@@ -39,5 +19,12 @@ namespace BetterLyrics.WinUI3.Views {
DataContext = Ioc.Default.GetService();
}
+ private void SettingsPageOpenPathButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) {
+ SettingsViewModel.OpenMusicFolder((string)(sender as HyperlinkButton)!.Tag);
+ }
+
+ private async void SettingsPageRemovePathButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e) {
+ await ViewModel.RemoveFolderAsync((string)(sender as HyperlinkButton)!.Tag);
+ }
}
}
diff --git a/How2Install/How2Install.md b/How2Install/How2Install.md
new file mode 100644
index 0000000..898b3b7
--- /dev/null
+++ b/How2Install/How2Install.md
@@ -0,0 +1,35 @@
+# How to install ".msixbundle" package
+
+## Pre-steps
+
+Be sure that you have already enable developer mode. To do that, you can follow the steps below:
+
+1. Go to "Settings", select "System", go to "Developer Options".
+ 
+
+2. Turn on "Developer Mode" and enable local PowerShell script allowance.
+ 
+
+Now you are good to go.
+
+## Step 1
+
+Unzip downloaded .zip file, right-click on "install.ps1", select "Run using PowerShell".
+
+
+## Step 2
+
+Press "Enter" to continue, and agree on the popup window.
+
+
+## Step 3
+
+Enter "Y" to install cert.
+
+
+## Step 4
+
+You are good to go now.
+
+
+> If you fail to install it with the previous version installed, please try to uninstall the old one and install it again.
\ No newline at end of file
diff --git a/How2Install/image-1.png b/How2Install/image-1.png
new file mode 100644
index 0000000..8a0a991
Binary files /dev/null and b/How2Install/image-1.png differ
diff --git a/How2Install/image-2.png b/How2Install/image-2.png
new file mode 100644
index 0000000..685d968
Binary files /dev/null and b/How2Install/image-2.png differ
diff --git a/How2Install/image-3.png b/How2Install/image-3.png
new file mode 100644
index 0000000..c6ba1a2
Binary files /dev/null and b/How2Install/image-3.png differ
diff --git a/How2Install/image-4.png b/How2Install/image-4.png
new file mode 100644
index 0000000..c6ba1a2
Binary files /dev/null and b/How2Install/image-4.png differ
diff --git a/How2Install/image-5.png b/How2Install/image-5.png
new file mode 100644
index 0000000..ec0db1b
Binary files /dev/null and b/How2Install/image-5.png differ
diff --git a/How2Install/image-6.png b/How2Install/image-6.png
new file mode 100644
index 0000000..566dd7d
Binary files /dev/null and b/How2Install/image-6.png differ
diff --git a/How2Install/image.png b/How2Install/image.png
new file mode 100644
index 0000000..b382640
Binary files /dev/null and b/How2Install/image.png differ
diff --git a/README.md b/README.md
index 6a6a1bf..a160346 100644
--- a/README.md
+++ b/README.md
@@ -64,6 +64,12 @@ Or watch our introduction video「BetterLyrics 阶段性开发成果展示」(up


+## Try it now
+
+Download latest version via [Google Drive](https://drive.google.com/file/d/1Hh8ijbODIksPmmRYujys7fXngw93Of7I/view?usp=sharing) or visit Microsoft Store (unavailable at the moment)
+
+To learn about how to install ".msixbundle" package, see [this doc](How2Install/How2Install.md).
+
## Many thanks to
- [Audio Tools Library (ATL) for .NET](https://github.com/Zeugma440/atldotnet)