Skip to content

Commit

Permalink
Added: Overhauled Download Menu [Part 1]
Browse files Browse the repository at this point in the history
  • Loading branch information
Sewer56 committed Aug 3, 2022
1 parent 2f29e64 commit 61c6817
Show file tree
Hide file tree
Showing 24 changed files with 571 additions and 142 deletions.
64 changes: 64 additions & 0 deletions source/Reloaded.Mod.Launcher.Lib/Utility/ImageCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System.Reactive.Linq;
using Akavache;
using Akavache.Sqlite3;

namespace Reloaded.Mod.Launcher.Lib.Utility;

/// <summary>
/// Service that provides caching support for fetching images via URL.
/// Used as a singleton.
/// </summary>
public class ImageCacheService
{
private readonly SqlRawPersistentBlobCache _cache;

/// <summary/>
public ImageCacheService()
{
var directory = Paths.ImageCachePath;
Directory.CreateDirectory(directory);
var filePath = Path.Combine(directory, "Cache.db");
_cache = new SqlRawPersistentBlobCache(filePath);
}

/// <summary>
/// Shuts down the service. Call this on application exit.
/// </summary>
public void Shutdown()
{
_cache.Flush().Wait();
_cache.Vacuum().Wait();
_cache.Connection.ExecuteScalar<int>("PRAGMA wal_checkpoint(TRUNCATE)", Array.Empty<object>());
_cache.Dispose();
_cache.Shutdown.Wait();
}

/// <summary>
/// Retrieves the image for a given URI.
/// </summary>
/// <param name="uri">The URI to get image for.</param>
/// <param name="expiration">How long should the file persist in the cache.</param>
public async ValueTask<byte[]> GetImage(Uri uri, TimeSpan expiration)
{
// Check the cache.
var key = uri.ToString();
var observable = _cache.Get(key);
var bytes = await observable.Catch(Observable.Return<byte[]?>(null!));

if (bytes == null)
{
// Get it, and put into cache.
using var client = new WebClient();
var data = await client.DownloadDataTaskAsync(uri);
_ = _cache.Insert(key, data, expiration);
return data;
}

return bytes;
}

/// <summary>
/// Gets the time a mod preview should expire from current time.
/// </summary>
public TimeSpan ModPreviewExpiration => TimeSpan.FromDays(14);
}
12 changes: 12 additions & 0 deletions source/Reloaded.Mod.Launcher/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,16 @@ public static void StopProfileOptimization()

[DllImport("psapi")]
private static extern bool EmptyWorkingSet(IntPtr hProcess);

/// <summary>
/// Ran upon exiting the application.
/// </summary>
protected override void OnExit(ExitEventArgs e)
{
base.OnExit(e);

// Flush image cache on exit.
if (Lib.IoC.IsExplicitlyBound<ImageCacheService>())
Lib.IoC.GetConstant<ImageCacheService>().Shutdown();
}
}
3 changes: 3 additions & 0 deletions source/Reloaded.Mod.Launcher/Assets/Languages/en-GB.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -539,4 +539,7 @@
<sys:String x:Key="PublishSelectMarkdownTitle">Select a Markdown File (*.md).</sys:String>
<sys:String x:Key="PublishSelectMarkdownTypeName">Markdown File</sys:String>

<!-- Update 1.20.0: Revamped Downloads Menu -->
<sys:String x:Key="DownloadsMenuNuGetButton">NuGet</sys:String>

</ResourceDictionary>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace Reloaded.Mod.Launcher.Controls.Properties;

/// <summary>
/// An attached WPF property that auto adjusts column count of a uniform grid based on a min width.
/// </summary>
public class AutoAdjustColumnCount : WPF.MVVM.AttachedPropertyBase<AutoAdjustColumnCount, int>
{
public override void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue == null)
return;

// If attached to tooltip, handle via parent.
if (sender is UniformGrid uniformGrid)
{
// Remove if already present, then re-add.
uniformGrid.SizeChanged -= OnSizeChanged;
uniformGrid.SizeChanged += OnSizeChanged;
OnSizeChanged(sender, null!);
}
}

private void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
var grid = (UniformGrid)sender;
var minWidth = GetValue(grid);
var numColumns = (int)grid.RenderSize.Width / minWidth;
if (numColumns != grid.Columns)
grid.Columns = numColumns;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ private ImageSource GetImageForAppConfig(PathTuple<ApplicationConfig> applicatio
}
}

var image = new BitmapImage(new Uri(Paths.PLACEHOLDER_IMAGE, UriKind.RelativeOrAbsolute));
image.Freeze();

return image;
return Misc.Imaging.GetPlaceholderIcon();
}
}
7 changes: 6 additions & 1 deletion source/Reloaded.Mod.Launcher/LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ Markdig.Wpf: MIT
Colorful.Console: MIT
PropertyChanged.Fody: MIT
Fody: MIT
Onova: GPL V3 or later*
Ultimate ASI Loader: MIT
SharpCompress: MIT
System.Drawing.Common: MIT
System.Management: MIT
MaterialDesignIcons: MIT
Akavache: MIT
CacheCow: MIT

If any licenses are missing in this document, please notify me.
It is difficult to keep track of recursive dependencies.

-----
GPL V3
Expand Down
23 changes: 23 additions & 0 deletions source/Reloaded.Mod.Launcher/Misc/Imaging.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,22 @@ namespace Reloaded.Mod.Launcher.Misc;

public class Imaging
{
/// <summary>
/// Converts a WPF URI into a image.
/// </summary>
public static BitmapImage BitmapFromUri(Uri source)
{
string uri = source.OriginalString.Replace("pack://siteoforigin:,,,", Constants.ApplicationDirectory);
using var stream = new FileStream(uri, FileMode.Open, FileAccess.Read, FileShare.Read);
var bitmapImage = BitmapFromStream(stream);
return bitmapImage;
}

/// <summary>
/// Loads an image from a given stream.
/// </summary>
public static BitmapImage BitmapFromStream(Stream stream)
{
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
Expand All @@ -18,6 +30,17 @@ public static BitmapImage BitmapFromUri(Uri source)
return bitmapImage;
}

/// <summary>
/// Gets the icon used for placeholders in Reloaded.
/// </summary>
public static BitmapImage GetPlaceholderIcon()
{
var img = new BitmapImage(new Uri(Paths.PLACEHOLDER_IMAGE, UriKind.RelativeOrAbsolute));
img.CacheOption = BitmapCacheOption.OnLoad;
img.Freeze();
return img;
}

public static Image ImageFromUri(Uri source)
{
string uri = source.OriginalString.Replace("pack://siteoforigin:,,,", Constants.ApplicationDirectory);
Expand Down
11 changes: 11 additions & 0 deletions source/Reloaded.Mod.Launcher/ModuleInitialiser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Reloaded.Mod.Launcher;

internal class ModuleInitialiser
{
[ModuleInitializer]
public static void Init()
{
// Raise maximum number of WebRequest connections
ServicePointManager.DefaultConnectionLimit = int.MaxValue;
}
}
Loading

0 comments on commit 61c6817

Please sign in to comment.