mirror of
https://github.com/jayfunc/BetterLyrics.git
synced 2026-01-12 10:54:55 +08:00
add support for editing album art corner radius
This commit is contained in:
@@ -11,6 +11,7 @@ using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.UI.Xaml;
|
||||
using SQLite;
|
||||
using Ude;
|
||||
using Windows.Media.Control;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.Database
|
||||
{
|
||||
@@ -18,6 +19,8 @@ namespace BetterLyrics.WinUI3.Services.Database
|
||||
{
|
||||
private readonly SQLiteConnection _connection;
|
||||
|
||||
private readonly CharsetDetector _charsetDetector = new();
|
||||
|
||||
public DatabaseService()
|
||||
{
|
||||
_connection = new SQLiteConnection(Helper.AppInfo.DatabasePath);
|
||||
@@ -53,5 +56,83 @@ namespace BetterLyrics.WinUI3.Services.Database
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Track? GetMusicMetadata(
|
||||
GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps
|
||||
)
|
||||
{
|
||||
if (mediaProps == null || mediaProps.Title == null || mediaProps.Artist == null)
|
||||
return null;
|
||||
|
||||
var founds = _connection
|
||||
.Table<MetadataIndex>()
|
||||
// Look up by Title and Artist (these two props were fetched by reading metadata in music file befoe) first
|
||||
// then by Path (music file name usually contains song name and artist so this can be a second way to look up for)
|
||||
// Please note for .lrc file, only the second way works for it
|
||||
.Where(m =>
|
||||
(
|
||||
m.Title != null
|
||||
&& m.Artist != null
|
||||
&& m.Title.Contains(mediaProps.Title)
|
||||
&& m.Artist.Contains(mediaProps.Artist)
|
||||
)
|
||||
|| (
|
||||
m.Path != null
|
||||
&& m.Path.Contains(mediaProps.Title)
|
||||
&& m.Path.Contains(mediaProps.Artist)
|
||||
)
|
||||
)
|
||||
.ToList();
|
||||
if (founds == null || founds.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
var first = new Track(founds[0].Path);
|
||||
if (founds.Count == 1)
|
||||
{
|
||||
return first;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (first.Lyrics.Exists())
|
||||
{
|
||||
return first;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var found in founds)
|
||||
{
|
||||
if (found.Path.EndsWith(".lrc"))
|
||||
{
|
||||
using (FileStream fs = File.OpenRead(found.Path))
|
||||
{
|
||||
_charsetDetector.Feed(fs);
|
||||
_charsetDetector.DataEnd();
|
||||
}
|
||||
|
||||
string content;
|
||||
if (_charsetDetector.Charset != null)
|
||||
{
|
||||
Encoding encoding = Encoding.GetEncoding(
|
||||
_charsetDetector.Charset
|
||||
);
|
||||
content = File.ReadAllText(found.Path, encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
content = File.ReadAllText(found.Path, Encoding.UTF8);
|
||||
}
|
||||
first.Lyrics.ParseLRC(content);
|
||||
|
||||
return first;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,9 @@ namespace BetterLyrics.WinUI3.Services.Settings
|
||||
public const int CoverOverlayOpacity = 100; // 1.0
|
||||
public const int CoverOverlayBlurAmount = 200;
|
||||
|
||||
// Album art
|
||||
public const int CoverImageRadius = 24;
|
||||
|
||||
// Lyrics
|
||||
public const int LyricsAlignmentType = 1; // Center
|
||||
public const int LyricsBlurAmount = 0;
|
||||
@@ -36,5 +39,6 @@ namespace BetterLyrics.WinUI3.Services.Settings
|
||||
public const bool IsLyricsGlowEffectEnabled = false;
|
||||
public const bool IsLyricsDynamicGlowEffectEnabled = false;
|
||||
public const int LyricsFontColorType = 0; // Default
|
||||
public const int LyricsFontSelectedAccentColorIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ namespace BetterLyrics.WinUI3.Services.Settings
|
||||
public const string CoverOverlayOpacity = "CoverOverlayOpacity";
|
||||
public const string CoverOverlayBlurAmount = "CoverOverlayBlurAmount";
|
||||
|
||||
// Album art
|
||||
public const string CoverImageRadius = "CoverImageRadius";
|
||||
|
||||
// Lyrics
|
||||
public const string LyricsAlignmentType = "LyricsAlignmentType";
|
||||
public const string LyricsBlurAmount = "LyricsBlurAmount";
|
||||
@@ -35,5 +38,7 @@ namespace BetterLyrics.WinUI3.Services.Settings
|
||||
public const string IsLyricsGlowEffectEnabled = "IsLyricsGlowEffectEnabled";
|
||||
public const string IsLyricsDynamicGlowEffectEnabled = "IsLyricsDynamicGlowEffectEnabled";
|
||||
public const string LyricsFontColorType = "LyricsFontColorType";
|
||||
public const string LyricsFontSelectedAccentColorIndex =
|
||||
"LyricsFontSelectedAccentColorIndex";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +1,62 @@
|
||||
using BetterLyrics.WinUI3.Messages;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using DevWinUI;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using BetterLyrics.WinUI3.Messages;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using DevWinUI;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Newtonsoft.Json;
|
||||
using Windows.Globalization;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.Settings {
|
||||
public partial class SettingsService : ObservableObject {
|
||||
|
||||
namespace BetterLyrics.WinUI3.Services.Settings
|
||||
{
|
||||
public partial class SettingsService : ObservableObject
|
||||
{
|
||||
private readonly ApplicationDataContainer _localSettings;
|
||||
|
||||
public SettingsService() {
|
||||
|
||||
public SettingsService()
|
||||
{
|
||||
_localSettings = ApplicationData.Current.LocalSettings;
|
||||
|
||||
_musicLibraries = [.. JsonConvert.DeserializeObject<List<string>>(
|
||||
Get(SettingsKeys.MusicLibraries, SettingsDefaultValues.MusicLibraries)!)!];
|
||||
_musicLibraries =
|
||||
[
|
||||
.. JsonConvert.DeserializeObject<List<string>>(
|
||||
Get(SettingsKeys.MusicLibraries, SettingsDefaultValues.MusicLibraries)!
|
||||
)!,
|
||||
];
|
||||
|
||||
_musicLibraries.CollectionChanged += (_, _) => SaveMusicLibraries();
|
||||
}
|
||||
|
||||
private void WatchMultipleDirectories(IEnumerable<string> directories) {
|
||||
foreach (var dir in directories) {
|
||||
if (!Directory.Exists(dir)) continue;
|
||||
private void WatchMultipleDirectories(IEnumerable<string> directories)
|
||||
{
|
||||
foreach (var dir in directories)
|
||||
{
|
||||
if (!Directory.Exists(dir))
|
||||
continue;
|
||||
|
||||
var watcher = new FileSystemWatcher {
|
||||
var watcher = new FileSystemWatcher
|
||||
{
|
||||
Path = dir,
|
||||
Filter = "*.*",
|
||||
NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite,
|
||||
EnableRaisingEvents = true
|
||||
EnableRaisingEvents = true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void OnFileCreated(object sender, FileSystemEventArgs e) {
|
||||
App.DispatcherQueue.TryEnqueue(() =>
|
||||
{
|
||||
Debug.WriteLine($"[Created] {e.FullPath}");
|
||||
});
|
||||
private void OnFileCreated(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
App.DispatcherQueue.TryEnqueue(() => { });
|
||||
}
|
||||
|
||||
public bool IsFirstRun {
|
||||
public bool IsFirstRun
|
||||
{
|
||||
get => Get(SettingsKeys.IsFirstRun, SettingsDefaultValues.IsFirstRun);
|
||||
set => Set(SettingsKeys.IsFirstRun, value);
|
||||
}
|
||||
@@ -57,9 +65,11 @@ namespace BetterLyrics.WinUI3.Services.Settings {
|
||||
private bool _isRebuildingLyricsIndexDatabase = false;
|
||||
|
||||
// Theme
|
||||
public int Theme {
|
||||
public int Theme
|
||||
{
|
||||
get => Get(SettingsKeys.ThemeType, SettingsDefaultValues.ThemeType);
|
||||
set {
|
||||
set
|
||||
{
|
||||
Set(SettingsKeys.ThemeType, value);
|
||||
WeakReferenceMessenger.Default.Send(new ThemeChangedMessage((ElementTheme)value));
|
||||
}
|
||||
@@ -68,12 +78,13 @@ namespace BetterLyrics.WinUI3.Services.Settings {
|
||||
// Music
|
||||
private ObservableCollection<string> _musicLibraries;
|
||||
|
||||
public ObservableCollection<string> MusicLibraries {
|
||||
get {
|
||||
return _musicLibraries;
|
||||
}
|
||||
set {
|
||||
if (_musicLibraries != null) {
|
||||
public ObservableCollection<string> MusicLibraries
|
||||
{
|
||||
get { return _musicLibraries; }
|
||||
set
|
||||
{
|
||||
if (_musicLibraries != null)
|
||||
{
|
||||
_musicLibraries.CollectionChanged -= (_, _) => SaveMusicLibraries();
|
||||
}
|
||||
|
||||
@@ -84,17 +95,20 @@ namespace BetterLyrics.WinUI3.Services.Settings {
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveMusicLibraries() {
|
||||
private void SaveMusicLibraries()
|
||||
{
|
||||
Set(SettingsKeys.MusicLibraries, JsonConvert.SerializeObject(MusicLibraries.ToList()));
|
||||
}
|
||||
|
||||
|
||||
// Language
|
||||
public int Language {
|
||||
public int Language
|
||||
{
|
||||
get => Get(SettingsKeys.Language, SettingsDefaultValues.Language);
|
||||
set {
|
||||
set
|
||||
{
|
||||
Set(SettingsKeys.Language, value);
|
||||
switch ((Models.Language)Language) {
|
||||
switch ((Models.Language)Language)
|
||||
{
|
||||
case Models.Language.FollowSystem:
|
||||
ApplicationLanguages.PrimaryLanguageOverride = "";
|
||||
break;
|
||||
@@ -114,76 +128,138 @@ namespace BetterLyrics.WinUI3.Services.Settings {
|
||||
}
|
||||
|
||||
// Backdrop
|
||||
public int BackdropType {
|
||||
public int BackdropType
|
||||
{
|
||||
get => Get(SettingsKeys.BackdropType, SettingsDefaultValues.BackdropType);
|
||||
set {
|
||||
set
|
||||
{
|
||||
Set(SettingsKeys.BackdropType, value);
|
||||
WeakReferenceMessenger.Default.Send(new SystemBackdropChangedMessage((BackdropType)value));
|
||||
WeakReferenceMessenger.Default.Send(
|
||||
new SystemBackdropChangedMessage((BackdropType)value)
|
||||
);
|
||||
}
|
||||
}
|
||||
public bool IsCoverOverlayEnabled {
|
||||
get => Get(SettingsKeys.IsCoverOverlayEnabled, SettingsDefaultValues.IsCoverOverlayEnabled);
|
||||
public bool IsCoverOverlayEnabled
|
||||
{
|
||||
get =>
|
||||
Get(
|
||||
SettingsKeys.IsCoverOverlayEnabled,
|
||||
SettingsDefaultValues.IsCoverOverlayEnabled
|
||||
);
|
||||
set => Set(SettingsKeys.IsCoverOverlayEnabled, value);
|
||||
}
|
||||
public bool IsDynamicCoverOverlay {
|
||||
get => Get(SettingsKeys.IsDynamicCoverOverlay, SettingsDefaultValues.IsDynamicCoverOverlay);
|
||||
public bool IsDynamicCoverOverlay
|
||||
{
|
||||
get =>
|
||||
Get(
|
||||
SettingsKeys.IsDynamicCoverOverlay,
|
||||
SettingsDefaultValues.IsDynamicCoverOverlay
|
||||
);
|
||||
set => Set(SettingsKeys.IsDynamicCoverOverlay, value);
|
||||
}
|
||||
public int CoverOverlayOpacity {
|
||||
public int CoverOverlayOpacity
|
||||
{
|
||||
get => Get(SettingsKeys.CoverOverlayOpacity, SettingsDefaultValues.CoverOverlayOpacity);
|
||||
set => Set(SettingsKeys.CoverOverlayOpacity, value);
|
||||
}
|
||||
public int CoverOverlayBlurAmount {
|
||||
get => Get(SettingsKeys.CoverOverlayBlurAmount, SettingsDefaultValues.CoverOverlayBlurAmount);
|
||||
public int CoverOverlayBlurAmount
|
||||
{
|
||||
get =>
|
||||
Get(
|
||||
SettingsKeys.CoverOverlayBlurAmount,
|
||||
SettingsDefaultValues.CoverOverlayBlurAmount
|
||||
);
|
||||
set => Set(SettingsKeys.CoverOverlayBlurAmount, value);
|
||||
}
|
||||
|
||||
// Album art
|
||||
public int CoverImageRadius
|
||||
{
|
||||
get => Get(SettingsKeys.CoverImageRadius, SettingsDefaultValues.CoverImageRadius);
|
||||
set => Set(SettingsKeys.CoverImageRadius, value);
|
||||
}
|
||||
|
||||
// Lyrics
|
||||
public int LyricsAlignmentType {
|
||||
public int LyricsAlignmentType
|
||||
{
|
||||
get => Get(SettingsKeys.LyricsAlignmentType, SettingsDefaultValues.LyricsAlignmentType);
|
||||
set => Set(SettingsKeys.LyricsAlignmentType, value);
|
||||
}
|
||||
public int LyricsBlurAmount {
|
||||
public int LyricsBlurAmount
|
||||
{
|
||||
get => Get(SettingsKeys.LyricsBlurAmount, SettingsDefaultValues.LyricsBlurAmount);
|
||||
set => Set(SettingsKeys.LyricsBlurAmount, value);
|
||||
}
|
||||
public int LyricsVerticalEdgeOpacity {
|
||||
get => Get(SettingsKeys.LyricsVerticalEdgeOpacity, SettingsDefaultValues.LyricsVerticalEdgeOpacity);
|
||||
public int LyricsVerticalEdgeOpacity
|
||||
{
|
||||
get =>
|
||||
Get(
|
||||
SettingsKeys.LyricsVerticalEdgeOpacity,
|
||||
SettingsDefaultValues.LyricsVerticalEdgeOpacity
|
||||
);
|
||||
set => Set(SettingsKeys.LyricsVerticalEdgeOpacity, value);
|
||||
}
|
||||
public float LyricsLineSpacingFactor {
|
||||
get => Get(SettingsKeys.LyricsLineSpacingFactor, SettingsDefaultValues.LyricsLineSpacingFactor);
|
||||
public float LyricsLineSpacingFactor
|
||||
{
|
||||
get =>
|
||||
Get(
|
||||
SettingsKeys.LyricsLineSpacingFactor,
|
||||
SettingsDefaultValues.LyricsLineSpacingFactor
|
||||
);
|
||||
set => Set(SettingsKeys.LyricsLineSpacingFactor, value);
|
||||
}
|
||||
public int LyricsFontSize {
|
||||
public int LyricsFontSize
|
||||
{
|
||||
get => Get(SettingsKeys.LyricsFontSize, SettingsDefaultValues.LyricsFontSize);
|
||||
set => Set(SettingsKeys.LyricsFontSize, value);
|
||||
}
|
||||
public bool IsLyricsGlowEffectEnabled {
|
||||
get => Get(SettingsKeys.IsLyricsGlowEffectEnabled, SettingsDefaultValues.IsLyricsGlowEffectEnabled);
|
||||
public bool IsLyricsGlowEffectEnabled
|
||||
{
|
||||
get =>
|
||||
Get(
|
||||
SettingsKeys.IsLyricsGlowEffectEnabled,
|
||||
SettingsDefaultValues.IsLyricsGlowEffectEnabled
|
||||
);
|
||||
set => Set(SettingsKeys.IsLyricsGlowEffectEnabled, value);
|
||||
}
|
||||
public bool IsLyricsDynamicGlowEffectEnabled {
|
||||
get => Get(SettingsKeys.IsLyricsDynamicGlowEffectEnabled, SettingsDefaultValues.IsLyricsDynamicGlowEffectEnabled);
|
||||
public bool IsLyricsDynamicGlowEffectEnabled
|
||||
{
|
||||
get =>
|
||||
Get(
|
||||
SettingsKeys.IsLyricsDynamicGlowEffectEnabled,
|
||||
SettingsDefaultValues.IsLyricsDynamicGlowEffectEnabled
|
||||
);
|
||||
set => Set(SettingsKeys.IsLyricsDynamicGlowEffectEnabled, value);
|
||||
}
|
||||
public int LyricsFontColorType {
|
||||
public int LyricsFontColorType
|
||||
{
|
||||
get => Get(SettingsKeys.LyricsFontColorType, SettingsDefaultValues.LyricsFontColorType);
|
||||
set => Set(SettingsKeys.LyricsFontColorType, value);
|
||||
}
|
||||
public int LyricsFontSelectedAccentColorIndex
|
||||
{
|
||||
get =>
|
||||
Get(
|
||||
SettingsKeys.LyricsFontSelectedAccentColorIndex,
|
||||
SettingsDefaultValues.LyricsFontSelectedAccentColorIndex
|
||||
);
|
||||
set => Set(SettingsKeys.LyricsFontSelectedAccentColorIndex, value);
|
||||
}
|
||||
|
||||
private T? Get<T>(string key, T? defaultValue = default) {
|
||||
if (_localSettings.Values.TryGetValue(key, out object? value)) {
|
||||
private T? Get<T>(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<T>(string key, T value, [CallerMemberName] string? propertyName = null) {
|
||||
private void Set<T>(string key, T value, [CallerMemberName] string? propertyName = null)
|
||||
{
|
||||
_localSettings.Values[key] = value;
|
||||
OnPropertyChanged(propertyName);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@
|
||||
<data name="SettingsPageLyricsEffect.Text" xml:space="preserve">
|
||||
<value>Lyrics effect</value>
|
||||
</data>
|
||||
<data name="SettingsPageAlbum.Text" xml:space="preserve">
|
||||
<data name="SettingsPageAlbumOverlay.Text" xml:space="preserve">
|
||||
<value>Album background</value>
|
||||
</data>
|
||||
<data name="SettingsPageAbout.Text" xml:space="preserve">
|
||||
@@ -363,4 +363,10 @@
|
||||
<data name="SettingsPageLyricsFontColorDominant.Content" xml:space="preserve">
|
||||
<value>Album art accent color</value>
|
||||
</data>
|
||||
<data name="SettingsPageAlbumStyle.Text" xml:space="preserve">
|
||||
<value>Album art style</value>
|
||||
</data>
|
||||
<data name="SettingsPageAlbumRadius.Header" xml:space="preserve">
|
||||
<value>Corner radius</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -279,7 +279,7 @@
|
||||
<data name="SettingsPageLyricsEffect.Text" xml:space="preserve">
|
||||
<value>歌词效果</value>
|
||||
</data>
|
||||
<data name="SettingsPageAlbum.Text" xml:space="preserve">
|
||||
<data name="SettingsPageAlbumOverlay.Text" xml:space="preserve">
|
||||
<value>专辑背景</value>
|
||||
</data>
|
||||
<data name="SettingsPageAbout.Text" xml:space="preserve">
|
||||
@@ -363,4 +363,10 @@
|
||||
<data name="SettingsPageLyricsFontColorDominant.Content" xml:space="preserve">
|
||||
<value>专辑强调色</value>
|
||||
</data>
|
||||
<data name="SettingsPageAlbumStyle.Text" xml:space="preserve">
|
||||
<value>专辑封面样式</value>
|
||||
</data>
|
||||
<data name="SettingsPageAlbumRadius.Header" xml:space="preserve">
|
||||
<value>圆角半径</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -279,7 +279,7 @@
|
||||
<data name="SettingsPageLyricsEffect.Text" xml:space="preserve">
|
||||
<value>歌詞效果</value>
|
||||
</data>
|
||||
<data name="SettingsPageAlbum.Text" xml:space="preserve">
|
||||
<data name="SettingsPageAlbumOverlay.Text" xml:space="preserve">
|
||||
<value>專輯背景</value>
|
||||
</data>
|
||||
<data name="SettingsPageAbout.Text" xml:space="preserve">
|
||||
@@ -363,4 +363,10 @@
|
||||
<data name="SettingsPageLyricsFontColorDominant.Content" xml:space="preserve">
|
||||
<value>專輯強調色</value>
|
||||
</data>
|
||||
<data name="SettingsPageAlbumStyle.Text" xml:space="preserve">
|
||||
<value>專輯封面樣式</value>
|
||||
</data>
|
||||
<data name="SettingsPageAlbumRadius.Header" xml:space="preserve">
|
||||
<value>圓角半徑</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -28,10 +28,11 @@ using static CommunityToolkit.WinUI.Animations.Expressions.ExpressionValues;
|
||||
|
||||
namespace BetterLyrics.WinUI3.ViewModels
|
||||
{
|
||||
public partial class MainViewModel(SettingsService settingsService) : ObservableObject
|
||||
public partial class MainViewModel(
|
||||
SettingsService settingsService,
|
||||
DatabaseService databaseService
|
||||
) : ObservableObject
|
||||
{
|
||||
private readonly CharsetDetector _charsetDetector = new();
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isAnyMusicSessionExisted = false;
|
||||
|
||||
@@ -67,12 +68,13 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
private readonly Helper.ColorThief _colorThief = new();
|
||||
|
||||
private readonly SettingsService _settingsService = settingsService;
|
||||
private readonly DatabaseService _databaseService = databaseService;
|
||||
|
||||
public List<LyricsLine> GetLyrics(Track? track)
|
||||
{
|
||||
List<LyricsLine> result = [];
|
||||
|
||||
var lyricsPhrases = track?.Lyrics.SynchronizedLyrics;
|
||||
var lyricsPhrases = track?.Lyrics?.SynchronizedLyrics;
|
||||
|
||||
if (lyricsPhrases?.Count > 0)
|
||||
{
|
||||
@@ -126,91 +128,6 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<Track?> FindTrackFromDirectories(
|
||||
IEnumerable<string> directories,
|
||||
GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps
|
||||
)
|
||||
{
|
||||
Track? finalResult = null;
|
||||
|
||||
if (mediaProps == null || mediaProps.Title == null || mediaProps.Artist == null)
|
||||
return finalResult;
|
||||
|
||||
finalResult = new() { Title = mediaProps.Title, Artist = mediaProps.Artist };
|
||||
|
||||
bool coverFound = false;
|
||||
bool lyricsFound = false;
|
||||
|
||||
if (mediaProps.Thumbnail is IRandomAccessStreamReference streamReference)
|
||||
{
|
||||
coverFound = true;
|
||||
PictureInfo pictureInfo = PictureInfo.fromBinaryData(
|
||||
await ImageHelper.ToByteArrayAsync(streamReference)
|
||||
);
|
||||
finalResult.EmbeddedPictures.Add(pictureInfo);
|
||||
}
|
||||
|
||||
foreach (var dir in directories)
|
||||
{
|
||||
if (!Directory.Exists(dir))
|
||||
continue;
|
||||
|
||||
foreach (
|
||||
var file in Directory.EnumerateFiles(dir, "*.*", SearchOption.AllDirectories)
|
||||
)
|
||||
{
|
||||
string content = File.ReadAllText(file);
|
||||
var result = new Track(content);
|
||||
|
||||
if (
|
||||
result.Title.Contains(mediaProps.Title)
|
||||
&& result.Artist.Contains(mediaProps.Artist)
|
||||
)
|
||||
{
|
||||
if (!coverFound && result.EmbeddedPictures.Count > 0)
|
||||
{
|
||||
coverFound = true;
|
||||
finalResult.EmbeddedPictures.AddRange(result.EmbeddedPictures);
|
||||
}
|
||||
|
||||
if (!lyricsFound && result.Lyrics != null)
|
||||
{
|
||||
lyricsFound = true;
|
||||
finalResult.Lyrics = result.Lyrics;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lyricsFound && file.EndsWith(".lrc"))
|
||||
{
|
||||
using (FileStream fs = File.OpenRead(file))
|
||||
{
|
||||
_charsetDetector.Feed(fs);
|
||||
_charsetDetector.DataEnd();
|
||||
}
|
||||
|
||||
if (_charsetDetector.Charset != null)
|
||||
{
|
||||
Encoding encoding = Encoding.GetEncoding(_charsetDetector.Charset);
|
||||
content = File.ReadAllText(file, encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
content = File.ReadAllText(file, Encoding.UTF8);
|
||||
}
|
||||
|
||||
lyricsFound = true;
|
||||
finalResult.Lyrics = new();
|
||||
finalResult.Lyrics.ParseLRC(content);
|
||||
}
|
||||
|
||||
if (coverFound && lyricsFound)
|
||||
return finalResult;
|
||||
}
|
||||
}
|
||||
|
||||
return finalResult;
|
||||
}
|
||||
|
||||
public async Task<(List<LyricsLine>, SoftwareBitmap?, uint, uint)> SetSongInfoAsync(
|
||||
GlobalSystemMediaTransportControlsSessionMediaProperties? mediaProps
|
||||
)
|
||||
@@ -224,10 +141,23 @@ namespace BetterLyrics.WinUI3.ViewModels
|
||||
|
||||
IRandomAccessStream? stream = null;
|
||||
|
||||
var track = await FindTrackFromDirectories(_settingsService.MusicLibraries, mediaProps);
|
||||
var track = _databaseService.GetMusicMetadata(mediaProps);
|
||||
|
||||
if (track?.EmbeddedPictures?[0].PictureData is byte[] bytes)
|
||||
stream = await ImageHelper.GetStreamFromBytesAsync(bytes);
|
||||
if (mediaProps?.Thumbnail is IRandomAccessStreamReference reference)
|
||||
{
|
||||
stream = await reference.OpenReadAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (track?.EmbeddedPictures.Count > 0)
|
||||
{
|
||||
var bytes = track.EmbeddedPictures[0].PictureData;
|
||||
if (bytes != null)
|
||||
{
|
||||
stream = await Helper.ImageHelper.GetStreamFromBytesAsync(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set cover image and dominant colors
|
||||
if (stream == null)
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
public sealed partial class MainPage : Page
|
||||
{
|
||||
public MainViewModel ViewModel => (MainViewModel)DataContext;
|
||||
private readonly SettingsService _settingsService;
|
||||
public SettingsService SettingsService { get; set; }
|
||||
|
||||
private List<LyricsLine> _lyricsLines = [];
|
||||
|
||||
@@ -101,24 +101,21 @@ namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
_queueTimer = _dispatcherQueue.CreateTimer();
|
||||
|
||||
_logger = Ioc.Default.GetService<ILogger<MainPage>>()!;
|
||||
SettingsService = Ioc.Default.GetService<SettingsService>()!;
|
||||
DataContext = Ioc.Default.GetService<MainViewModel>();
|
||||
|
||||
SettingsService.PropertyChanged += SettingsService_PropertyChanged;
|
||||
ViewModel.PropertyChanged += ViewModel_PropertyChanged;
|
||||
|
||||
SetLyricsColor();
|
||||
|
||||
_settingsService = Ioc.Default.GetService<SettingsService>()!;
|
||||
|
||||
if (_settingsService.IsFirstRun)
|
||||
if (SettingsService.IsFirstRun)
|
||||
{
|
||||
WelcomeTeachingTip.IsOpen = true;
|
||||
}
|
||||
|
||||
_settingsService.PropertyChanged += SettingsService_PropertyChanged;
|
||||
|
||||
DataContext = Ioc.Default.GetService<MainViewModel>();
|
||||
|
||||
ViewModel.PropertyChanged += ViewModel_PropertyChanged;
|
||||
|
||||
_queueTimer = _dispatcherQueue.CreateTimer();
|
||||
}
|
||||
|
||||
private async Task ForceToScrollToCurrentPlayingLineAsync()
|
||||
@@ -135,21 +132,28 @@ namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
switch (e.PropertyName)
|
||||
{
|
||||
case nameof(_settingsService.LyricsFontSize):
|
||||
case nameof(_settingsService.LyricsLineSpacingFactor):
|
||||
case nameof(SettingsService.LyricsFontSize):
|
||||
case nameof(SettingsService.LyricsLineSpacingFactor):
|
||||
LayoutLyrics();
|
||||
await ForceToScrollToCurrentPlayingLineAsync();
|
||||
break;
|
||||
case nameof(_settingsService.IsRebuildingLyricsIndexDatabase):
|
||||
if (!_settingsService.IsRebuildingLyricsIndexDatabase)
|
||||
case nameof(SettingsService.IsRebuildingLyricsIndexDatabase):
|
||||
if (!SettingsService.IsRebuildingLyricsIndexDatabase)
|
||||
{
|
||||
CurrentSession_MediaPropertiesChanged(_currentSession, null);
|
||||
}
|
||||
break;
|
||||
case nameof(_settingsService.Theme):
|
||||
case nameof(SettingsService.Theme):
|
||||
case nameof(SettingsService.LyricsFontColorType):
|
||||
case nameof(SettingsService.LyricsFontSelectedAccentColorIndex):
|
||||
await Task.Delay(1);
|
||||
SetLyricsColor();
|
||||
break;
|
||||
case nameof(SettingsService.CoverImageRadius):
|
||||
CoverImageGrid.CornerRadius = new CornerRadius(
|
||||
SettingsService.CoverImageRadius / 100f * (CoverImageGrid.ActualHeight / 2)
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -172,7 +176,19 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
private void SetLyricsColor()
|
||||
{
|
||||
_lyricsColor = ((SolidColorBrush)LyricsCanvas.Foreground).Color;
|
||||
switch ((LyricsFontColorType)SettingsService.LyricsFontColorType)
|
||||
{
|
||||
case LyricsFontColorType.Default:
|
||||
_lyricsColor = ((SolidColorBrush)LyricsCanvas.Foreground).Color;
|
||||
break;
|
||||
case LyricsFontColorType.Dominant:
|
||||
_lyricsColor = ViewModel.CoverImageDominantColors[
|
||||
SettingsService.LyricsFontSelectedAccentColorIndex
|
||||
];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private async void InitMediaManager()
|
||||
@@ -391,7 +407,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
var b = _lyricsColor.B;
|
||||
|
||||
// Draw (dynamic) cover image as the very first layer
|
||||
if (_settingsService.IsCoverOverlayEnabled && _coverSoftwareBitmap != null)
|
||||
if (SettingsService.IsCoverOverlayEnabled && _coverSoftwareBitmap != null)
|
||||
{
|
||||
DrawCoverImage(sender, ds);
|
||||
}
|
||||
@@ -406,7 +422,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
using var glowedLyrics = new CanvasCommandList(sender);
|
||||
using (var glowedLyricsDs = glowedLyrics.CreateDrawingSession())
|
||||
{
|
||||
if (_settingsService.IsLyricsGlowEffectEnabled)
|
||||
if (SettingsService.IsLyricsGlowEffectEnabled)
|
||||
{
|
||||
glowedLyricsDs.DrawImage(
|
||||
new GaussianBlurEffect
|
||||
@@ -432,7 +448,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
// Mock gradient blurred lyrics layer
|
||||
using var combinedBlurredLyrics = new CanvasCommandList(sender);
|
||||
using var combinedBlurredLyricsDs = combinedBlurredLyrics.CreateDrawingSession();
|
||||
if (_settingsService.LyricsBlurAmount == 0)
|
||||
if (SettingsService.LyricsBlurAmount == 0)
|
||||
{
|
||||
combinedBlurredLyricsDs.DrawImage(glowedLyrics);
|
||||
}
|
||||
@@ -446,7 +462,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
Source = glowedLyrics,
|
||||
BlurAmount = (float)(
|
||||
_settingsService.LyricsBlurAmount * (1 - i / (0.5 - step))
|
||||
SettingsService.LyricsBlurAmount * (1 - i / (0.5 - step))
|
||||
),
|
||||
Optimization = EffectOptimization.Quality,
|
||||
BorderMode = EffectBorderMode.Soft,
|
||||
@@ -483,7 +499,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
maskedCombinedBlurredLyrics.CreateDrawingSession()
|
||||
)
|
||||
{
|
||||
if (_settingsService.LyricsVerticalEdgeOpacity == 100)
|
||||
if (SettingsService.LyricsVerticalEdgeOpacity == 100)
|
||||
{
|
||||
maskedCombinedBlurredLyricsDs.DrawImage(combinedBlurredLyrics);
|
||||
}
|
||||
@@ -538,7 +554,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
float centerX = position.X;
|
||||
float centerY = position.Y + (float)line.TextLayout.LayoutBounds.Height / 2;
|
||||
|
||||
switch ((LyricsAlignmentType)_settingsService.LyricsAlignmentType)
|
||||
switch ((LyricsAlignmentType)SettingsService.LyricsAlignmentType)
|
||||
{
|
||||
case LyricsAlignmentType.Left:
|
||||
line.TextLayout.HorizontalAlignment = CanvasHorizontalAlignment.Left;
|
||||
@@ -632,10 +648,10 @@ namespace BetterLyrics.WinUI3.Views
|
||||
|
||||
using var coverOverlayEffect = new OpacityEffect
|
||||
{
|
||||
Opacity = _settingsService.CoverOverlayOpacity / 100f,
|
||||
Opacity = SettingsService.CoverOverlayOpacity / 100f,
|
||||
Source = new GaussianBlurEffect
|
||||
{
|
||||
BlurAmount = _settingsService.CoverOverlayBlurAmount,
|
||||
BlurAmount = SettingsService.CoverOverlayBlurAmount,
|
||||
Source = new ScaleEffect
|
||||
{
|
||||
InterpolationMode = CanvasImageInterpolation.HighQualityCubic,
|
||||
@@ -664,9 +680,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
byte b
|
||||
)
|
||||
{
|
||||
byte verticalEdgeAlpha = (byte)(
|
||||
255 * _settingsService.LyricsVerticalEdgeOpacity / 100f
|
||||
);
|
||||
byte verticalEdgeAlpha = (byte)(255 * SettingsService.LyricsVerticalEdgeOpacity / 100f);
|
||||
using var maskBrush = new CanvasLinearGradientBrush(
|
||||
control,
|
||||
[
|
||||
@@ -690,18 +704,18 @@ namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
_currentTime += args.Timing.ElapsedTime;
|
||||
|
||||
if (_settingsService.IsDynamicCoverOverlay)
|
||||
if (SettingsService.IsDynamicCoverOverlay)
|
||||
{
|
||||
_coverBitmapRotateAngle += _coverRotateSpeed;
|
||||
_coverBitmapRotateAngle %= MathF.PI * 2;
|
||||
}
|
||||
if (_settingsService.IsLyricsDynamicGlowEffectEnabled)
|
||||
if (SettingsService.IsLyricsDynamicGlowEffectEnabled)
|
||||
{
|
||||
_lyricsGlowEffectAngle += _lyricsGlowEffectSpeed;
|
||||
_lyricsGlowEffectAngle %= MathF.PI * 2;
|
||||
}
|
||||
|
||||
if (_settingsService.IsCoverOverlayEnabled && _coverSoftwareBitmap != null)
|
||||
if (SettingsService.IsCoverOverlayEnabled && _coverSoftwareBitmap != null)
|
||||
{
|
||||
var diagonal = Math.Sqrt(
|
||||
Math.Pow(_lyricsAreaWidth, 2) + Math.Pow(_lyricsAreaHeight, 2)
|
||||
@@ -850,7 +864,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
{
|
||||
using CanvasTextFormat textFormat = new()
|
||||
{
|
||||
FontSize = _settingsService.LyricsFontSize,
|
||||
FontSize = SettingsService.LyricsFontSize,
|
||||
HorizontalAlignment = CanvasHorizontalAlignment.Left,
|
||||
VerticalAlignment = CanvasVerticalAlignment.Top,
|
||||
FontWeight = FontWeights.Bold,
|
||||
@@ -876,7 +890,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
y +=
|
||||
(float)line.TextLayout.LayoutBounds.Height
|
||||
/ line.TextLayout.LineCount
|
||||
* (line.TextLayout.LineCount + _settingsService.LyricsLineSpacingFactor);
|
||||
* (line.TextLayout.LineCount + SettingsService.LyricsLineSpacingFactor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1028,7 +1042,7 @@ namespace BetterLyrics.WinUI3.Views
|
||||
TeachingTipClosedEventArgs args
|
||||
)
|
||||
{
|
||||
_settingsService.IsFirstRun = false;
|
||||
SettingsService.IsFirstRun = false;
|
||||
}
|
||||
|
||||
private void CoverArea_SizeChanged(object sender, SizeChangedEventArgs e)
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<TextBlock x:Uid="SettingsPageAlbum" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
<TextBlock x:Uid="SettingsPageAlbumOverlay" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsExpander
|
||||
x:Uid="SettingsPageCoverOverlay"
|
||||
@@ -196,6 +196,27 @@
|
||||
</controls:SettingsExpander.Items>
|
||||
</controls:SettingsExpander>
|
||||
|
||||
<TextBlock x:Uid="SettingsPageAlbumStyle" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageAlbumRadius" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock x:Uid="SettingsPageSliderPrefix" VerticalAlignment="Center" />
|
||||
<TextBlock VerticalAlignment="Center" Text="{x:Bind ViewModel.SettingsService.CoverImageRadius, Mode=OneWay}" />
|
||||
<TextBlock
|
||||
Margin="0,0,14,0"
|
||||
VerticalAlignment="Center"
|
||||
Text=" %" />
|
||||
<Slider
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
SnapsTo="Ticks"
|
||||
StepFrequency="2"
|
||||
TickFrequency="2"
|
||||
TickPlacement="Outside"
|
||||
Value="{x:Bind ViewModel.SettingsService.CoverImageRadius, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</controls:SettingsCard>
|
||||
|
||||
<TextBlock x:Uid="SettingsPageLyricsStyle" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
|
||||
|
||||
<controls:SettingsCard x:Uid="SettingsPageLyricsAlignment" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
@@ -241,7 +262,7 @@
|
||||
<interactivity:ChangePropertyAction PropertyName="Visibility" Value="Visible" />
|
||||
</interactivity:DataTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
<GridView ItemsSource="{x:Bind ViewModel.MainViewModel.CoverImageDominantColors, Mode=OneWay}" SelectedIndex="0">
|
||||
<GridView ItemsSource="{x:Bind ViewModel.MainViewModel.CoverImageDominantColors, Mode=OneWay}" SelectedIndex="{x:Bind ViewModel.SettingsService.LyricsFontSelectedAccentColorIndex, Mode=TwoWay}">
|
||||
<GridView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<GridViewItem>
|
||||
|
||||
Reference in New Issue
Block a user