Skip to content

Commit

Permalink
Refactor for performance, readability and maintainability (#210)
Browse files Browse the repository at this point in the history
* chore: Use string interpolation instead of concatenation

* Refactor code for improved readability and maintainability

Several changes were made to the codebase to improve code readability and maintainability. These include the restructuring of multiple conditional statements, improved logger messaging, deletion of unnecessary comments and spaces, modification of class and method visibility, and alteration of class structure and parameters for better performance and clarity.

* refactor: code quality and maintainability issues

* Refactor code for better readability and async treatment

Several synchronous methods have been transformed into asynchronous tasks across ViewModel and utilities. All the constructors in the classes ListItem and PickedListItem were refactored into property initialization for better readability. Also, localization strings now use the LangProvider directly for language access. These significant changes will improve the codebase's maintainability.

* Refactor: Simplify SearchResult data load method

Refactored the LoadData method in SearchResultViewModel.cs for better readability and logical flow. Extracted complex search result checks into a separate private method, HasSearchResult(). This makes the code cleaner and more maintainable by avoiding nested ternary operations and deep if conditions.

* Refactor media type string properties and detail-fetching logic

The commit alters properties in the MediaTypes class to be constants rather than static getters. In the FileUtils class, it refactors the multipart conditional logic for fetching media details into a switch expression and separate helper methods for cleaner, more maintainable code.

* Refactor: Simplify Search method in MainWindowViewModel

Previously, item processing was complex and involved many nested conditions. This made it difficult to understand and maintain. Now, item processing is simplified by extracting it into separate methods: `ProcessItemAsync`, `ProcessResultsAsync`, `AddToFinalList`, and `ProcessSubfolders`. This change improves the code's readability and maintainability.

* Refactor search result processing in ProSearchResultViewModel

This update simplifies the result processing code in ProSearchResultViewModel by extracting reusable logic into separate methods. It also improves readability by breaking down complex conditions and loops into more manageable chunks. The handling of no results, processing of search results, and individual result items are now handled in their own methods.

* Refactor: Make GetClientAccessTokenAsync private and awaitable

Changed the GetClientAccessTokenAsync method from public to private as it does not need to be openly available. This method is now properly awaited in all calls to ensure sequential execution and prevent potential issues related to concurrency or incomplete tasks.

* refactor: Implement auto-scroll behavior in ScrollViewers

Extract auto-scroll logic into ScrollViewerBehavior and update XAML to use this new behavior. This cleaning encapsulates the auto-scroll functionality and removes redundant code, improving maintainability and readability.

* fix total poster count

* fix: Refactor file validation logic

Simplify the file validation process by moving exclusion logic to `FileUtils`. Combined multiple conditions into a single method for clarity and maintainability.

* refactor: Use MediaTypes constants for media type strings

Replaced hardcoded media type strings with `MediaTypes` constants across the entire codebase for better maintainability and consistency. This change affects various modules including ProcessUtils, MainWindowViewModel, SearchResultViewModel, TmdbDataTransformer, DataUtils, TMDBService, and IgdbDataTransformer.

* refactor: Segregate methods to simplify ResultPicked logic

Separated complex logic within the `ResultPicked` method into smaller methods to improve code readability and maintainability. Introduced `PrepareRating`, `PickResult`, `SelectMtvType`, `CastResult`, and `AddToPickedList` methods.

* refactor: Refactor image URL generation

created a utility method to generate poster url for IGDB, also fix the issue of poster preview not working in game mode

* refactor: Unified image handling with a new IImage interface

Replaced direct image handling with `IImage` interface to streamline processing. Introduced `ArtworkWrapper` and `ImageDataWrapper` classes for better abstraction. Enhanced loading and processing logic for improved code clarity and maintainability.

* refactor: Simplify media type handling in PosterPickerViewModel

Refactored PosterPickerViewModel to streamline media type handling by extracting methods for different media types. Improved readability and maintainability by reducing redundancy.

* refactor: modularize SearchAndMakeMethod in MainWindowViewModel

Refactored SearchAndMakeMethod by extracting validation and initialization logic into separate helper methods. Improved code readability and maintainability by organizing related functionalities and reducing method complexity.

* refactor for code quality

* fix: Remove async/await from sync methods and add static modifier

Refactored methods in PosterPickerViewModel to remove unnecessary async/await usage for synchronous operations. Made ProcessSubfolders method in MainWindowViewModel static to align it with its usage context. Added an async keyword to SearchAgainMethod to correctly await StartSearch execution in SearchResultViewModel.

* refactor: Apply various code improvements and fixes

Refined method visibility, improved formatting, and fixed minor logical issues. Specifically, adjusted method access modifiers to `static`, used concise collection initializations, and corrected string formatting issues. Reorganized namespaces and fixed inconsistency in the handling of media types and file attributes.

* refactor: readability and code style

Replaced switch with if-else in MainWindowViewModel for readability. Added exception for invalid search mode in TMDBService. Improved readability in FileUtils by adding braces around conditional return.

* refactor: Extract dialog logic to ShowSearchResultDialog method

Refactored dialog handling for search results into a separate method
to reduce code duplication and improve readability. This change
affects the processing of zero, single, and multiple result cases.

* feature: Refactor and centralize PosterIcon code

Unified PosterIcon classes into a base class to avoid code duplication and simplify maintenance. Updated class for different PosterIcon variants to extend from the new PosterIconBase class.

* refactor: Centralize image opening logic

Refactored the image opening logic by creating a centralized `ShowImageBrowser` method in `UiUtil` class. This reduces redundancy and improves maintainability across the `ProSearchResultViewModel`, `PosterPickerViewModel`, and `ManualExplorerViewModel` classes.

* refactor: refactor data extraction to use a common method

Consolidate the logic for creating ListItem instances by introducing the TransformDetailsIntoListItem method. This reduces code duplication and simplifies updates.

* chore: Move ShowImageBrowser method to UiUtils

Moved `UiUtil.ShowImageBrowser` method to `UiUtils` and updated all references to use the new location.

* refactor: Move ListView sort logic to behavior class

Moved ListView sorting logic from code-behind to a new behavior class `ListViewClickSortBehavior`.

* chore: Remove unused using directives, and move most used directives to GlobalUsing pattern

Unnecessary using directives have been removed across multiple files to clean up the codebase and move frequently used directives to Usings.cs to reduce clutter

* fix: Improve error handling and remove unnecessary async

Enhanced error handling in `ProcessUtils.cs` by adding detailed error messages and throwing `InvalidOperationException`. Removed the unnecessary ` async ` keyword from `LoadGameData` in `PosterPickerViewModel.cs` as the method does not contain any async operations.

* refactor: Refactor TMDB data handling to use SearchResultData class

Refactored TmdbDataTransformer to encapsulate result details into a new SearchResultData class. This change simplifies the method signatures and improves code readability by reducing parameter count. Added SearchResultData.cs to define the new data structure.

* fix: add braces around if

* refactor: Simplify MainWindowViewModel constructor

Refactored MainWindowViewModel constructor by extracting property tracking, culture setup, and command line processing into separate methods for better readability and maintainability. Removed redundant initialization code and reorganized method calls for logical flow.

* fix: Replace `ProgressInfo` with `ProgressBarData`

Updated the codebase to replace the `ProgressInfo` class with `ProgressBarData`. This change affects all instances where progress information is handled, including UI bindings and method parameters. Additionally, added an attribute `[Localizable(false)]` to `IconUtils`.

* chore: Add braces around if
  • Loading branch information
DineshSolanki authored Jul 27, 2024
1 parent 8cdfe76 commit 7c54bda
Show file tree
Hide file tree
Showing 93 changed files with 1,746 additions and 1,584 deletions.
15 changes: 5 additions & 10 deletions FoliCon/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
using FoliCon.Modules.Configuration;
using FoliCon.Modules.UI;
using FoliCon.Modules.utils;
using FoliCon.ViewModels;
using NLog;
using Prism.Ioc;
using Prism.Ioc;
using Sentry;
using Logger = NLog.Logger;
using Window = System.Windows.Window;

namespace FoliCon;

Expand All @@ -15,7 +10,7 @@ namespace FoliCon;
public partial class App
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
protected override System.Windows.Window CreateShell()
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
Expand Down Expand Up @@ -44,8 +39,8 @@ protected override void RegisterTypes(IContainerRegistry containerRegistry)
containerRegistry.RegisterDialog<Previewer, PreviewerViewModel>("Previewer");
containerRegistry.RegisterDialogWindow<HandyWindow>();
}
void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)

