Fix WebP images not loading on Windows installations without WebP extensions installed

This commit is contained in:
trawzified 2023-12-28 17:15:19 +01:00
parent 0be1081142
commit 1c609a3d6a
8 changed files with 2239 additions and 206 deletions

View File

@ -19,6 +19,9 @@ using Wabbajack.Extensions;
using Wabbajack.Models; using Wabbajack.Models;
using Wabbajack.Paths; using Wabbajack.Paths;
using Wabbajack.Paths.IO; using Wabbajack.Paths.IO;
using System.Drawing;
using Catel.IO;
using System.Drawing.Imaging;
namespace Wabbajack namespace Wabbajack
{ {
@ -37,6 +40,32 @@ namespace Wabbajack
return img; return img;
} }
public static BitmapImage BitmapImageFromWebp(byte[] bytes, bool getThumbnail = false)
{
using(WebP webp = new())
{
Bitmap bitmap;
if (getThumbnail)
bitmap = webp.GetThumbnailFast(bytes, 640, 360);
else
bitmap = webp.Decode(bytes);
using(var ms = new MemoryStream())
{
bitmap.Save(ms, ImageFormat.Png);
ms.Position = 0;
var img = new BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnLoad;
img.StreamSource = ms;
img.EndInit();
img.Freeze();
return img;
}
}
}
public static bool TryGetBitmapImageFromFile(AbsolutePath path, out BitmapImage bitmapImage) public static bool TryGetBitmapImageFromFile(AbsolutePath path, out BitmapImage bitmapImage)
{ {
try try
@ -95,7 +124,7 @@ namespace Wabbajack
try try
{ {
var (found, mstream) = await FindCachedImage(url); var (found, mstream) = await FindCachedImage(url);
if (found) return (ll, mstream); if (found) return (ll, mstream, url);
var ret = new MemoryStream(); var ret = new MemoryStream();
using (var client = new HttpClient()) using (var client = new HttpClient())
@ -107,21 +136,21 @@ namespace Wabbajack
ret.Seek(0, SeekOrigin.Begin); ret.Seek(0, SeekOrigin.Begin);
await WriteCachedImage(url, ret.ToArray()); await WriteCachedImage(url, ret.ToArray());
return (ll, ret); return (ll, ret, url);
} }
catch (Exception ex) catch (Exception ex)
{ {
exceptionHandler(ex); exceptionHandler(ex);
return (ll, default); return (ll, default, url);
} }
}) })
.Select(x => .Select(x =>
{ {
var (ll, memStream) = x; var (ll, memStream, url) = x;
if (memStream == null) return default; if (memStream == null) return default;
try try
{ {
return BitmapImageFromStream(memStream); return url.EndsWith("webp", StringComparison.InvariantCultureIgnoreCase) ? BitmapImageFromWebp(memStream.ToArray(), true) : BitmapImageFromStream(memStream);
} }
catch (Exception ex) catch (Exception ex)
{ {

File diff suppressed because it is too large Load Diff

View File

@ -133,7 +133,8 @@ namespace Wabbajack
{ {
if (string.IsNullOrWhiteSpace(txt)) return _ => true; if (string.IsNullOrWhiteSpace(txt)) return _ => true;
return item => item.Metadata.Title.ContainsCaseInsensitive(txt) || return item => item.Metadata.Title.ContainsCaseInsensitive(txt) ||
item.Metadata.Description.ContainsCaseInsensitive(txt); item.Metadata.Description.ContainsCaseInsensitive(txt) ||
item.Metadata.Tags.Contains(txt);
}); });
var onlyInstalledGamesFilter = this.ObservableForProperty(vm => vm.OnlyInstalled) var onlyInstalledGamesFilter = this.ObservableForProperty(vm => vm.OnlyInstalled)
@ -169,12 +170,12 @@ namespace Wabbajack
}) })
.StartWith(_ => true); .StartWith(_ => true);
var searchSorter = this.WhenValueChanged(x => x.Search) var searchSorter = this.WhenValueChanged(vm => vm.Search)
.Where(x => !string.IsNullOrWhiteSpace(x)) .Where(s => !string.IsNullOrWhiteSpace(s))
.Throttle(searchThrottle, RxApp.MainThreadScheduler) .Throttle(searchThrottle, RxApp.MainThreadScheduler)
.Select(s => SortExpressionComparer<ModListMetadataVM> .Select(s => SortExpressionComparer<ModListMetadataVM>
.Descending(modlist => modlist.Metadata.Title.StartsWith(s, StringComparison.InvariantCultureIgnoreCase)) .Descending(m => m.Metadata.Title.StartsWith(s, StringComparison.InvariantCultureIgnoreCase))
.ThenByDescending(modlist => modlist.Metadata.Title.Contains(s, StringComparison.InvariantCultureIgnoreCase))); .ThenByDescending(m => m.Metadata.Title.Contains(s, StringComparison.InvariantCultureIgnoreCase)));
_modLists.Connect() _modLists.Connect()
.ObserveOn(RxApp.MainThreadScheduler) .ObserveOn(RxApp.MainThreadScheduler)
.Filter(searchTextPredicates) .Filter(searchTextPredicates)
@ -183,6 +184,7 @@ namespace Wabbajack
.Filter(showNSFWFilter) .Filter(showNSFWFilter)
.Filter(gameFilter) .Filter(gameFilter)
.Sort(searchSorter) .Sort(searchSorter)
.Sort(SortExpressionComparer<ModListMetadataVM>.Descending(modlist => !modlist.IsBroken))
.TreatMovesAsRemoveAdd() .TreatMovesAsRemoveAdd()
.Bind(out _filteredModLists) .Bind(out _filteredModLists)
.Subscribe((_) => .Subscribe((_) =>

View File

@ -176,7 +176,7 @@ namespace Wabbajack
.ToGuiProperty(this, nameof(Exists)); .ToGuiProperty(this, nameof(Exists));
var imageObs = Observable.Return(Metadata.Links.ImageUri) var imageObs = Observable.Return(Metadata.Links.ImageUri)
.DownloadBitmapImage((ex) => _logger.LogError("Error downloading modlist image {Title}", Metadata.Title), LoadingImageLock); .DownloadBitmapImage((ex) => _logger.LogError("Error downloading modlist image {Title} from {ImageUri}: {Exception}", Metadata.Title, Metadata.Links.ImageUri, ex.Message), LoadingImageLock);
_Image = imageObs _Image = imageObs
.ToGuiProperty(this, nameof(Image)); .ToGuiProperty(this, nameof(Image));

View File

@ -17,7 +17,7 @@
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="3*" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Border Grid.Column="1" <Border Grid.Column="1"
BorderBrush="Transparent" BorderBrush="Transparent"
@ -137,25 +137,8 @@
</DataTemplate> </DataTemplate>
</ComboBox.ItemTemplate> </ComboBox.ItemTemplate>
</ComboBox> </ComboBox>
<Grid Grid.Row="2" Margin="0, 10, 0, 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<CheckBox
x:Name="ShowNSFW"
FontSize="7"
VerticalAlignment="Center"
Foreground="{StaticResource ForegroundBrush}"
ToolTip="Only show Not Safe For Work (NSFW) modlists">
<CheckBox.LayoutTransform>
<ScaleTransform ScaleX="1.6" ScaleY="1.6"/>
</CheckBox.LayoutTransform>
</CheckBox>
<TextBlock Grid.Column="1" Margin="5, 0, 0, 0" Text="Show NSFW modlists" FontSize="14" VerticalAlignment="Center" />
</Grid>
<Grid Grid.Row="3" Margin="0, 10, 0, 0"> <Grid Grid.Row="2" Margin="0, 10, 0, 0">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
@ -172,6 +155,24 @@
<TextBlock Grid.Column="1" Margin="5, 0, 0, 0" Text="Show unofficial modlists" FontSize="14" VerticalAlignment="Center" /> <TextBlock Grid.Column="1" Margin="5, 0, 0, 0" Text="Show unofficial modlists" FontSize="14" VerticalAlignment="Center" />
</Grid> </Grid>
<Grid Grid.Row="3" Margin="0, 10, 0, 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<CheckBox
x:Name="ShowNSFW"
FontSize="7"
VerticalAlignment="Center"
Foreground="{StaticResource ForegroundBrush}"
ToolTip="Only show Not Safe For Work (NSFW) modlists">
<CheckBox.LayoutTransform>
<ScaleTransform ScaleX="1.6" ScaleY="1.6"/>
</CheckBox.LayoutTransform>
</CheckBox>
<TextBlock Grid.Column="1" Margin="5, 0, 0, 0" Text="Show only NSFW modlists" FontSize="14" VerticalAlignment="Center" />
</Grid>
<Grid Grid.Row="4" Margin="0, 10, 0, 0"> <Grid Grid.Row="4" Margin="0, 10, 0, 0">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>

View File

@ -48,14 +48,15 @@
</UserControl.Resources> </UserControl.Resources>
<Border <Border
x:Name="ModListTile" x:Name="ModListTile"
Margin="10" Margin="8"
Background="Transparent" Background="Transparent"
BorderThickness="1"> CornerRadius="8"
BorderThickness="0">
<Border.Effect> <Border.Effect>
<DropShadowEffect <DropShadowEffect
BlurRadius="25" BlurRadius="25"
Opacity="0.5" Opacity="0.25"
ShadowDepth="5" /> ShadowDepth="3" />
</Border.Effect> </Border.Effect>
<Border.Style> <Border.Style>
<Style TargetType="Border"> <Style TargetType="Border">
@ -68,227 +69,216 @@
</Style> </Style>
</Border.Style> </Border.Style>
<Grid <Grid
Width="570" Width="327"
Height="480" Height="184"
Background="{StaticResource DarkBackgroundBrush}"> Background="Transparent">
<Grid.RowDefinitions> <Grid ClipToBounds="True">
<RowDefinition Height="Auto" /> <mahapps:ProgressRing x:Name="LoadingProgress" />
<RowDefinition Height="*" /> <TextBlock Text="{Binding Metadata.Title}" VerticalAlignment="Bottom" FontSize="14" Margin="10, 0, 0, 10" Panel.ZIndex="1"/>
<RowDefinition Height="40" /> <Border
</Grid.RowDefinitions> BorderThickness="0"
<Grid.ColumnDefinitions> HorizontalAlignment="Stretch"
<ColumnDefinition Width="*" /> VerticalAlignment="Stretch">
<ColumnDefinition Width="Auto" /> <Border.Background>
</Grid.ColumnDefinitions> <ImageBrush x:Name="ModlistImage" Stretch="UniformToFill"/>
<Border Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" </Border.Background>
BorderBrush="{StaticResource ButtonNormalBorder}" <Border.Style>
BorderThickness="0,0,0,1"> <Style TargetType="Border">
<Grid ClipToBounds="True"> <Style.Triggers>
<mahapps:ProgressRing x:Name="LoadingProgress" /> <DataTrigger Binding="{Binding IsBroken}" Value="True">
<Viewbox <Setter Property="Effect">
Height="340" <Setter.Value>
HorizontalAlignment="Center" <BlurEffect Radius="35" />
VerticalAlignment="Center" </Setter.Value>
Stretch="UniformToFill"> </Setter>
<Image x:Name="ModListImage"> </DataTrigger>
<Image.Style> </Style.Triggers>
<Style TargetType="Image"> </Style>
<Style.Triggers> </Border.Style>
<DataTrigger Binding="{Binding IsBroken}" Value="True"> </Border>
<Setter Property="Effect"> <Ellipse
<Setter.Value>
<BlurEffect Radius="35" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Viewbox>
<Ellipse
Height="120" Height="120"
Margin="-40,0,-40,-60" Margin="-80,-100,-80,0"
VerticalAlignment="Bottom" VerticalAlignment="Top"
Fill="Black" Fill="White"
Opacity="0.5"> Opacity="0.15">
<Ellipse.Effect> <Ellipse.Effect>
<BlurEffect Radius="55" /> <BlurEffect Radius="75" />
</Ellipse.Effect> </Ellipse.Effect>
<Ellipse.Style> <Ellipse.Style>
<Style TargetType="Ellipse"> <Style TargetType="Ellipse">
<Style.Triggers> <Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, ElementName=ModListTile}" Value="True"> <DataTrigger Binding="{Binding IsMouseOver, ElementName=ModListTile}" Value="True">
<DataTrigger.EnterActions> <DataTrigger.EnterActions>
<BeginStoryboard> <BeginStoryboard>
<Storyboard> <Storyboard>
<DoubleAnimation <DoubleAnimation
Storyboard.TargetProperty="Opacity" Storyboard.TargetProperty="Opacity"
To="0.75" To="0.25"
Duration="0:0:0.08" /> Duration="0:0:0.08" />
</Storyboard> </Storyboard>
</BeginStoryboard> </BeginStoryboard>
</DataTrigger.EnterActions> </DataTrigger.EnterActions>
<DataTrigger.ExitActions> <DataTrigger.ExitActions>
<BeginStoryboard> <BeginStoryboard>
<Storyboard> <Storyboard>
<DoubleAnimation <DoubleAnimation
Storyboard.TargetProperty="Opacity" Storyboard.TargetProperty="Opacity"
To="0.5" To="0.15"
Duration="0:0:0.08" /> Duration="0:0:0.08" />
</Storyboard> </Storyboard>
</BeginStoryboard> </BeginStoryboard>
</DataTrigger.ExitActions> </DataTrigger.ExitActions>
</DataTrigger> </DataTrigger>
</Style.Triggers> </Style.Triggers>
</Style> </Style>
</Ellipse.Style> </Ellipse.Style>
</Ellipse> </Ellipse>
<Label <Label
Margin="10,242,0,0" Margin="10,242,0,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Top" VerticalAlignment="Top"
Content="{Binding VersionText}" Content="{Binding VersionText}"
Opacity="0"> Opacity="0">
<Label.Style> <Label.Style>
<Style TargetType="Label"> <Style TargetType="Label">
<Style.Triggers> <Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, ElementName=ModListTile}" Value="True"> <DataTrigger Binding="{Binding IsMouseOver, ElementName=ModListTile}" Value="True">
<DataTrigger.EnterActions> <DataTrigger.EnterActions>
<BeginStoryboard> <BeginStoryboard>
<Storyboard> <Storyboard>
<DoubleAnimation <DoubleAnimation
Storyboard.TargetProperty="Opacity" Storyboard.TargetProperty="Opacity"
To="1" To="1"
Duration="0:0:0.08" /> Duration="0:0:0.08" />
</Storyboard> </Storyboard>
</BeginStoryboard> </BeginStoryboard>
</DataTrigger.EnterActions> </DataTrigger.EnterActions>
<DataTrigger.ExitActions> <DataTrigger.ExitActions>
<BeginStoryboard> <BeginStoryboard>
<Storyboard> <Storyboard>
<DoubleAnimation <DoubleAnimation
Storyboard.TargetProperty="Opacity" Storyboard.TargetProperty="Opacity"
To="0" To="0"
Duration="0:0:0.08" /> Duration="0:0:0.08" />
</Storyboard> </Storyboard>
</BeginStoryboard> </BeginStoryboard>
</DataTrigger.ExitActions> </DataTrigger.ExitActions>
</DataTrigger> </DataTrigger>
</Style.Triggers> </Style.Triggers>
</Style> </Style>
</Label.Style> </Label.Style>
</Label> </Label>
<Label <Label
Margin="10,257,0,0" Margin="10,257,0,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Top" VerticalAlignment="Top"
Content="{Binding DownloadSizeText}" Content="{Binding DownloadSizeText}"
Opacity="0"> Opacity="0">
<Label.Style> <Label.Style>
<Style TargetType="Label"> <Style TargetType="Label">
<Style.Triggers> <Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, ElementName=ModListTile}" Value="True"> <DataTrigger Binding="{Binding IsMouseOver, ElementName=ModListTile}" Value="True">
<DataTrigger.EnterActions> <DataTrigger.EnterActions>
<BeginStoryboard> <BeginStoryboard>
<Storyboard> <Storyboard>
<DoubleAnimation <DoubleAnimation
Storyboard.TargetProperty="Opacity" Storyboard.TargetProperty="Opacity"
To="1" To="1"
Duration="0:0:0.08" /> Duration="0:0:0.08" />
</Storyboard> </Storyboard>
</BeginStoryboard> </BeginStoryboard>
</DataTrigger.EnterActions> </DataTrigger.EnterActions>
<DataTrigger.ExitActions> <DataTrigger.ExitActions>
<BeginStoryboard> <BeginStoryboard>
<Storyboard> <Storyboard>
<DoubleAnimation <DoubleAnimation
Storyboard.TargetProperty="Opacity" Storyboard.TargetProperty="Opacity"
To="0" To="0"
Duration="0:0:0.08" /> Duration="0:0:0.08" />
</Storyboard> </Storyboard>
</BeginStoryboard> </BeginStoryboard>
</DataTrigger.ExitActions> </DataTrigger.ExitActions>
</DataTrigger> </DataTrigger>
</Style.Triggers> </Style.Triggers>
</Style> </Style>
</Label.Style> </Label.Style>
</Label> </Label>
<Label <Label
Margin="10,272,0,0" Margin="10,272,0,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Top" VerticalAlignment="Top"
Content="{Binding InstallSizeText}" Content="{Binding InstallSizeText}"
Opacity="0"> Opacity="0">
<Label.Style> <Label.Style>
<Style TargetType="Label"> <Style TargetType="Label">
<Style.Triggers> <Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, ElementName=ModListTile}" Value="True"> <DataTrigger Binding="{Binding IsMouseOver, ElementName=ModListTile}" Value="True">
<DataTrigger.EnterActions> <DataTrigger.EnterActions>
<BeginStoryboard> <BeginStoryboard>
<Storyboard> <Storyboard>
<DoubleAnimation <DoubleAnimation
Storyboard.TargetProperty="Opacity" Storyboard.TargetProperty="Opacity"
To="1" To="1"
Duration="0:0:0.08" /> Duration="0:0:0.08" />
</Storyboard> </Storyboard>
</BeginStoryboard> </BeginStoryboard>
</DataTrigger.EnterActions> </DataTrigger.EnterActions>
<DataTrigger.ExitActions> <DataTrigger.ExitActions>
<BeginStoryboard> <BeginStoryboard>
<Storyboard> <Storyboard>
<DoubleAnimation <DoubleAnimation
Storyboard.TargetProperty="Opacity" Storyboard.TargetProperty="Opacity"
To="0" To="0"
Duration="0:0:0.08" /> Duration="0:0:0.08" />
</Storyboard> </Storyboard>
</BeginStoryboard> </BeginStoryboard>
</DataTrigger.ExitActions> </DataTrigger.ExitActions>
</DataTrigger> </DataTrigger>
</Style.Triggers> </Style.Triggers>
</Style> </Style>
</Label.Style> </Label.Style>
</Label> </Label>
<Label <Label
Margin="10,287,0,0" Margin="10,287,0,0"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Top" VerticalAlignment="Top"
Content="{Binding TotalSizeRequirementText}" Content="{Binding TotalSizeRequirementText}"
Opacity="0"> Opacity="0">
<Label.Style> <Label.Style>
<Style TargetType="Label"> <Style TargetType="Label">
<Style.Triggers> <Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, ElementName=ModListTile}" Value="True"> <DataTrigger Binding="{Binding IsMouseOver, ElementName=ModListTile}" Value="True">
<DataTrigger.EnterActions> <DataTrigger.EnterActions>
<BeginStoryboard> <BeginStoryboard>
<Storyboard> <Storyboard>
<DoubleAnimation <DoubleAnimation
Storyboard.TargetProperty="Opacity" Storyboard.TargetProperty="Opacity"
To="1" To="1"
Duration="0:0:0.08" /> Duration="0:0:0.08" />
</Storyboard> </Storyboard>
</BeginStoryboard> </BeginStoryboard>
</DataTrigger.EnterActions> </DataTrigger.EnterActions>
<DataTrigger.ExitActions> <DataTrigger.ExitActions>
<BeginStoryboard> <BeginStoryboard>
<Storyboard> <Storyboard>
<DoubleAnimation <DoubleAnimation
Storyboard.TargetProperty="Opacity" Storyboard.TargetProperty="Opacity"
To="0" To="0"
Duration="0:0:0.08" /> Duration="0:0:0.08" />
</Storyboard> </Storyboard>
</BeginStoryboard> </BeginStoryboard>
</DataTrigger.ExitActions> </DataTrigger.ExitActions>
</DataTrigger> </DataTrigger>
</Style.Triggers> </Style.Triggers>
</Style> </Style>
</Label.Style> </Label.Style>
</Label> </Label>
</Grid> </Grid>
</Border>
<local:UnderMaintenanceOverlay Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" <local:UnderMaintenanceOverlay Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
x:Name="Overlay" x:Name="Overlay"
Visibility="Collapsed" /> Visibility="Collapsed" />
<!--
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"
x:Name="ModListTitleShadow" x:Name="ModListTitleShadow"
Margin="5" Margin="5"
@ -402,8 +392,8 @@
Kind="Exclamation" /> Kind="Exclamation" />
</StackPanel> </StackPanel>
</Button> </Button>
</Grid> </Grid>
-->
</Grid> </Grid>
</Border> </Border>
</rxui:ReactiveUserControl> </rxui:ReactiveUserControl>

