diff --git a/ClientHandler/Program.cs b/ClientHandler/Program.cs index 5f0e241e..e6b33ae4 100644 --- a/ClientHandler/Program.cs +++ b/ClientHandler/Program.cs @@ -160,4 +160,4 @@ public Task WaitForExitTaskAsync() }); } } -} +} \ No newline at end of file diff --git a/Package/Package.appxmanifest b/Package/Package.appxmanifest index 259f8673..01e49313 100644 --- a/Package/Package.appxmanifest +++ b/Package/Package.appxmanifest @@ -11,7 +11,7 @@ + Version="0.4.5.0" /> SD Launcher diff --git a/SDLauncher UWP/Dialogs/Login.xaml.cs b/SDLauncher UWP/Dialogs/Login.xaml.cs index e2d4fecd..5741476d 100644 --- a/SDLauncher UWP/Dialogs/Login.xaml.cs +++ b/SDLauncher UWP/Dialogs/Login.xaml.cs @@ -342,15 +342,6 @@ private void UpdateAccounts() } private void btnChooseAcc_Click(object sender, RoutedEventArgs e) { - for (int i = vars.Accounts.Count - 1; i >= 0; i--) - { - try - { - vars.Accounts[i].PropertyChanged -= Login_PropertyChanged; - } - catch { } - vars.Accounts[i].PropertyChanged += Login_PropertyChanged; - } ShowSelect(false, false); gridChoose.Visibility = Visibility.Visible; gridNew.Visibility = Visibility.Collapsed; @@ -358,10 +349,6 @@ private void btnChooseAcc_Click(object sender, RoutedEventArgs e) UpdateAccounts(); } - private void Login_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) - { - // UpdateAccounts(); - } private void btnBack_Click(object sender, RoutedEventArgs e) { diff --git a/SDLauncher UWP/Helpers/Labrinth.cs b/SDLauncher UWP/Helpers/Labrinth.cs index 62887dec..7c22a0a1 100644 --- a/SDLauncher UWP/Helpers/Labrinth.cs +++ b/SDLauncher UWP/Helpers/Labrinth.cs @@ -7,6 +7,10 @@ using System.Text; using System.Threading.Tasks; using System.Web; +using Windows.Foundation; +using Windows.Networking.BackgroundTransfer; +using Windows.Storage; +using Windows.UI.Xaml; namespace SDLauncher_UWP.Helpers { @@ -25,6 +29,8 @@ public class Labrinth { public event EventHandler StatusChanged = delegate { }; public event EventHandler UIChangeRequested = delegate { }; + public event EventHandler MainUIChangeRequested = delegate { }; + public event EventHandler ProgressChanged = delegate { }; public HttpClient Client = new HttpClient(); //ModrinthClient c = new ModrinthClient(); public void Test() @@ -38,19 +44,96 @@ private void UI(bool UI) { UIChangeRequested(this, new SDLauncher.UIChangeRequestedEventArgs(UI)); } - public async Task Search(string name, int? limit = null) + int DownloadTaskID; + public async void DownloadMod(LabrinthResults.DownloadManager.File file,CmlLib.Core.MinecraftPath mcPath) + { + DownloadTaskID = LittleHelp.AddTask("Download " + file.filename); + MainUIChangeRequested(this, new SDLauncher.UIChangeRequestedEventArgs(false)); + StorageFolder f = await StorageFolder.GetFolderFromPathAsync(mcPath.BasePath); + var m = await f.CreateFolderAsync("mods", CreationCollisionOption.OpenIfExists); + try + { + var mfile = await m.CreateFileAsync(file.filename, CreationCollisionOption.FailIfExists); + await mfile.DeleteAsync(); + ModrinthDownload(file.url, mcPath.BasePath + @"\mods\", file.filename); + } + catch + { + var r = await MessageBox.Show("Information", "The file \"" + file.filename + "\" already exists in the mod folder.\nDo you want to download and replace it ?", MessageBoxButtons.YesNo); + if (r == MessageBoxResults.Yes) + { + ModrinthDownload(file.url, m.Path, file.filename); + } + else + { + this.MainUIChangeRequested(this, new SDLauncher.UIChangeRequestedEventArgs(true)); + LittleHelp.CompleteTask(DownloadTaskID); + } + } + } + private async void ModrinthDownload(string link,string folderdir, string fileName) + { + try + { + Uri source = new Uri(link); + + var folder = await StorageFolder.GetFolderFromPathAsync(folderdir); + var file = await folder.CreateFileAsync( + fileName, + CreationCollisionOption.ReplaceExisting); + string path = file.Path; + file = null; + using (var client = new HttpClientDownloadWithProgress(link, path)) + { + client.ProgressChanged += (totalFileSize, totalBytesDownloaded, progressPercentage) => { + StatusChanged("Download " + fileName, new EventArgs()); + this.ProgressChanged(this, new SDLauncher.ProgressChangedEventArgs(currentProg: Convert.ToInt32(progressPercentage))); + if(progressPercentage == 100) + { + this.DownloadFileCompleted(); + client.Dispose(); + } + }; + + await client.StartDownload(); + } + + } + catch + { + + } + } + private void DownloadFileCompleted() + { + StatusChanged("Ready", new EventArgs()); + ProgressChanged(this, new SDLauncher.ProgressChangedEventArgs(currentProg:0)); + LittleHelp.CompleteTask(DownloadTaskID); + MainUIChangeRequested(this, new SDLauncher.UIChangeRequestedEventArgs(true)); + } + public async Task Search(string name, int? limit = null, LabrinthResults.SearchSortOptions sortOptions = LabrinthResults.SearchSortOptions.Relevance, LabrinthResults.SearchCategories[] categories = null) { int taskID = 0; UI(false); if (name == "") { StatusChanged("Getting Mods",new EventArgs()); - taskID = LittleHelp.AddTask("Getting Mods"); + taskID = LittleHelp.AddTask("Get Mods"); } else { - taskID = LittleHelp.AddTask("Searcging Store"); - StatusChanged("Searcging Store", new EventArgs()); + taskID = LittleHelp.AddTask("Search Store"); + StatusChanged("Searching Store", new EventArgs()); + } + string categouriesString = ""; + if(categories != null) + { + if (categories.Count() > 0) + { + categouriesString = string.Join("\"],[\"categories:", categories); + categouriesString = ",[\"categories:" + categouriesString + "\"]"; + categouriesString = categouriesString.ToLower(); + } } LabrinthResults.SearchResult s = null; try @@ -65,7 +148,7 @@ private void UI(bool UI) { l = "limit="; } - var json = await Util.DownloadText("https://api.modrinth.com/v2/search?query=" + q + "&facets=[[%22categories:fabric%22],[%22project_type:mod%22]]&" + l); + var json = await Util.DownloadText("https://api.modrinth.com/v2/search?query=" + q + "&index=" + sortOptions.ToString().ToLower() + "&facets=[[\"categories:fabric\"]" + categouriesString + ",[\"project_type:mod\"]]&" + l); s = JSONConverter.ConvertToLabrinthSearchResult(json); StatusChanged("Ready", new EventArgs()); UI(true); @@ -80,10 +163,13 @@ private void UI(bool UI) return null; } } - public async Task GetProject(string id) + public async Task GetProject(string id,bool UIChange = true) { - int taskID = LittleHelp.AddTask("Loading Mod"); - UI(false); + int taskID = LittleHelp.AddTask("Load Mod"); + if (UIChange) + { + UI(false); + } StatusChanged("Loading Mod",new EventArgs()); LabrinthResults.ModrinthProject s = null; try @@ -91,6 +177,36 @@ private void UI(bool UI) var json = await Util.DownloadText("https://api.modrinth.com/v2/project/" + id); s = JSONConverter.ConvertToLabrinthProject(json); StatusChanged("Ready", new EventArgs()); + if (UIChange) + { + UI(true); + } + LittleHelp.CompleteTask(taskID); + return s; + } + catch + { + StatusChanged("Ready", new EventArgs()); + if (UIChange) + { + UI(true); + } + LittleHelp.CompleteTask(taskID); + return null; + } + } + public async Task> GetVersions(string id) + { + int taskID = LittleHelp.AddTask("Load Download versionss"); + UI(false); + StatusChanged("Loading Mod downloads", new EventArgs()); + List s = null; + try + { + string link = "https://api.modrinth.com/v2/project/" + id + "/version"; + var json = await Util.DownloadText(link); + s = JSONConverter.ConvertDownloadLinksToCS(json); + StatusChanged("Ready", new EventArgs()); UI(true); LittleHelp.CompleteTask(taskID); return s; @@ -107,12 +223,47 @@ private void UI(bool UI) public class LabrinthResults { + public class DownloadManager + { + public class File + { + public Hashes hashes { get; set; } + public string url { get; set; } + public string filename { get; set; } + public bool primary { get; set; } + public int size { get; set; } + } + public class DownloadLink + { + public string id { get; set; } + public string project_id { get; set; } + public string author_id { get; set; } + public bool featured { get; set; } + public string name { get; set; } + public string version_number { get; set; } + public string changelog { get; set; } + public object changelog_url { get; set; } + public DateTime date_published { get; set; } + public int downloads { get; set; } + public string version_type { get; set; } + public List files { get; set; } + public List dependencies { get; set; } + public List game_versions { get; set; } + public List loaders { get; set; } + } + public class Hashes + { + public string sha512 { get; set; } + public string sha1 { get; set; } + } + } public enum SearchSortOptions { Relevance, Downloads, Follows, - Updated + Updated, + Newest } public enum SearchCategories diff --git a/SDLauncher UWP/Helpers/ModManager.cs b/SDLauncher UWP/Helpers/ModManager.cs index 89d6b56a..68cd6471 100644 --- a/SDLauncher UWP/Helpers/ModManager.cs +++ b/SDLauncher UWP/Helpers/ModManager.cs @@ -20,13 +20,15 @@ public class StoreItem public string Description { get; private set; } public async Task BigDescription() { - var mod = await vars.Launcher.Labrinth.GetProject(ProjectID); + var mod = await vars.Launcher.Labrinth.GetProject(ProjectID,false); return await Util.DownloadText(mod.body_url); } public string ProjectID { get; set; } public string Author { get; set; } public int Followers { get; set; } + public string FollowersString { get { return Followers.KiloFormat(); } } public int TotalDownloads { get; set; } + public string TotalDownloadsString { get { return TotalDownloads.KiloFormat(); } } public string[] SupportedVers { get; set; } @@ -44,60 +46,11 @@ public List SampleImages return b; } } - private List features; - public List Features - { - get - { - return features; - } - } public BitmapImage Icon; - public List ModDownloadLinks { get; set; } - public List ShaderDownloadLinks { get; set; } + public List DownloadLinks; public StoreItem(object Item, int iD) { - ModDownloadLinks = new List(); - ShaderDownloadLinks = new List(); - if (Item.GetType() == typeof(StoreManager.StoreShader)) - { - Type = StoreManager.Type.Shader; - var i = (StoreManager.StoreShader)Item; - this.Description = i.Description; - this.Name = i.Name; - this.sampleImages = new List(); - - if (i.SampleImages != null) - { - foreach (var item in i.SampleImages) - { - this.sampleImages.Add(item.Url); - } - } - try - { - this.Icon = new BitmapImage(new Uri(i.Icon)); - } - catch { } - - - features = new List(); - if (i.Features != null) - { - foreach (var item in i.Features) - { - features.Add(item.Name); - } - } - if (i.DownloadLinks != null) - { - foreach (var item in i.DownloadLinks) - { - ShaderDownloadLinks.Add(item); - } - } - } - else if(Item.GetType() == typeof(LabrinthResults.Hit)) + if(Item.GetType() == typeof(LabrinthResults.Hit)) { var hit = (LabrinthResults.Hit)Item; this.Name = hit.title; @@ -113,7 +66,7 @@ public StoreItem(object Item, int iD) { sampleImages.Add(item); } - + DownloadLinks = new List(); } ID = iD; } diff --git a/SDLauncher UWP/Helpers/SDLauncher.cs b/SDLauncher UWP/Helpers/SDLauncher.cs index ff519be5..995b374f 100644 --- a/SDLauncher UWP/Helpers/SDLauncher.cs +++ b/SDLauncher UWP/Helpers/SDLauncher.cs @@ -106,12 +106,24 @@ public SDLauncher() StoreManager = new StoreManager(); Labrinth = new Labrinth(); Labrinth.StatusChanged += Labrinth_StatusChanged; + Labrinth.MainUIChangeRequested += Labrinth_MainUIChangeRequested; + Labrinth.ProgressChanged += Labrinth_ProgressChanged; this.TasksHelper = new TasksHelper(); this.FileOrProgressChanged += SDLauncher_FileOrProgressChanged; } + private void Labrinth_ProgressChanged(object sender, ProgressChangedEventArgs e) + { + this.FileOrProgressChanged(sender, e); + } + + private void Labrinth_MainUIChangeRequested(object sender, UIChangeRequestedEventArgs e) + { + UI(e.UI); + } + private void SDLauncher_FileOrProgressChanged(object sender, ProgressChangedEventArgs e) { string stats = ""; diff --git a/SDLauncher UWP/Helpers/ServerStatusInfo.cs b/SDLauncher UWP/Helpers/ServerStatusInfo.cs index c7913048..6732ddf1 100644 --- a/SDLauncher UWP/Helpers/ServerStatusInfo.cs +++ b/SDLauncher UWP/Helpers/ServerStatusInfo.cs @@ -7,21 +7,6 @@ namespace SDLauncher_UWP.Helpers { - public static class JSONConverter - { - public static ServerStatusInfo.Root ConvertToServerStatus(string json) - { - return JsonConvert.DeserializeObject(json); - } - public static LabrinthResults.SearchResult ConvertToLabrinthSearchResult(string json) - { - return JsonConvert.DeserializeObject(json); - } - public static LabrinthResults.ModrinthProject ConvertToLabrinthProject(string json) - { - return JsonConvert.DeserializeObject(json); - } - } public class ServerStatusInfo { diff --git a/SDLauncher UWP/Helpers/Util.cs b/SDLauncher UWP/Helpers/Util.cs index acc9bdd9..d9736874 100644 --- a/SDLauncher UWP/Helpers/Util.cs +++ b/SDLauncher UWP/Helpers/Util.cs @@ -1,7 +1,9 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net.Http; using System.Reflection; using System.Runtime.InteropServices; using System.Text; @@ -13,8 +15,130 @@ namespace SDLauncher_UWP.Helpers { - public class Util + public static class JSONConverter { + public static ServerStatusInfo.Root ConvertToServerStatus(string json) + { + return JsonConvert.DeserializeObject(json); + } + public static LabrinthResults.SearchResult ConvertToLabrinthSearchResult(string json) + { + return JsonConvert.DeserializeObject(json); + } + public static LabrinthResults.ModrinthProject ConvertToLabrinthProject(string json) + { + return JsonConvert.DeserializeObject(json); + } + public static List ConvertDownloadLinksToCS(string json) + { + return JsonConvert.DeserializeObject>(json); + } + } + public class HttpClientDownloadWithProgress : IDisposable + { + private readonly string _downloadUrl; + private readonly string _destinationFilePath; + + private HttpClient _httpClient; + + public delegate void ProgressChangedHandler(long? totalFileSize, long totalBytesDownloaded, double? progressPercentage); + + public event ProgressChangedHandler ProgressChanged; + + public HttpClientDownloadWithProgress(string downloadUrl, string destinationFilePath) + { + _downloadUrl = downloadUrl; + _destinationFilePath = destinationFilePath; + } + + public async Task StartDownload() + { + _httpClient = new HttpClient { Timeout = TimeSpan.FromDays(1) }; + + using (var response = await _httpClient.GetAsync(_downloadUrl, HttpCompletionOption.ResponseHeadersRead)) + await DownloadFileFromHttpResponseMessage(response); + } + + private async Task DownloadFileFromHttpResponseMessage(HttpResponseMessage response) + { + response.EnsureSuccessStatusCode(); + + var totalBytes = response.Content.Headers.ContentLength; + + using (var contentStream = await response.Content.ReadAsStreamAsync()) + await ProcessContentStream(totalBytes, contentStream); + } + + private async Task ProcessContentStream(long? totalDownloadSize, Stream contentStream) + { + var totalBytesRead = 0L; + var readCount = 0L; + var buffer = new byte[8192]; + var isMoreToRead = true; + + using (var fileStream = new FileStream(_destinationFilePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true)) + { + do + { + var bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length); + if (bytesRead == 0) + { + isMoreToRead = false; + TriggerProgressChanged(totalDownloadSize, totalBytesRead); + continue; + } + + await fileStream.WriteAsync(buffer, 0, bytesRead); + + totalBytesRead += bytesRead; + readCount += 1; + + if (readCount % 100 == 0) + TriggerProgressChanged(totalDownloadSize, totalBytesRead); + } + while (isMoreToRead); + } + } + + private void TriggerProgressChanged(long? totalDownloadSize, long totalBytesRead) + { + if (ProgressChanged == null) + return; + + double? progressPercentage = null; + if (totalDownloadSize.HasValue) + progressPercentage = Math.Round((double)totalBytesRead / totalDownloadSize.Value * 100, 2); + + ProgressChanged(totalDownloadSize, totalBytesRead, progressPercentage); + } + + public void Dispose() + { + _httpClient?.Dispose(); + } + } + public static class Util + { + public static string KiloFormat(this int num) + { + if (num >= 100000000) + return (num / 1000000).ToString("#,0M"); + + if (num >= 10000000) + return (num / 1000000).ToString("0.#") + "M"; + + if (num >= 100000) + return (num / 1000).ToString("#,0K"); + + if (num >= 10000) + return (num / 1000).ToString("0.#") + "K"; + + if (num >= 1000) + return (num / 100).ToString("0.#") + "K"; + + return num.ToString("#,0"); + } + public static BitmapImage Base64StringToBitmap(string base64String) { byte[] byteBuffer = Convert.FromBase64String(base64String); @@ -63,6 +187,36 @@ public static async Task LoadImage(StorageFile file) return null; } } + + public static async Task FileExists(string path) + { + try + { + var f = await StorageFile.GetFileFromPathAsync(path); + if (f == null) + { return false; } + else { return true; } + } + catch + { + return false; + } + } + public static async Task FolderExists(string path) + { + try + { + var f = await StorageFolder.GetFolderFromPathAsync(path); + f = null; + if (f == null) + { return false; } + else { return true; } + } + catch + { + return false; + } + } } public class IniFile // revision 11 diff --git a/SDLauncher UWP/Package.appxmanifest b/SDLauncher UWP/Package.appxmanifest index f151b720..32892bbe 100644 --- a/SDLauncher UWP/Package.appxmanifest +++ b/SDLauncher UWP/Package.appxmanifest @@ -11,7 +11,7 @@ + Version="0.4.5.0" /> diff --git a/SDLauncher UWP/Resources/LocalizedStrings.cs b/SDLauncher UWP/Resources/LocalizedStrings.cs index 107f6a80..901018a7 100644 --- a/SDLauncher UWP/Resources/LocalizedStrings.cs +++ b/SDLauncher UWP/Resources/LocalizedStrings.cs @@ -9,19 +9,19 @@ namespace SDLauncher_UWP.Resources { public static class Localized { - public static string Welcome { get { return Localizer.GetLocalizedString("Welcome"); } } - public static string GoodLuck { get { return Localizer.GetLocalizedString("GoodLuck"); } } - public static string GoodEvening { get { return Localizer.GetLocalizedString("GoodEvening"); } } - public static string GettingVers { get { return Localizer.GetLocalizedString("GettingVers"); } } - public static string Ready { get { return Localizer.GetLocalizedString("Ready"); } } - public static string RamFailed { get { return Localizer.GetLocalizedString("RamFailed"); } } - public static string GoodMorning { get { return Localizer.GetLocalizedString("GoodMorning"); } } - public static string BegLogIn { get { return Localizer.GetLocalizedString("BegLogIn"); } } - public static string Error { get { return Localizer.GetLocalizedString("Error"); } } - public static string BegVer { get { return Localizer.GetLocalizedString("BegVer"); } } - public static string WrongRAM { get { return Localizer.GetLocalizedString("WrongRAM"); } } - public static string NoNetwork { get { return Localizer.GetLocalizedString("NoNetwork"); } } - public static string Win32Error { get { return Localizer.GetLocalizedString("Win32Error"); } } - public static string GetVerFailed { get { return Localizer.GetLocalizedString("GetVerFailed"); } } + public static string Welcome => Localizer.GetLocalizedString("Welcome"); + public static string GoodLuck => Localizer.GetLocalizedString("GoodLuck"); + public static string GoodEvening => Localizer.GetLocalizedString("GoodEvening"); + public static string GettingVers => Localizer.GetLocalizedString("GettingVers"); + public static string Ready => Localizer.GetLocalizedString("Ready"); + public static string RamFailed => Localizer.GetLocalizedString("RamFailed"); + public static string GoodMorning => Localizer.GetLocalizedString("GoodMorning"); + public static string BegLogIn => Localizer.GetLocalizedString("BegLogIn"); + public static string Error => Localizer.GetLocalizedString("Error"); + public static string BegVer => Localizer.GetLocalizedString("BegVer"); + public static string WrongRAM => Localizer.GetLocalizedString("WrongRAM"); + public static string NoNetwork => Localizer.GetLocalizedString("NoNetwork"); + public static string Win32Error => Localizer.GetLocalizedString("Win32Error"); + public static string GetVerFailed => Localizer.GetLocalizedString("GetVerFailed"); } } diff --git a/SDLauncher UWP/SDLauncher UWP.csproj b/SDLauncher UWP/SDLauncher UWP.csproj index 33fc5c35..a0d67b5f 100644 --- a/SDLauncher UWP/SDLauncher UWP.csproj +++ b/SDLauncher UWP/SDLauncher UWP.csproj @@ -157,6 +157,9 @@ ArgumentsListView.xaml + + ModrinthDownloadsListView.xaml + SettingsCard.xaml @@ -284,6 +287,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -326,6 +333,9 @@ + + 2.1.1 + 3.3.5 diff --git a/SDLauncher UWP/UserControls/ModrinthDownloadsListView.xaml b/SDLauncher UWP/UserControls/ModrinthDownloadsListView.xaml new file mode 100644 index 00000000..9de84426 --- /dev/null +++ b/SDLauncher UWP/UserControls/ModrinthDownloadsListView.xaml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + | + Downloads + + + + | + + + + + + + + + diff --git a/SDLauncher UWP/UserControls/ModrinthDownloadsListView.xaml.cs b/SDLauncher UWP/UserControls/ModrinthDownloadsListView.xaml.cs new file mode 100644 index 00000000..72e8ebaf --- /dev/null +++ b/SDLauncher UWP/UserControls/ModrinthDownloadsListView.xaml.cs @@ -0,0 +1,150 @@ +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 Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; +using SDLauncher_UWP.Helpers; +using System.ComponentModel; +using ByteSizeLib; +using System.Collections.ObjectModel; +// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 + +namespace SDLauncher_UWP.UserControls +{ + public sealed partial class ModrinthDownloadsListView : UserControl, INotifyPropertyChanged + { + public event TypedEventHandler DownloadRequested = delegate { }; + public event PropertyChangedEventHandler PropertyChanged = delegate { }; + + private List Mainsource; + private ObservableCollection templateSource; + public ObservableCollection TemplateSource { get { return templateSource; } set { templateSource = value; this.PropertyChanged(this, new PropertyChangedEventArgs(nameof(TemplateSource))); } } + public ModrinthDownloadsListView() + { + this.InitializeComponent(); + } + + public List ItemsSource + { + get { return Mainsource; } + set { + Mainsource = value; + var s = new ObservableCollection(); + foreach (var item in Mainsource) + { + s.Add(new DownloadLink(item)); + } + TemplateSource = s; + this.PropertyChanged(this, new PropertyChangedEventArgs(null)); + } + } + + private void btnDownload_Click(object sender, RoutedEventArgs e) + { + if (sender is Button btn) + { + var s = from DownloadLink link in templateSource where link.ID == btn.Tag.ToString() select link; + if (s != null) + { + var file = from t in s.FirstOrDefault().MainLink.files where t.primary = true select t; + + this.DownloadRequested(this, file.FirstOrDefault()); + } + } + } + private void lview_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + foreach (var item in TemplateSource) + { + if (lview.SelectedItem != null) + { + if (item.ID == (lview.SelectedItem as DownloadLink).ID) + { + item.ShowMoreInfo = Visibility.Visible; + } + else + { + item.ShowMoreInfo = Visibility.Collapsed; + } + } + } + } + } + public class DownloadLink : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged = delegate { }; + public enum versionType + { + Release, + Beta, + Alpha + } + public LabrinthResults.DownloadManager.DownloadLink MainLink { get; set; } + public string VersionName => MainLink.name; + public string FileName + { + get + { + try + { + var file = from t in MainLink.files where t.primary == true select t; + string filename = ""; + if (file != null) + { + filename = file.First().filename; + } + else + { + filename = ""; + } + return filename; + } + catch + { + return ""; + } +} + } + public string VersionNumber => MainLink.version_number; + public string Downloads => MainLink.downloads.KiloFormat(); + public string ID => MainLink.id; + public versionType VersionType => (versionType)Enum.Parse(typeof(versionType), MainLink.version_type, true); + public string DisplaySize + { + get { + int size = 0; + try + { + foreach (var item in MainLink.files) + { + if (item.primary) + { + size += item.size; + } + } + } + catch { } + var s = ByteSize.FromBytes(size); + return decimal.Round((decimal)s.MegaBytes,1,MidpointRounding.AwayFromZero).ToString(); + } + } + + private Visibility showMoreInfo; + public Visibility ShowMoreInfo { get { return showMoreInfo; } set { showMoreInfo = value; this.PropertyChanged(this, new PropertyChangedEventArgs(null)); } } + public DownloadLink(LabrinthResults.DownloadManager.DownloadLink mainLink) + { + MainLink = mainLink; + ShowMoreInfo = Visibility.Collapsed; + } + + } +} diff --git a/SDLauncher UWP/UserControls/StoreItemsCollection.xaml b/SDLauncher UWP/UserControls/StoreItemsCollection.xaml index f651b874..c7a1d159 100644 --- a/SDLauncher UWP/UserControls/StoreItemsCollection.xaml +++ b/SDLauncher UWP/UserControls/StoreItemsCollection.xaml @@ -29,34 +29,35 @@ - + - - - - - + + + + + + - - + + - - - - - - - - - - - - - + + + + + + + + + + + + + @@ -96,13 +97,13 @@ - + Downloads | - + Followers - + diff --git a/SDLauncher UWP/UserControls/StoreItemsCollection.xaml.cs b/SDLauncher UWP/UserControls/StoreItemsCollection.xaml.cs index df43a3d9..49d43ce6 100644 --- a/SDLauncher UWP/UserControls/StoreItemsCollection.xaml.cs +++ b/SDLauncher UWP/UserControls/StoreItemsCollection.xaml.cs @@ -25,13 +25,7 @@ public StoreItemsCollection() { this.InitializeComponent(); } - public string SearchText - { - get - { - return txtSearch.Text.ToString(); - } - } + public string SearchText => txtSearch.Text.ToString(); public List ItemsSource { get { return (List)GetValue(ItemsSourceProperty); } @@ -54,11 +48,11 @@ private void txtSearch_TextChanged(object sender, TextChangedEventArgs e) { if (txtSearch.Text.Length > 0) { - SearchRequested(this, new SearchRequestedEventArgs(txtSearch.Text)); + SearchRequested(this, new SearchRequestedEventArgs(txtSearch.Text,this.SortOptions,this.SearchCategories.ToArray())); } else { - SearchRequested(this, new SearchRequestedEventArgs("")); + SearchRequested(this, new SearchRequestedEventArgs("", this.SortOptions, this.SearchCategories.ToArray())); } } @@ -66,6 +60,56 @@ private void txtSearch_KeyDown(object sender, KeyRoutedEventArgs e) { } + private LabrinthResults.SearchSortOptions SortOptions = LabrinthResults.SearchSortOptions.Relevance; + private List SearchCategories = new List(); + private void SortOptions_Click(object sender, RoutedEventArgs e) + { + SortOptions = (LabrinthResults.SearchSortOptions)Enum.Parse(typeof(LabrinthResults.SearchSortOptions), (sender as Microsoft.UI.Xaml.Controls.RadioMenuFlyoutItem).Text); + txtSearch_TextChanged(null, null); + } + + private void Categories_Click(object sender, RoutedEventArgs e) + { + try { + string name = (sender as ToggleMenuFlyoutItem).Text; + ToggleMenuFlyoutItem btn = (sender as ToggleMenuFlyoutItem); + if (name == "All") + { + SearchCategories = new List(); + tglAll.IsChecked = true; + tglAdv.IsChecked = false; + tglCursed.IsChecked = false; + tglDeco.IsChecked = false; + tglEqu.IsChecked = false; + tglFood.IsChecked = false; + tglLib.IsChecked = false; + tglMagic.IsChecked = false; + tglMisc.IsChecked = false; + tglOptimi.IsChecked = false; + tglStore.IsChecked = false; + tglTech.IsChecked = false; + tglUtil.IsChecked = false; + tglWorld.IsChecked = false; + } + else + { + if (btn.IsChecked) + { + tglAll.IsChecked = false; + SearchCategories.Add((LabrinthResults.SearchCategories)Enum.Parse(typeof(LabrinthResults.SearchCategories), name)); + } + else + { + SearchCategories.Remove((LabrinthResults.SearchCategories)Enum.Parse(typeof(LabrinthResults.SearchCategories), name)); + if (SearchCategories.Count < 1) + { + tglAll.IsChecked = true; + } + } + } + } + catch { }txtSearch_TextChanged(null, null); + } } public class StoreItemSelectedEventArgs : EventArgs { @@ -78,9 +122,13 @@ public StoreItemSelectedEventArgs(int itm) public class SearchRequestedEventArgs : EventArgs { public string Name { get; private set; } - public SearchRequestedEventArgs(string itm) + public LabrinthResults.SearchSortOptions SortOptions { get; private set; } + public LabrinthResults.SearchCategories[] SearchCategories { get; private set; } + public SearchRequestedEventArgs(string itm, LabrinthResults.SearchSortOptions sortBy, LabrinthResults.SearchCategories[] categories) { Name = itm; + SortOptions = sortBy; + SearchCategories = categories; } } } diff --git a/SDLauncher UWP/UserControls/TaskListView.xaml b/SDLauncher UWP/UserControls/TaskListView.xaml index 4b370118..d3a058e4 100644 --- a/SDLauncher UWP/UserControls/TaskListView.xaml +++ b/SDLauncher UWP/UserControls/TaskListView.xaml @@ -5,6 +5,7 @@ xmlns:local="using:SDLauncher_UWP.UserControls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:winui="using:Microsoft.UI.Xaml.Controls" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> @@ -42,20 +43,29 @@ - + - - - - - - + + + + + + + + + + + + + + at - + + @@ -64,7 +74,7 @@ - + diff --git a/SDLauncher UWP/UserControls/TaskListView.xaml.cs b/SDLauncher UWP/UserControls/TaskListView.xaml.cs index 7101eb66..312b7eef 100644 --- a/SDLauncher UWP/UserControls/TaskListView.xaml.cs +++ b/SDLauncher UWP/UserControls/TaskListView.xaml.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; @@ -12,6 +14,7 @@ using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; +using System.Collections.ObjectModel; // The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236 @@ -19,15 +22,15 @@ namespace SDLauncher_UWP.UserControls { public sealed partial class TaskListView : UserControl { - public List TasksCompleted { get;private set; } - public List CurrentTasks { get;private set; } + public ObservableCollection TasksCompleted { get;private set; } + public ObservableCollection CurrentTasks { get;private set; } private int WholeTaskCount = 0; public TaskListView() { this.InitializeComponent(); - this.TasksCompleted = new List(); - this.CurrentTasks = new List(); + this.TasksCompleted = new ObservableCollection(); + this.CurrentTasks = new ObservableCollection(); RefreshTasks(); } public int AddTask(string name,int? ID = null) @@ -79,9 +82,6 @@ public bool CompleteTask(int id) } public void RefreshTasks() { - lvRuning.ItemsSource = null; - lvDone.ItemsSource = null; - //Remove Before empty tasks var emptyTasks = new List(); foreach (var item in CurrentTasks) { @@ -110,7 +110,7 @@ public void RefreshTasks() //Add Empty Tasks if (CurrentTasks.Count < 1) { - CurrentTasks.Add(new Task("Empty", 1000)); + CurrentTasks.Add(new Task("Empty", 1000) { RingVisibility = Visibility.Collapsed}); } // if (TasksCompleted.Count < 1) @@ -121,9 +121,13 @@ public void RefreshTasks() lvDone.ItemsSource = TasksCompleted; } } - public class Task + public class Task : INotifyPropertyChanged { + + public event PropertyChangedEventHandler PropertyChanged = delegate { }; + private Visibility ringVisibility = Visibility.Visible; public string Name { get; set; } + public Visibility RingVisibility { get { return ringVisibility; }set { ringVisibility = value;OnPropertyChanged(); } } public int ID { get; private set; } public DateTime DateAdded { get; set; } public Task(string name, int iD) @@ -132,5 +136,9 @@ public Task(string name, int iD) DateAdded = DateTime.Now; ID = iD; } + private void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } } } diff --git a/SDLauncher UWP/Views/StorePage.xaml b/SDLauncher UWP/Views/StorePage.xaml index 3081bba2..ead3bb4c 100644 --- a/SDLauncher UWP/Views/StorePage.xaml +++ b/SDLauncher UWP/Views/StorePage.xaml @@ -19,39 +19,54 @@ - + - + + + - + - + - +