private static void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
SentrySdk.CaptureException(e.Exception);

Expand Down
4 changes: 1 addition & 3 deletions FoliCon/Models/Configs/IgdbJotTrackerStore.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using FoliCon.Modules.Configuration;

namespace FoliCon.Models.Configs;
namespace FoliCon.Models.Configs;

public class IgdbJotTrackerStore : BindableBase, ITokenStore
{
Expand Down
7 changes: 2 additions & 5 deletions FoliCon/Models/Constants/GlobalVariables.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
using FoliCon.Models.Enums;
using FoliCon.ViewModels;

namespace FoliCon.Models.Constants;
namespace FoliCon.Models.Constants;

internal static class GlobalVariables
{
Expand All @@ -19,5 +16,5 @@ public static IconOverlay IconOverlayType()
};
}

public static string MediaInfoFile = "info.folicon";
public static readonly string MediaInfoFile = "info.folicon";
}
11 changes: 6 additions & 5 deletions FoliCon/Models/Constants/MediaTypes.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
namespace FoliCon.Models.Constants;

[Localizable(false)]
public static class MediaTypes
{
public static string Game { get; } = "Game";
public static string Movie { get; } = "Movie";
public static string Collection { get; } = "Collection";
public static string Tv { get; } = "TV";
public static string Mtv { get; } = "Auto (Movies & TV Shows)";
public const string Game = "Game";
public const string Movie = "Movie";
public const string Collection = "Collection";
public const string Tv = "TV";
public const string Mtv = "Auto (Movies & TV Shows)";
}
15 changes: 8 additions & 7 deletions FoliCon/Models/Constants/PosterSize.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
namespace FoliCon.Models.Constants;