View File

@ -2,6 +2,8 @@
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Windows; using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D; using System.Windows.Media.Media3D;
using MahApps.Metro.IconPacks; using MahApps.Metro.IconPacks;
using ReactiveUI; using ReactiveUI;
@ -19,14 +21,39 @@ namespace Wabbajack
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
ViewModel.WhenAnyValue(vm => vm.Image) ViewModel.WhenAnyValue(vm => vm.Image)
.BindToStrict(this, view => view.ModListImage.Source) .BindToStrict(this, v => v.ModlistImage.ImageSource)
.DisposeWith(disposables);
/*
this.WhenAny(x => x.ViewModel.Metadata.Links.ImageUri)
.Select(x => new BitmapImage() { UriSource = new Uri(x) })
.BindToStrict(this, v => v.ModlistImage.ImageSource)
.DisposeWith(disposables); .DisposeWith(disposables);
*/
/*
ViewModel.WhenAnyValue(x => x.Metadata.Links.ImageUri)
.Select(x => {
var img = new BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnDemand;
img.DecodePixelWidth = 327;
var uri = new Uri(x, UriKind.Absolute);
img.UriSource = uri;
img.EndInit();
return img;
})
.BindToStrict(this, v => v.ModlistImage.ImageSource)
.DisposeWith(disposables);
*/
var textXformed = ViewModel.WhenAnyValue(vm => vm.Metadata.Title) var textXformed = ViewModel.WhenAnyValue(vm => vm.Metadata.Title)
.CombineLatest(ViewModel.WhenAnyValue(vm => vm.Metadata.ImageContainsTitle), .CombineLatest(ViewModel.WhenAnyValue(vm => vm.Metadata.ImageContainsTitle),
ViewModel.WhenAnyValue(vm => vm.IsBroken)) ViewModel.WhenAnyValue(vm => vm.IsBroken))
.Select(x => x.Second && !x.Third ? "" : x.First); .Select(x => x.Second && !x.Third ? "" : x.First);
/*
textXformed textXformed
.BindToStrict(this, view => view.ModListTitle.Text) .BindToStrict(this, view => view.ModListTitle.Text)
.DisposeWith(disposables); .DisposeWith(disposables);
@ -42,6 +69,7 @@ namespace Wabbajack
ViewModel.WhenAnyValue(x => x.ModListTagList) ViewModel.WhenAnyValue(x => x.ModListTagList)
.BindToStrict(this, x => x.TagsList.ItemsSource) .BindToStrict(this, x => x.TagsList.ItemsSource)
.DisposeWith(disposables); .DisposeWith(disposables);
*/
ViewModel.WhenAnyValue(x => x.LoadingImageLock.IsLoading) ViewModel.WhenAnyValue(x => x.LoadingImageLock.IsLoading)
.Select(x => x ? Visibility.Visible : Visibility.Collapsed) .Select(x => x ? Visibility.Visible : Visibility.Collapsed)
@ -53,6 +81,7 @@ namespace Wabbajack
.BindToStrict(this, view => view.Overlay.Visibility) .BindToStrict(this, view => view.Overlay.Visibility)
.DisposeWith(disposables); .DisposeWith(disposables);
/*
ViewModel.WhenAnyValue(x => x.OpenWebsiteCommand) ViewModel.WhenAnyValue(x => x.OpenWebsiteCommand)
.BindToStrict(this, x => x.OpenWebsiteButton.Command) .BindToStrict(this, x => x.OpenWebsiteButton.Command)
.DisposeWith(disposables); .DisposeWith(disposables);
@ -64,14 +93,18 @@ namespace Wabbajack
ViewModel.WhenAnyValue(x => x.ExecuteCommand) ViewModel.WhenAnyValue(x => x.ExecuteCommand)
.BindToStrict(this, x => x.ExecuteButton.Command) .BindToStrict(this, x => x.ExecuteButton.Command)
.DisposeWith(disposables); .DisposeWith(disposables);
*/
/*
ViewModel.WhenAnyValue(x => x.ProgressPercent) ViewModel.WhenAnyValue(x => x.ProgressPercent)
.ObserveOnDispatcher() .ObserveOn(RxApp.MainThreadScheduler)
.Select(p => p.Value) .Select(p => p.Value)
.BindTo(this, x => x.DownloadProgressBar.Value) .BindTo(this, x => x.DownloadProgressBar.Value)
.DisposeWith(disposables); .DisposeWith(disposables);
*/
/*
ViewModel.WhenAnyValue(x => x.Status) ViewModel.WhenAnyValue(x => x.Status)
.ObserveOnGuiThread() .ObserveOnGuiThread()
.Subscribe(x => .Subscribe(x =>
@ -91,6 +124,7 @@ namespace Wabbajack
}); });
}) })
.DisposeWith(disposables); .DisposeWith(disposables);
*/
/* /*
this.MarkAsNeeded<ModListTileView, ModListMetadataVM, bool>(this.ViewModel, x => x.IsBroken); this.MarkAsNeeded<ModListTileView, ModListMetadataVM, bool>(this.ViewModel, x => x.IsBroken);

View File

@ -96,6 +96,7 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Imazen.WebP" Version="10.0.1" />
<PackageReference Include="MahApps.Metro" Version="2.4.10" /> <PackageReference Include="MahApps.Metro" Version="2.4.10" />
<PackageReference Include="MahApps.Metro.IconPacks" Version="4.11.0" /> <PackageReference Include="MahApps.Metro.IconPacks" Version="4.11.0" />
<PackageReference Include="Microsoft-WindowsAPICodePack-Shell" Version="1.1.5" /> <PackageReference Include="Microsoft-WindowsAPICodePack-Shell" Version="1.1.5" />