diff --git a/.drone.yml b/.drone.yml
index 7c67229..ac474fb 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -49,11 +49,10 @@ steps:
path: /docs
commands:
- /entrypoint.sh
- environment:
- NODOXYGEN: true
when:
branch:
- master
+ - dev-doxygen
event:
- push
- pull_request
diff --git a/Documentation/doxygen/Doxyfile b/Documentation/doxygen/Doxyfile
index 319cdef..06b6b8e 100644
--- a/Documentation/doxygen/Doxyfile
+++ b/Documentation/doxygen/Doxyfile
@@ -5,7 +5,7 @@ DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "Linaris"
PROJECT_NUMBER = 1.0.0
PROJECT_BRIEF = "Music player and manager"
-PROJECT_LOGO = appicon.svg
+PROJECT_LOGO = appicon.png
OUTPUT_DIRECTORY = /docs/doxygen
CREATE_SUBDIRS = NO
ALLOW_UNICODE_NAMES = NO
@@ -226,7 +226,7 @@ HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_EXTRA_STYLESHEET =
-HTML_EXTRA_FILES = images/CodeFirst.png images/clubinfo.png
+HTML_EXTRA_FILES =
HTML_COLORSTYLE_HUE = 215
HTML_COLORSTYLE_SAT = 45
HTML_COLORSTYLE_GAMMA = 240
diff --git a/Documentation/doxygen/appicon.png b/Documentation/doxygen/appicon.png
new file mode 100644
index 0000000..6d0b4f4
Binary files /dev/null and b/Documentation/doxygen/appicon.png differ
diff --git a/Images/logo.png b/Images/logo.png
new file mode 100644
index 0000000..32d4d00
Binary files /dev/null and b/Images/logo.png differ
diff --git a/README.md b/README.md
index 0199dc7..ab49c91 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Linaris_MAUI_SAE_201
+# Linaris
[](https://codefirst.iut.uca.fr/corentin.lemaire/Linaris_MAUI_SAE_201)
@@ -9,9 +9,15 @@
Linaris is a music and playlist management application, as well as a source of information about various popular albums and tracks. Our app is available on Windows and Android platforms through Visual Studio.
+## Trailer
+
+
+
+[](https://opencast.dsi.uca.fr/paella/ui/watch.html?id=41e87f72-a922-44a3-ad2c-1432540bace0)
+
## Documentation
-You can find all the documentation [here](https://codefirst.iut.uca.fr/git/corentin.lemaire/Linaris_MAUI_SAE_201/src/branch/dev-doc#user-content-documentation-1)
+You can find all the documentation [here](https://codefirst.iut.uca.fr/git/corentin.lemaire/Linaris_MAUI_SAE_201#documentation-1)
### Prerequisites
diff --git a/Sources/Console/Console.csproj b/Sources/Console/Console.csproj
index a816ead..b491ec4 100644
--- a/Sources/Console/Console.csproj
+++ b/Sources/Console/Console.csproj
@@ -13,10 +13,6 @@
-
-
-
-
diff --git a/Sources/Linaris/AlbumPage.xaml.cs b/Sources/Linaris/AlbumPage.xaml.cs
index 66b931f..9b0952f 100644
--- a/Sources/Linaris/AlbumPage.xaml.cs
+++ b/Sources/Linaris/AlbumPage.xaml.cs
@@ -1,3 +1,4 @@
+using CommunityToolkit.Maui.Core.Primitives;
using CommunityToolkit.Maui.Views;
using Model;
@@ -20,7 +21,7 @@ public partial class AlbumPage : ContentPage
{
InitializeComponent();
album = (Application.Current as App).Manager.CurrentAlbum;
- BindingContext = album;
+ BindingContext = Album;
}
@@ -33,9 +34,16 @@ public partial class AlbumPage : ContentPage
}
}
+ protected override void OnAppearing()
+ {
+ base.OnAppearing();
+ GetFooterData();
+ }
+
protected override void OnDisappearing()
{
base.OnDisappearing();
+ SetFooterData();
ContentView footer = this.FindByName("Footer");
var musicElement = footer?.FindByName("music");
if (musicElement != null)
@@ -43,4 +51,50 @@ public partial class AlbumPage : ContentPage
musicElement.Stop();
}
}
+
+ private void GetFooterData()
+ {
+ FooterPage FooterPage = (Application.Current as App).FooterPage;
+ Footer.CurrentPlaying = FooterPage.CurrentPlaying;
+ Footer.PlayImage = FooterPage.PlayImage;
+ Footer.LoopImage = FooterPage.LoopImage;
+ Footer.ShuffleImage = FooterPage.ShuffleImage;
+ Footer.Volume = FooterPage.Volume;
+ Footer.Position = FooterPage.Position;
+ Footer.Duration = FooterPage.Duration;
+ Footer.SliderPosition = FooterPage.SliderPosition;
+
+ // Place l'index de lecture de la musique à la position du slider
+ var musicElement = Footer?.FindByName("music");
+ musicElement.Dispatcher.StartTimer(TimeSpan.FromMilliseconds(100), () =>
+ {
+ musicElement.SeekTo((Application.Current as App).MusicPosition);
+ if ((Application.Current as App).MediaState == MediaElementState.Playing)
+ {
+ musicElement.Play();
+ }
+ else
+ {
+ musicElement.Pause();
+ }
+ return false;
+ });
+ }
+
+ public void SetFooterData()
+ {
+ FooterPage FooterPage = (Application.Current as App).FooterPage;
+ FooterPage.CurrentPlaying = (Application.Current as App).Manager.CurrentPlaying;
+ FooterPage.PlayImage = Footer.PlayImage;
+ FooterPage.LoopImage = Footer.LoopImage;
+ FooterPage.ShuffleImage = Footer.ShuffleImage;
+ FooterPage.Volume = Footer.Volume;
+ FooterPage.Position = Footer.Position;
+ FooterPage.Duration = Footer.Duration;
+ FooterPage.SliderPosition = Footer.SliderPosition;
+
+ var musicElement = Footer?.FindByName("music");
+ (Application.Current as App).MusicPosition = musicElement.Position;
+ (Application.Current as App).MediaState = musicElement.CurrentState;
+ }
}
\ No newline at end of file
diff --git a/Sources/Linaris/App.xaml b/Sources/Linaris/App.xaml
index ae057eb..d56b28b 100644
--- a/Sources/Linaris/App.xaml
+++ b/Sources/Linaris/App.xaml
@@ -12,3 +12,4 @@
+
\ No newline at end of file
diff --git a/Sources/Linaris/App.xaml.cs b/Sources/Linaris/App.xaml.cs
index e506791..008f26e 100644
--- a/Sources/Linaris/App.xaml.cs
+++ b/Sources/Linaris/App.xaml.cs
@@ -1,15 +1,27 @@
-using Model.Serialization;
+using CommunityToolkit.Maui.Core.Primitives;
+using Model.Serialization;
using Model.Stub;
+using System.Diagnostics;
namespace Linaris;
public partial class App : Application
{
- public Manager Manager = new(new LinqXmlSerialization(Path.Combine(FileSystem.Current.AppDataDirectory, "Data")));
+ public Manager Manager { get; set; }
+
+ public FooterPage FooterPage { get; set; }
+
+ public TimeSpan MusicPosition { get; set; }
+
+ public MediaElementState MediaState { get; set; }
public App()
{
InitializeComponent();
+ MusicPosition = TimeSpan.FromSeconds(0);
+ MediaState = MediaElementState.Paused;
+ Manager = new Manager(new LinqXmlSerialization(FileSystem.Current.AppDataDirectory));
+ FooterPage = new FooterPage();
MainPage = new AppShell();
}
diff --git a/Sources/Linaris/Converters.cs b/Sources/Linaris/Converters.cs
index f55ecc2..2189d2c 100644
--- a/Sources/Linaris/Converters.cs
+++ b/Sources/Linaris/Converters.cs
@@ -1,22 +1,21 @@
using System;
-namespace Linaris.Converters
+namespace Linaris.Converters;
+
+public class InverseBooleanConverter : IValueConverter
{
- public class InverseBooleanConverter : IValueConverter
+ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
- public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ if (value is bool boolValue)
{
- if (value is bool boolValue)
- {
- return !boolValue;
- }
-
- return value;
+ return !boolValue;
}
- public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
- {
- throw new NotImplementedException();
- }
+ return value;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+ {
+ return Convert(value, targetType, parameter, culture);
}
}
\ No newline at end of file
diff --git a/Sources/Linaris/EditPlaylistPage.xaml.cs b/Sources/Linaris/EditPlaylistPage.xaml.cs
index 2b52ba4..2a456af 100644
--- a/Sources/Linaris/EditPlaylistPage.xaml.cs
+++ b/Sources/Linaris/EditPlaylistPage.xaml.cs
@@ -38,12 +38,9 @@ public partial class EditPlaylistPage : ContentPage
return;
}
- if (sender is Image image)
+ if (sender is Image image && image.BindingContext is Playlist p)
{
- if (image.BindingContext is Playlist playlist)
- {
- playlist.ImageURL = result.FullPath;
- }
+ p.ImageURL = result.FullPath;
}
}
diff --git a/Sources/Linaris/FooterPage.xaml b/Sources/Linaris/FooterPage.xaml
index 38bd297..997f179 100644
--- a/Sources/Linaris/FooterPage.xaml
+++ b/Sources/Linaris/FooterPage.xaml
@@ -1,20 +1,40 @@
-
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Sources/Linaris/FooterPage.xaml.cs b/Sources/Linaris/FooterPage.xaml.cs
index dd59eca..78d2d9d 100644
--- a/Sources/Linaris/FooterPage.xaml.cs
+++ b/Sources/Linaris/FooterPage.xaml.cs
@@ -1,29 +1,178 @@
+using CommunityToolkit.Maui.Core.Primitives;
using Model;
using Model.Stub;
using System.ComponentModel;
+using System.Configuration;
using System.Runtime.CompilerServices;
namespace Linaris;
public partial class FooterPage : ContentView, INotifyPropertyChanged
{
+ public new event PropertyChangedEventHandler PropertyChanged;
- private readonly Manager Manager = (Application.Current as App).Manager;
+ private CustomTitle currentPlaying;
+
+ public CustomTitle CurrentPlaying
+ {
+ get => currentPlaying;
+ set
+ {
+ currentPlaying = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private string playImage = "play.png";
+
+ public string PlayImage
+ {
+ get => playImage;
+ set
+ {
+ playImage = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private string loopImage = "loop.png";
+
+ public string LoopImage
+ {
+ get => loopImage;
+ set
+ {
+ loopImage = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private string shuffleImage = "rdm.png";
+
+ public string ShuffleImage
+ {
+ get => shuffleImage;
+ set
+ {
+ shuffleImage = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private double volume = 1;
+
+ public double Volume
+ {
+ get => volume;
+ set
+ {
+ volume = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private string position = "00:00:00";
+
+ public string Position
+ {
+ get => position;
+ set
+ {
+ position = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private string duration = "00:00:00";
+
+ public string Duration
+ {
+ get => duration;
+ set
+ {
+ duration = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private double sliderPosition = 0;
+
+ public double SliderPosition
+ {
+ get => sliderPosition;
+ set
+ {
+ sliderPosition = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private readonly Manager manager = (Application.Current as App).Manager;
+
+ public Manager Manager
+ {
+ get => manager;
+ }
public FooterPage()
{
InitializeComponent();
- BindingContext = Manager.CurrentPlaying;
+
+ music.StateChanged += Music_StateChanged;
+ TimeSlider.ValueChanged += TimeSlider_ValueChanged;
+ VolumeSlider.ValueChanged += VolumeSlider_ValueChanged;
+ music.PositionChanged += Music_PositionChanged;
+ CurrentPlaying = Manager.CurrentPlaying;
+ BindingContext = this;
}
+ private void Music_PositionChanged(object sender, EventArgs e)
+ {
+ SliderPosition = music.Position.TotalSeconds / music.Duration.TotalSeconds;
+ Position = music.Position.ToString(@"hh\:mm\:ss");
+ Duration = music.Duration.ToString(@"hh\:mm\:ss");
+ }
+
+ private void VolumeSlider_ValueChanged(object sender, ValueChangedEventArgs e)
+ {
+ Volume = VolumeSlider.Value;
+ music.Volume = Volume;
+ }
+
+ private void TimeSlider_ValueChanged(object sender, ValueChangedEventArgs e)
+ {
+ if ((TimeSlider.Value * music.Duration.TotalSeconds) - music.Position.TotalSeconds <= 1 && (TimeSlider.Value * music.Duration.TotalSeconds) - music.Position.TotalSeconds >= -1)
+ {
+ return;
+ }
+ TimeSpan PositionTimeSpan = TimeSpan.FromSeconds(TimeSlider.Value * music.Duration.TotalSeconds);
+ music.SeekTo(PositionTimeSpan);
+ Position = music.Position.ToString(@"hh\:mm\:ss");
+ Duration = music.Duration.ToString(@"hh\:mm\:ss");
+ }
+
+ private void Music_StateChanged(object sender, MediaStateChangedEventArgs e)
+ {
+ if (music.CurrentState == MediaElementState.Paused || music.CurrentState == MediaElementState.Stopped)
+ {
+ PlayImage = "play.png";
+ }
+ else
+ {
+ PlayImage = "pause.png";
+ }
+ }
public void RewindButton_Clicked(object sender, EventArgs e)
{
if (Manager.CurrentPlaylist == null || Manager.CurrentPlaying == null) return;
Manager.PreviousTitle();
+ CurrentPlaying = Manager.CurrentPlaying;
Dispatcher.DispatchAsync(() =>
{
music.Source = Manager.CurrentPlaying.Path;
+ music.SeekTo(TimeSpan.FromSeconds(0));
+ Duration = music.Duration.ToString(@"hh\:mm\:ss");
});
}
@@ -31,29 +180,56 @@ public partial class FooterPage : ContentView, INotifyPropertyChanged
{
if (Manager.CurrentPlaylist == null || Manager.CurrentPlaying == null) return;
Manager.NextTitle();
+ CurrentPlaying = Manager.CurrentPlaying;
Dispatcher.DispatchAsync(() =>
{
music.Source = Manager.CurrentPlaying.Path;
+ music.SeekTo(TimeSpan.FromSeconds(0));
+ Duration = music.Duration.ToString(@"hh\:mm\:ss");
});
}
public void ShuffleButton_Clicked(object sender, EventArgs e)
{
Manager.Shuffle();
+ if (ShuffleImage == "rdm.png")
+ {
+ ShuffleImage = "rdm2.png";
+ } else {
+ ShuffleImage = "rdm.png";
+ }
}
public void LoopButton_Clicked(object sender, EventArgs e)
{
Manager.Loop();
+ if (LoopImage == "loop.png")
+ {
+ LoopImage = "loop2.png";
+ }
+ else
+ {
+ LoopImage = "loop.png";
+ }
}
public void OnCompleted(object sender, EventArgs e)
{
- if (Manager.CurrentPlaying == null) return;
- Manager.NextTitle();
- Dispatcher.DispatchAsync(() =>
+ NextButton_Clicked(sender, e);
+ }
+
+ public void PlayButton_Clicked(object sender, EventArgs e)
+ {
+ if (music.CurrentState == MediaElementState.Paused || music.CurrentState == MediaElementState.Stopped)
{
- music.Source = Manager.CurrentPlaying.Path;
- });
+ music.Play();
+ }
+ else
+ {
+ music.Pause();
+ }
}
+
+ protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
\ No newline at end of file
diff --git a/Sources/Linaris/InfoTitlePage.xaml.cs b/Sources/Linaris/InfoTitlePage.xaml.cs
index 1eb4768..679cb58 100644
--- a/Sources/Linaris/InfoTitlePage.xaml.cs
+++ b/Sources/Linaris/InfoTitlePage.xaml.cs
@@ -1,3 +1,4 @@
+using CommunityToolkit.Maui.Core.Primitives;
using CommunityToolkit.Maui.Views;
using Model;
@@ -27,9 +28,16 @@ public partial class InfoTitlePage : ContentPage
BindingContext = this;
}
+ protected override void OnAppearing()
+ {
+ base.OnAppearing();
+ GetFooterData();
+ }
+
protected override void OnDisappearing()
{
base.OnDisappearing();
+ SetFooterData();
ContentView footer = this.FindByName("Footer");
var musicElement = footer?.FindByName("music");
if (musicElement != null)
@@ -37,4 +45,50 @@ public partial class InfoTitlePage : ContentPage
musicElement.Stop();
}
}
+
+ private void GetFooterData()
+ {
+ FooterPage FooterPage = (Application.Current as App).FooterPage;
+ Footer.CurrentPlaying = FooterPage.CurrentPlaying;
+ Footer.PlayImage = FooterPage.PlayImage;
+ Footer.LoopImage = FooterPage.LoopImage;
+ Footer.ShuffleImage = FooterPage.ShuffleImage;
+ Footer.Volume = FooterPage.Volume;
+ Footer.Position = FooterPage.Position;
+ Footer.Duration = FooterPage.Duration;
+ Footer.SliderPosition = FooterPage.SliderPosition;
+
+ // Place l'index de lecture de la musique à la position du slider
+ var musicElement = Footer?.FindByName("music");
+ musicElement.Dispatcher.StartTimer(TimeSpan.FromMilliseconds(300), () =>
+ {
+ musicElement.SeekTo((Application.Current as App).MusicPosition);
+ if ((Application.Current as App).MediaState == MediaElementState.Playing)
+ {
+ musicElement.Play();
+ }
+ else
+ {
+ musicElement.Pause();
+ }
+ return false;
+ });
+ }
+
+ public void SetFooterData()
+ {
+ FooterPage FooterPage = (Application.Current as App).FooterPage;
+ FooterPage.CurrentPlaying = (Application.Current as App).Manager.CurrentPlaying;
+ FooterPage.PlayImage = Footer.PlayImage;
+ FooterPage.LoopImage = Footer.LoopImage;
+ FooterPage.ShuffleImage = Footer.ShuffleImage;
+ FooterPage.Volume = Footer.Volume;
+ FooterPage.Position = Footer.Position;
+ FooterPage.Duration = Footer.Duration;
+ FooterPage.SliderPosition = Footer.SliderPosition;
+
+ var musicElement = Footer?.FindByName("music");
+ (Application.Current as App).MusicPosition = musicElement.Position;
+ (Application.Current as App).MediaState = musicElement.CurrentState;
+ }
}
\ No newline at end of file
diff --git a/Sources/Linaris/Layout.xaml.cs b/Sources/Linaris/Layout.xaml.cs
index c116bb0..8cac82a 100644
--- a/Sources/Linaris/Layout.xaml.cs
+++ b/Sources/Linaris/Layout.xaml.cs
@@ -11,50 +11,21 @@ public partial class Layout : ContentView
private async void Go_Home(object sender, EventArgs e)
{
- StopMusic();
await Navigation.PopToRootAsync();
}
private async void Go_Playlists(object sender, EventArgs e)
{
- StopMusic();
await Navigation.PushAsync(new PlaylistsPage());
}
private async void Go_Back(object sender, EventArgs e)
{
- StopMusic();
await Navigation.PopAsync();
}
private async void Go_Files(object sender, EventArgs e)
{
- StopMusic();
await Navigation.PushAsync(new LocalFilesPage());
}
- private void StopMusic()
- {
- var parentPage = GetParentPage(this);
- if (parentPage == null) return;
- ContentView footer = parentPage.FindByName("Footer");
- var musicElement = footer?.FindByName("music");
- if (musicElement != null)
- {
- musicElement.Stop();
- }
- }
-
- private ContentPage GetParentPage(Element element)
- {
- Element parent = element?.Parent;
- while (parent != null)
- {
- if (parent is ContentPage contentPage)
- {
- return contentPage;
- }
- parent = parent.Parent;
- }
- return null;
- }
}
\ No newline at end of file
diff --git a/Sources/Linaris/Linaris.csproj b/Sources/Linaris/Linaris.csproj
index f954d66..bdee2a0 100644
--- a/Sources/Linaris/Linaris.csproj
+++ b/Sources/Linaris/Linaris.csproj
@@ -1,5 +1,4 @@

-
net7.0-android
$(TargetFrameworks);net7.0-windows10.0.19041.0
@@ -30,6 +29,16 @@
10.0.17763.0
10.0.17763.0
6.5
+ True
+ False
+ D9EF0E98B2CABE92C87A46ACC4954059B92B6346
+ SHA256
+ True
+ False
+ True
+ D:\Bureau
+ 24
+ fr
@@ -52,10 +61,8 @@
-
+
-
-
@@ -81,6 +88,9 @@
MSBuild:Compile
+
+ MSBuild:Compile
+
MSBuild:Compile
@@ -96,6 +106,9 @@
MSBuild:Compile
+
+ MSBuild:Compile
+
MSBuild:Compile
@@ -123,4 +136,6 @@
+
+
diff --git a/Sources/Linaris/LocalFilesPage.xaml b/Sources/Linaris/LocalFilesPage.xaml
index ca1ffb2..4f29c03 100644
--- a/Sources/Linaris/LocalFilesPage.xaml
+++ b/Sources/Linaris/LocalFilesPage.xaml
@@ -14,7 +14,7 @@
-
+
@@ -33,19 +33,19 @@
-
-
-
-
+
+
+
+
-
+
-
+
diff --git a/Sources/Linaris/LocalFilesPage.xaml.cs b/Sources/Linaris/LocalFilesPage.xaml.cs
index 291494a..4ebb1ad 100644
--- a/Sources/Linaris/LocalFilesPage.xaml.cs
+++ b/Sources/Linaris/LocalFilesPage.xaml.cs
@@ -1,7 +1,12 @@
+using CommunityToolkit.Maui.Core.Primitives;
using CommunityToolkit.Maui.Views;
+using Microsoft.Maui.Controls;
+using Microsoft.Maui.Platform;
using Model;
+using Model.Stub;
using System.Collections.ObjectModel;
using System.Diagnostics;
+using System.Globalization;
namespace Linaris;
@@ -31,19 +36,19 @@ public partial class LocalFilesPage : ContentPage
void ResetAll(object sender, EventArgs e)
{
- ResetSubMenus(sender, e);
+ ResetSubMenus();
}
- void ResetSubMenus(object sender, EventArgs e)
+ void ResetSubMenus()
{
foreach (var CustomTitle in customTitles)
{
CustomTitle.IsSubMenuVisible = false;
}
- ResetPlaylistMenu(sender, e);
+ ResetPlaylistMenu();
}
- void ResetPlaylistMenu(object sender, EventArgs e)
+ void ResetPlaylistMenu()
{
foreach (CustomTitle customTitle in CustomTitles)
{
@@ -87,11 +92,15 @@ public partial class LocalFilesPage : ContentPage
return;
}
- if (sender is Button button)
+ foreach (var result in results)
{
- foreach (var result in results)
+ string path = Path.Combine(FileSystem.Current.AppDataDirectory, "customs");
+ if (!Path.Exists(path)) Directory.CreateDirectory(path);
+ string fullPath = Path.Combine(path, result.FileName);
+ if (!File.Exists(fullPath))
{
- CustomTitle custom = new CustomTitle(result.FileName, "none.png", "", result.FullPath);
+ File.Copy(result.FullPath, fullPath);
+ CustomTitle custom = new(result.FileName, "none.png", "", fullPath);
if (!IsCustomTitleInCollection(custom))
{
AddCustomTitle(custom);
@@ -149,6 +158,8 @@ public partial class LocalFilesPage : ContentPage
{
(Application.Current as App).Manager.RemoveCustomTitle(titleToRemove);
customTitles.Remove(titleToRemove);
+ File.Delete(titleToRemove.Path);
+ (Application.Current as App).Manager.RemoveCustomTitleFromPlaylists(titleToRemove);
}
}
}
@@ -156,22 +167,20 @@ public partial class LocalFilesPage : ContentPage
// Show methods
- void ShowSubMenu(object sender, EventArgs e)
+ async void ShowSubMenu(object sender, EventArgs e)
{
- if (sender is Image image)
+ if (sender is Image image && image.BindingContext is CustomTitle customTitle)
{
- if (image.BindingContext is CustomTitle customTitle)
+ if (!customTitle.IsSubMenuVisible)
{
- if (!customTitle.IsSubMenuVisible)
- {
- ResetAll(sender, e);
- customTitle.IsSubMenuVisible = true;
- }
- else
- {
- ResetSubMenus(sender, e);
- }
+ ResetAll(sender, e);
+ customTitle.IsSubMenuVisible = true;
+ }
+ else
+ {
+ ResetSubMenus();
}
+ await MainScrollView.ScrollToAsync(image, ScrollToPosition.Center, true);
}
}
@@ -254,9 +263,17 @@ public partial class LocalFilesPage : ContentPage
return false;
}
+ protected override void OnAppearing()
+ {
+ base.OnAppearing();
+ GetFooterData();
+ }
+
protected override void OnDisappearing()
{
base.OnDisappearing();
+ ResetSubMenus();
+ SetFooterData();
ContentView footer = this.FindByName("Footer");
var musicElement = footer?.FindByName("music");
if (musicElement != null)
@@ -265,6 +282,55 @@ public partial class LocalFilesPage : ContentPage
}
}
+ private void GetFooterData()
+ {
+ FooterPage FooterPage = (Application.Current as App).FooterPage;
+ Footer.CurrentPlaying = FooterPage.CurrentPlaying;
+ Footer.PlayImage = FooterPage.PlayImage;
+ Footer.LoopImage = FooterPage.LoopImage;
+ Footer.ShuffleImage = FooterPage.ShuffleImage;
+ Footer.Volume = FooterPage.Volume;
+ Footer.Position = FooterPage.Position;
+ Footer.Duration = FooterPage.Duration;
+ Footer.SliderPosition = FooterPage.SliderPosition;
+
+ // Place l'index de lecture de la musique à la position du slider
+ var musicElement = Footer?.FindByName("music");
+ musicElement.Dispatcher.StartTimer(TimeSpan.FromMilliseconds(1000), () =>
+ {
+ musicElement.SeekTo((Application.Current as App).MusicPosition);
+ if ((Application.Current as App).MediaState == MediaElementState.Playing)
+ {
+ musicElement.Play();
+ }
+ else
+ {
+ musicElement.Pause();
+ }
+ return false;
+ });
+ }
+
+ public void SetFooterData()
+ {
+ FooterPage FooterPage = (Application.Current as App).FooterPage;
+ FooterPage.CurrentPlaying = (Application.Current as App).Manager.CurrentPlaying;
+ FooterPage.PlayImage = Footer.PlayImage;
+ FooterPage.LoopImage = Footer.LoopImage;
+ FooterPage.ShuffleImage = Footer.ShuffleImage;
+ FooterPage.Volume = Footer.Volume;
+ FooterPage.Position = Footer.Position;
+ FooterPage.Duration = Footer.Duration;
+ FooterPage.SliderPosition = Footer.SliderPosition;
+
+ var musicElement = Footer?.FindByName("music");
+ (Application.Current as App).MusicPosition = musicElement.Position;
+ (Application.Current as App).MediaState = musicElement.CurrentState;
+ }
+
+
+ // Others
+
private void Play(object sender, EventArgs e)
{
if (sender is Button button && button.BindingContext is CustomTitle customTitle)
@@ -275,7 +341,15 @@ public partial class LocalFilesPage : ContentPage
if (musicElement != null)
{
musicElement.Source = customTitle.Path;
+ musicElement.SeekTo(TimeSpan.FromSeconds(0));
+ musicElement.Play();
+ }
+ if (footer is FooterPage footerPage)
+ {
+ footerPage.CurrentPlaying = customTitle;
}
+ (Application.Current as App).Manager.CurrentPlaylist = null;
+ (Application.Current as App).Manager.CurrentPlaying = customTitle;
}
}
}
\ No newline at end of file
diff --git a/Sources/Linaris/MainPage.xaml.cs b/Sources/Linaris/MainPage.xaml.cs
index 6f88154..df5eb13 100644
--- a/Sources/Linaris/MainPage.xaml.cs
+++ b/Sources/Linaris/MainPage.xaml.cs
@@ -1,4 +1,5 @@
-using CommunityToolkit.Maui.Views;
+using CommunityToolkit.Maui.Core.Primitives;
+using CommunityToolkit.Maui.Views;
using Model;
using System.Collections.ObjectModel;
@@ -7,7 +8,7 @@ namespace Linaris;
public partial class MainPage : ContentPage
{
- private readonly ObservableCollection albums = (Application.Current as App).Manager.GetAlbums();
+ private readonly ObservableCollection albums;
public ObservableCollection Albums
{
@@ -17,24 +18,29 @@ public partial class MainPage : ContentPage
public MainPage()
{
InitializeComponent();
- BindingContext = this;
+ albums = (Application.Current as App).Manager.GetAlbums();
+ BindingContext = this;
}
- async void GoToAlbum(object sender, EventArgs e)
+ async void GoToAlbum(object sender, EventArgs e)
{
- if (sender is Image image)
+ if (sender is Image image && image.BindingContext is Album album)
{
- if (image.BindingContext is Album album)
- {
- (Application.Current as App).Manager.CurrentAlbum = album;
- await Navigation.PushAsync(new AlbumPage());
- }
+ (Application.Current as App).Manager.CurrentAlbum = album;
+ await Navigation.PushAsync(new AlbumPage());
}
}
+ protected override void OnAppearing()
+ {
+ base.OnAppearing();
+ GetFooterData();
+ }
+
protected override void OnDisappearing()
{
base.OnDisappearing();
+ SetFooterData();
ContentView footer = this.FindByName("Footer");
var musicElement = footer?.FindByName("music");
if (musicElement != null)
@@ -42,5 +48,51 @@ public partial class MainPage : ContentPage
musicElement.Stop();
}
}
+
+ private void GetFooterData()
+ {
+ FooterPage FooterPage = (Application.Current as App).FooterPage;
+ Footer.CurrentPlaying = FooterPage.CurrentPlaying;
+ Footer.PlayImage = FooterPage.PlayImage;
+ Footer.LoopImage = FooterPage.LoopImage;
+ Footer.ShuffleImage = FooterPage.ShuffleImage;
+ Footer.Volume = FooterPage.Volume;
+ Footer.Position = FooterPage.Position;
+ Footer.Duration = FooterPage.Duration;
+ Footer.SliderPosition = FooterPage.SliderPosition;
+
+ // Place l'index de lecture de la musique à la position du slider
+ var musicElement = Footer?.FindByName("music");
+ musicElement.Dispatcher.StartTimer(TimeSpan.FromMilliseconds(100), () =>
+ {
+ musicElement.SeekTo((Application.Current as App).MusicPosition);
+ if ((Application.Current as App).MediaState == MediaElementState.Playing)
+ {
+ musicElement.Play();
+ }
+ else
+ {
+ musicElement.Pause();
+ }
+ return false;
+ });
+ }
+
+ public void SetFooterData()
+ {
+ FooterPage FooterPage = (Application.Current as App).FooterPage;
+ FooterPage.CurrentPlaying = (Application.Current as App).Manager.CurrentPlaying;
+ FooterPage.PlayImage = Footer.PlayImage;
+ FooterPage.LoopImage = Footer.LoopImage;
+ FooterPage.ShuffleImage = Footer.ShuffleImage;
+ FooterPage.Volume = Footer.Volume;
+ FooterPage.Position = Footer.Position;
+ FooterPage.Duration = Footer.Duration;
+ FooterPage.SliderPosition = Footer.SliderPosition;
+
+ var musicElement = Footer?.FindByName("music");
+ (Application.Current as App).MusicPosition = musicElement.Position;
+ (Application.Current as App).MediaState = musicElement.CurrentState;
+ }
}
diff --git a/Sources/Linaris/Platforms/Windows/Package.appxmanifest b/Sources/Linaris/Platforms/Windows/Package.appxmanifest
index 095b582..93c4356 100644
--- a/Sources/Linaris/Platforms/Windows/Package.appxmanifest
+++ b/Sources/Linaris/Platforms/Windows/Package.appxmanifest
@@ -6,7 +6,7 @@
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
-
+
diff --git a/Sources/Linaris/PlaylistPage.xaml b/Sources/Linaris/PlaylistPage.xaml
index f51b4b0..2d01fb5 100644
--- a/Sources/Linaris/PlaylistPage.xaml
+++ b/Sources/Linaris/PlaylistPage.xaml
@@ -22,9 +22,9 @@
-
-
-
+
+
+
@@ -35,8 +35,8 @@
-
-
+
+
diff --git a/Sources/Linaris/PlaylistPage.xaml.cs b/Sources/Linaris/PlaylistPage.xaml.cs
index 26fc7cc..4282358 100644
--- a/Sources/Linaris/PlaylistPage.xaml.cs
+++ b/Sources/Linaris/PlaylistPage.xaml.cs
@@ -1,3 +1,4 @@
+using CommunityToolkit.Maui.Core.Primitives;
using CommunityToolkit.Maui.Views;
using Model;
using Model.Stub;
@@ -45,6 +46,12 @@ public partial class PlaylistPage : ContentPage
{
if (Manager.CurrentPlaying == null) return;
musicElement.Source = Manager.CurrentPlaying.Path;
+ musicElement.SeekTo(TimeSpan.FromSeconds(0));
+ musicElement.Play();
+ }
+ if (footer is FooterPage footerPage)
+ {
+ footerPage.CurrentPlaying = Manager.CurrentPlaying;
}
}
}
@@ -65,14 +72,28 @@ public partial class PlaylistPage : ContentPage
{
if (Manager.CurrentPlaying == null) return;
musicElement.Source = Manager.CurrentPlaying.Path;
+ musicElement.SeekTo(TimeSpan.FromSeconds(0));
+ musicElement.Play();
+ if (footer is FooterPage footerPage)
+ {
+ footerPage.ShuffleImage = "rdm2.png";
+ footerPage.CurrentPlaying = (Application.Current as App).Manager.CurrentPlaying;
+ }
}
}
}
}
+ protected override void OnAppearing()
+ {
+ base.OnAppearing();
+ GetFooterData();
+ }
+
protected override void OnDisappearing()
{
base.OnDisappearing();
+ SetFooterData();
ContentView footer = this.FindByName("Footer");
var musicElement = footer?.FindByName("music");
if (musicElement != null)
@@ -80,4 +101,50 @@ public partial class PlaylistPage : ContentPage
musicElement.Stop();
}
}
+
+ private void GetFooterData()
+ {
+ FooterPage FooterPage = (Application.Current as App).FooterPage;
+ Footer.CurrentPlaying = FooterPage.CurrentPlaying;
+ Footer.PlayImage = FooterPage.PlayImage;
+ Footer.LoopImage = FooterPage.LoopImage;
+ Footer.ShuffleImage = FooterPage.ShuffleImage;
+ Footer.Volume = FooterPage.Volume;
+ Footer.Position = FooterPage.Position;
+ Footer.Duration = FooterPage.Duration;
+ Footer.SliderPosition = FooterPage.SliderPosition;
+
+ // Place l'index de lecture de la musique à la position du slider
+ var musicElement = Footer?.FindByName("music");
+ musicElement.Dispatcher.StartTimer(TimeSpan.FromMilliseconds(100), () =>
+ {
+ musicElement.SeekTo((Application.Current as App).MusicPosition);
+ if ((Application.Current as App).MediaState == MediaElementState.Playing)
+ {
+ musicElement.Play();
+ }
+ else
+ {
+ musicElement.Pause();
+ }
+ return false;
+ });
+ }
+
+ public void SetFooterData()
+ {
+ FooterPage FooterPage = (Application.Current as App).FooterPage;
+ FooterPage.CurrentPlaying = (Application.Current as App).Manager.CurrentPlaying;
+ FooterPage.PlayImage = Footer.PlayImage;
+ FooterPage.LoopImage = Footer.LoopImage;
+ FooterPage.ShuffleImage = Footer.ShuffleImage;
+ FooterPage.Volume = Footer.Volume;
+ FooterPage.Position = Footer.Position;
+ FooterPage.Duration = Footer.Duration;
+ FooterPage.SliderPosition = Footer.SliderPosition;
+
+ var musicElement = Footer?.FindByName("music");
+ (Application.Current as App).MusicPosition = musicElement.Position;
+ (Application.Current as App).MediaState = musicElement.CurrentState;
+ }
}
\ No newline at end of file
diff --git a/Sources/Linaris/PlaylistsPage.xaml.cs b/Sources/Linaris/PlaylistsPage.xaml.cs
index 8fb4e68..d7e143f 100644
--- a/Sources/Linaris/PlaylistsPage.xaml.cs
+++ b/Sources/Linaris/PlaylistsPage.xaml.cs
@@ -1,3 +1,4 @@
+using CommunityToolkit.Maui.Core.Primitives;
using CommunityToolkit.Maui.Views;
using Model;
using System.Collections.ObjectModel;
@@ -114,9 +115,16 @@ public partial class PlaylistsPage : ContentPage
await Navigation.PushAsync(new PlaylistPage());
}
+ protected override void OnAppearing()
+ {
+ base.OnAppearing();
+ GetFooterData();
+ }
+
protected override void OnDisappearing()
{
base.OnDisappearing();
+ SetFooterData();
ContentView footer = this.FindByName("Footer");
var musicElement = footer?.FindByName("music");
if (musicElement != null)
@@ -124,4 +132,50 @@ public partial class PlaylistsPage : ContentPage
musicElement.Stop();
}
}
+
+ private void GetFooterData()
+ {
+ FooterPage FooterPage = (Application.Current as App).FooterPage;
+ Footer.CurrentPlaying = FooterPage.CurrentPlaying;
+ Footer.PlayImage = FooterPage.PlayImage;
+ Footer.LoopImage = FooterPage.LoopImage;
+ Footer.ShuffleImage = FooterPage.ShuffleImage;
+ Footer.Volume = FooterPage.Volume;
+ Footer.Position = FooterPage.Position;
+ Footer.Duration = FooterPage.Duration;
+ Footer.SliderPosition = FooterPage.SliderPosition;
+
+ // Place l'index de lecture de la musique à la position du slider
+ var musicElement = Footer?.FindByName("music");
+ musicElement.Dispatcher.StartTimer(TimeSpan.FromMilliseconds(100), () =>
+ {
+ musicElement.SeekTo((Application.Current as App).MusicPosition);
+ if ((Application.Current as App).MediaState == MediaElementState.Playing)
+ {
+ musicElement.Play();
+ }
+ else
+ {
+ musicElement.Pause();
+ }
+ return false;
+ });
+ }
+
+ public void SetFooterData()
+ {
+ FooterPage FooterPage = (Application.Current as App).FooterPage;
+ FooterPage.CurrentPlaying = (Application.Current as App).Manager.CurrentPlaying;
+ FooterPage.PlayImage = Footer.PlayImage;
+ FooterPage.LoopImage = Footer.LoopImage;
+ FooterPage.ShuffleImage = Footer.ShuffleImage;
+ FooterPage.Volume = Footer.Volume;
+ FooterPage.Position = Footer.Position;
+ FooterPage.Duration = Footer.Duration;
+ FooterPage.SliderPosition = Footer.SliderPosition;
+
+ var musicElement = Footer?.FindByName("music");
+ (Application.Current as App).MusicPosition = musicElement.Position;
+ (Application.Current as App).MediaState = musicElement.CurrentState;
+ }
}
\ No newline at end of file
diff --git a/Sources/Linaris/Resources/Images/loop2.png b/Sources/Linaris/Resources/Images/loop2.png
new file mode 100644
index 0000000..275c215
Binary files /dev/null and b/Sources/Linaris/Resources/Images/loop2.png differ
diff --git a/Sources/Linaris/Resources/Images/rdm2.png b/Sources/Linaris/Resources/Images/rdm2.png
new file mode 100644
index 0000000..3aa1ff1
Binary files /dev/null and b/Sources/Linaris/Resources/Images/rdm2.png differ
diff --git a/Sources/Linaris/Resources/Styles/Styles.xaml b/Sources/Linaris/Resources/Styles/Styles.xaml
index 57d8d92..68d4367 100644
--- a/Sources/Linaris/Resources/Styles/Styles.xaml
+++ b/Sources/Linaris/Resources/Styles/Styles.xaml
@@ -361,6 +361,100 @@
+
+
+
+
+
+
-
+
+
+