[Localizable(false)]
public static class PosterSize
{
public static string W92 { get; } = "w92";
public static string W154 { get; } = "w154";
public static string W185 { get; } = "w185";
public static string W342 { get; } = "w342";
public static string W500 { get; } = "w500";
public static string W780 { get; } = "w780";
public static string Original { get; } = "original";
public static string W92 => "w92";
public static string W154 => "w154";
public static string W185 => "w185";
public static string W342 => "w342";
public static string W500 => "w500";
public static string W780 => "w780";
public static string Original => "original";
}
10 changes: 10 additions & 0 deletions FoliCon/Models/Data/Dialog/DialogParamContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace FoliCon.Models.Data.Dialog;

public class DialogParamContainer
{
public Tmdb TmdbObject { get; set; }
public IgdbClass IgdbObject { get; set; }
public ResultResponse Result { get; set; }
public bool IsPickedById { get; set; }
public Action<IDialogResult> CallBack { get; set; } = _ => { };
}
7 changes: 7 additions & 0 deletions FoliCon/Models/Data/Dialog/PosterPickerDialogParams.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace FoliCon.Models.Data.Dialog;

public class PosterPickerDialogParams : DialogParamContainer
{
public int PickedIndex { get; set; }
public ObservableCollection<ListItem> ResultData { get; set; }
}
8 changes: 8 additions & 0 deletions FoliCon/Models/Data/Dialog/SearchResultDialogParams.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace FoliCon.Models.Data.Dialog;

public class SearchResultDialogParams : DialogParamContainer
{
public string SearchMode { get; set; }
public string Query { get; set; }
public string FolderPath { get; set; }
}
39 changes: 14 additions & 25 deletions FoliCon/Models/Data/ListItem.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
using FoliCon.Modules.utils;

namespace FoliCon.Models.Data;
namespace FoliCon.Models.Data;

public class ListItem : BindableBase
{
private string _title;
private string _year;
private string _rating;
private string _folder;
private string _overview;
private string _folder = string.Empty;
private string _overview = string.Empty;
private string _poster;
private string _trailerKey;
private Uri _trailerLink;
private string _id;
private MediaType _mediaType;
private MediaType _mediaType = MediaType.Unknown;

private string _initialPoster;
private bool _isInitialSet;
Expand Down Expand Up @@ -94,32 +92,23 @@ public MediaType MediaType
set => SetProperty(ref _mediaType, value);
}

public ListItem(string title, string year, string rating, string overview = null, string poster = null,
string folder = "", string id = "", MediaType mediaType = MediaType.Unknown)
{
Title = title;
Year = year;
Rating = rating;
Overview = overview;
Poster = poster;
Folder = folder;
Id = id;
MediaType = mediaType;
}

public ListItem()
{
}

public void ResetInitialPoster()
{
if (!_isInitialSet) return;
if (!_isInitialSet)
{
return;
}

Poster = _initialPoster;
CanResetPoster = false;
}
public void SetInitialPoster()
{
if (_isInitialSet) return;
if (_isInitialSet)
{
return;
}

_initialPoster = _poster;
CanResetPoster = true;
}
Expand Down
4 changes: 1 addition & 3 deletions FoliCon/Models/Data/ParsedTitle.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using FoliCon.Models.Enums;

namespace FoliCon.Models.Data;
namespace FoliCon.Models.Data;

public record ParsedTitle(string Title, IdType IdType, string Id, int Year);
9 changes: 7 additions & 2 deletions FoliCon/Models/Data/PickedListItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ public string FolderName
set => SetProperty(ref _folderName, value);
}

public PickedListItem(string title, string year, string rating, string folder, string folderName, string poster)
: base(title, year, rating, "", poster, folder)
public PickedListItem(string title, string year, string rating, string folder, string folderName, string poster)
{
Title = title;
Year = year;
Rating = rating;
Folder = folder;
Poster = poster;

FolderName = folderName;
}
}
13 changes: 3 additions & 10 deletions FoliCon/Models/Data/PosterIcon.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using FoliCon.Modules.utils;

namespace FoliCon.Models.Data;
namespace FoliCon.Models.Data;

public class PosterIcon: BindableBase
{
Expand Down Expand Up @@ -35,7 +33,7 @@ public string MediaTitle

public PosterIcon()
{
var filePath = Path.GetTempPath() + "\\posterDummy.png";
var filePath = $"{Path.GetTempPath()}\\posterDummy.png";
if (!File.Exists(filePath))
{
_ = NetworkUtils.DownloadImageFromUrlAsync(new Uri("https://image.tmdb.org/t/p/original/r0bgHi3MwGHTKPWyJdORsb4ukY8.jpg"), filePath);
Expand All @@ -56,13 +54,8 @@ public PosterIcon(string folderJpgPath, string rating, string ratingVisibility,
var thisMemoryStream = new MemoryStream(File.ReadAllBytes(folderJpgPath));
FolderJpg = (ImageSource)new ImageSourceConverter().ConvertFrom(thisMemoryStream);
}
public PosterIcon(string folderJpgPath, string rating, string ratingVisibility, string mockupVisibility, string mediaTitle="FoliCon")
public PosterIcon(string folderJpgPath, string rating, string ratingVisibility, string mockupVisibility, string mediaTitle):this(folderJpgPath, rating, ratingVisibility, mockupVisibility)
{
RatingVisibility = ratingVisibility;
Rating = rating;
MockupVisibility = mockupVisibility;
var thisMemoryStream = new MemoryStream(File.ReadAllBytes(folderJpgPath));
FolderJpg = (ImageSource)new ImageSourceConverter().ConvertFrom(thisMemoryStream);
MediaTitle = mediaTitle;
}
}
46 changes: 46 additions & 0 deletions FoliCon/Models/Data/PosterIconBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using Size = System.Windows.Size;

namespace FoliCon.Models.Data;

public abstract class PosterIconBase : UserControl
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
protected PosterIconBase()
{
}

protected PosterIconBase(object dataContext)
{
DataContext = dataContext;
}

public Bitmap RenderToBitmap()
{
return RenderTargetBitmapTo32BppArgb(AsRenderTargetBitmap());
}

private RenderTargetBitmap AsRenderTargetBitmap()
{
var size = new Size(256, 256);
Measure(size);
Arrange(new Rect(size));

var rtb = new RenderTargetBitmap((int)size.Width, (int)size.Height, 96, 96, PixelFormats.Default);
RenderOptions.SetBitmapScalingMode(this, BitmapScalingMode.HighQuality);
RenderOptions.SetEdgeMode(this, EdgeMode.Aliased);
rtb.Render(this);

return rtb;
}

public static Bitmap RenderTargetBitmapTo32BppArgb(BitmapSource rtb)
{
Logger.Trace("Converting RenderTargetBitmap to 32BppArgb");
var stream = new MemoryStream();
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
encoder.Save(stream);
Logger.Trace("RenderTargetBitmap converted to 32BppArgb");
return new Bitmap(stream);
}
}
17 changes: 17 additions & 0 deletions FoliCon/Models/Data/ProgressBarData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,21 @@ public class ProgressBarData : BindableBase
public int Value { get => _value; set => SetProperty(ref _value, value); }
public int Max { get => _max; set => SetProperty(ref _max, value); }
public string Text { get => _text; set => SetProperty(ref _text, value); }

public double Progress => 100 * ((double)Value / Max);

public ProgressBarData()
{
}

public ProgressBarData(int value, int max)
{
Value = value;
Max = max;
}

public ProgressBarData(int value, int max, string text) : this(value, max)
{
Text = text;
}
}
23 changes: 0 additions & 23 deletions FoliCon/Models/Data/ProgressInfo.cs

This file was deleted.

12 changes: 12 additions & 0 deletions FoliCon/Models/Data/SearchResultData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace FoliCon.Models.Data;

public class SearchResultData
{
public dynamic Result { get; set; }
public string ResultType { get; set; }
public string FullFolderPath { get; set; }
public string Rating { get; set; }
public bool IsPickedById { get; set; }
public string FolderName { get; set; }
public string LocalPosterPath { get; set; }
}
7 changes: 1 addition & 6 deletions FoliCon/Models/Data/StatusBarData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,7 @@ public class StatusBarData : BindableBase
public int TotalIcons { get => _totalIcons; set => SetProperty(ref _totalIcons, value); }
public int TotalFolders { get => _totalFolders; set => SetProperty(ref _totalFolders, value); }
public string NetIcon { get => _netIcon; set => SetProperty(ref _netIcon, value); }
public ProgressBarData ProgressBarData { get; set; }

public StatusBarData()
{
ProgressBarData = new ProgressBarData();
}
public ProgressBarData ProgressBarData { get; set; } = new();

public void ResetData()
{
Expand Down
Loading

0 comments on commit 7c54bda

Please sign in to comment.