mirror of
https://github.com/Stone-Red-Code/Markdowser.git
synced 2026-09-07 15:56:28 +02:00
Fix formatting and some warnings
This commit is contained in:
@@ -1,27 +1,27 @@
|
|||||||
using Markdowser.ViewModels;
|
using Markdowser.ViewModels;
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Markdowser.Utilities
|
namespace Markdowser.Utilities;
|
||||||
|
|
||||||
|
public class CacheService
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, ContentViewModelBase> cache = [];
|
||||||
|
|
||||||
|
public ContentViewModelBase? Get(string url)
|
||||||
{
|
{
|
||||||
public class CacheService
|
if (cache.TryGetValue(url, out ContentViewModelBase? value))
|
||||||
{
|
{
|
||||||
private Dictionary<string, ContentViewModelBase> cache = new Dictionary<string, ContentViewModelBase>();
|
return value;
|
||||||
|
}
|
||||||
public ContentViewModelBase? Get(string url)
|
else
|
||||||
{
|
{
|
||||||
if (cache.ContainsKey(url))
|
return null;
|
||||||
{
|
|
||||||
return cache[url];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Set(string url, ContentViewModelBase content)
|
|
||||||
{
|
|
||||||
cache[url] = content;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Set(string url, ContentViewModelBase content)
|
||||||
|
{
|
||||||
|
cache[url] = content;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -104,7 +104,6 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||||||
public ICommand Browse => ReactiveCommand.Create(() => FetchUrl(true));
|
public ICommand Browse => ReactiveCommand.Create(() => FetchUrl(true));
|
||||||
public ICommand Reload => ReactiveCommand.Create(() => FetchUrl(false));
|
public ICommand Reload => ReactiveCommand.Create(() => FetchUrl(false));
|
||||||
|
|
||||||
|
|
||||||
public ICommand Back => ReactiveCommand.Create(() =>
|
public ICommand Back => ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
if (GlobalState.BackHistory.Count > 0)
|
if (GlobalState.BackHistory.Count > 0)
|
||||||
@@ -199,122 +198,121 @@ public partial class MainWindowViewModel : ViewModelBase
|
|||||||
return Uri.TryCreate(uriString, UriKind.Absolute, out uri) && (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps);
|
return Uri.TryCreate(uriString, UriKind.Absolute, out uri) && (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FetchUrl(bool useCache = true)
|
private void FetchUrl(bool useCache = true)
|
||||||
{
|
|
||||||
if (IsBusy)
|
|
||||||
{
|
{
|
||||||
WindowNotificationManager.Show(new Notification("Busy", "The browser is currently busy.", NotificationType.Warning));
|
if (IsBusy)
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(Url))
|
|
||||||
{
|
|
||||||
Content = DefaultContent;
|
|
||||||
Debug.WriteLine("URL is empty.");
|
|
||||||
CurrentTab.Header = "New Tab";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsValidHttpUri(Url, out _))
|
|
||||||
{
|
|
||||||
if (Url.StartsWith("//"))
|
|
||||||
{
|
{
|
||||||
Url = $"https:{Url}";
|
WindowNotificationManager.Show(new Notification("Busy", "The browser is currently busy.", NotificationType.Warning));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (string.IsNullOrWhiteSpace(Url))
|
||||||
{
|
{
|
||||||
// Search with duckduckgo
|
Content = DefaultContent;
|
||||||
|
Debug.WriteLine("URL is empty.");
|
||||||
|
CurrentTab.Header = "New Tab";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsValidHttpUri(Url, out _))
|
||||||
|
{
|
||||||
|
if (Url.StartsWith("//"))
|
||||||
|
{
|
||||||
|
Url = $"https:{Url}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Search with duckduckgo
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Url = string.Format(Settings.Current.SearchEngineUrl, Uri.EscapeDataString(Url));
|
||||||
|
}
|
||||||
|
catch (FormatException ex)
|
||||||
|
{
|
||||||
|
WindowNotificationManager.Show(new Notification("Invalid Search Engine URL", $"{ex.Message}", NotificationType.Error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IsBusy = true;
|
||||||
|
Progress = 0;
|
||||||
|
|
||||||
|
_ = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
Debug.WriteLine("Fetching URL...");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Url = string.Format(Settings.Current.SearchEngineUrl, Uri.EscapeDataString(Url));
|
ContentViewModelBase? cachedContent = cacheService.Get(Url);
|
||||||
}
|
if (cachedContent is not null && useCache)
|
||||||
catch (FormatException ex)
|
|
||||||
{
|
|
||||||
WindowNotificationManager.Show(new Notification("Invalid Search Engine URL", $"{ex.Message}", NotificationType.Error));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IsBusy = true;
|
|
||||||
Progress = 0;
|
|
||||||
|
|
||||||
_ = Task.Run(async () =>
|
|
||||||
{
|
|
||||||
Debug.WriteLine("Fetching URL...");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ContentViewModelBase cachedContent = cacheService.Get(Url);
|
|
||||||
if (cachedContent != null && useCache)
|
|
||||||
{
|
|
||||||
Content = cachedContent;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HttpResponseMessage httpResponseMessage = await httpClient.GetAsync(Url);
|
|
||||||
|
|
||||||
string? newUrl = httpResponseMessage.RequestMessage?.RequestUri?.ToString();
|
|
||||||
|
|
||||||
if (newUrl is not null && newUrl != Url)
|
|
||||||
{
|
{
|
||||||
string oldUrl = Url;
|
Content = cachedContent;
|
||||||
Dispatcher.UIThread.Post(() => WindowNotificationManager.Show(new Notification("Redirected", $"Redirected from\n{oldUrl}\nto\n{newUrl}", NotificationType.Warning)));
|
}
|
||||||
Url = newUrl;
|
else
|
||||||
|
{
|
||||||
|
HttpResponseMessage httpResponseMessage = await httpClient.GetAsync(Url);
|
||||||
|
|
||||||
|
string? newUrl = httpResponseMessage.RequestMessage?.RequestUri?.ToString();
|
||||||
|
|
||||||
|
if (newUrl is not null && newUrl != Url)
|
||||||
|
{
|
||||||
|
string oldUrl = Url;
|
||||||
|
Dispatcher.UIThread.Post(() => WindowNotificationManager.Show(new Notification("Redirected", $"Redirected from\n{oldUrl}\nto\n{newUrl}", NotificationType.Warning)));
|
||||||
|
Url = newUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!httpResponseMessage.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
IsBusy = false;
|
||||||
|
|
||||||
|
StringBuilder errorMessage = new();
|
||||||
|
|
||||||
|
_ = errorMessage.AppendLine($"# {(int)httpResponseMessage.StatusCode} {httpResponseMessage.StatusCode}");
|
||||||
|
_ = errorMessage.AppendLine($"Failed to fetch URL: {httpResponseMessage.ReasonPhrase}");
|
||||||
|
|
||||||
|
Content = new MarkdownContentViewModel("Error", errorMessage.ToString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Content = await contentProcessorManager.ProcessContent(httpResponseMessage, new Progress<ProcessingProgress>(p => Progress = p.Percentage));
|
||||||
|
cacheService.Set(Url, Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!httpResponseMessage.IsSuccessStatusCode)
|
Dispatcher.UIThread.Post(() => CurrentTab.Header = Content.Title);
|
||||||
|
}
|
||||||
|
catch (HttpRequestException e)
|
||||||
|
{
|
||||||
|
StringBuilder errorMessage = new();
|
||||||
|
|
||||||
|
if (e.StatusCode is not null)
|
||||||
{
|
{
|
||||||
IsBusy = false;
|
_ = errorMessage.AppendLine($"# {(int)e.StatusCode} {e.StatusCode}");
|
||||||
|
Dispatcher.UIThread.Post(() => CurrentTab.Header = $"Error: {(int)e.StatusCode} {e.StatusCode}");
|
||||||
StringBuilder errorMessage = new();
|
}
|
||||||
|
else
|
||||||
_ = errorMessage.AppendLine($"# {(int)httpResponseMessage.StatusCode} {httpResponseMessage.StatusCode}");
|
{
|
||||||
_ = errorMessage.AppendLine($"Failed to fetch URL: {httpResponseMessage.ReasonPhrase}");
|
Dispatcher.UIThread.Post(() => CurrentTab.Header = $"Error: {e.GetType().Name}");
|
||||||
|
|
||||||
Content = new MarkdownContentViewModel("Error", errorMessage.ToString());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Content = await contentProcessorManager.ProcessContent(httpResponseMessage, new Progress<ProcessingProgress>(p => Progress = p.Percentage));
|
_ = errorMessage.AppendLine($"# {e.HttpRequestError}");
|
||||||
cacheService.Set(Url, Content);
|
_ = errorMessage.AppendLine($"Failed to fetch URL: {e.Message}");
|
||||||
}
|
|
||||||
|
|
||||||
Dispatcher.UIThread.Post(() => CurrentTab.Header = Content.Title);
|
Content = new MarkdownContentViewModel("Error", errorMessage.ToString());
|
||||||
}
|
|
||||||
catch (HttpRequestException e)
|
|
||||||
{
|
|
||||||
StringBuilder errorMessage = new();
|
|
||||||
|
|
||||||
if (e.StatusCode is not null)
|
|
||||||
{
|
|
||||||
_ = errorMessage.AppendLine($"# {(int)e.StatusCode} {e.StatusCode}");
|
|
||||||
Dispatcher.UIThread.Post(() => CurrentTab.Header = $"Error: {(int)e.StatusCode} {e.StatusCode}");
|
|
||||||
}
|
}
|
||||||
else
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
StringBuilder errorMessage = new();
|
||||||
|
|
||||||
|
_ = errorMessage.AppendLine($"# {e.GetType().Name}");
|
||||||
|
_ = errorMessage.AppendLine($"Failed to fetch URL: {e.Message}");
|
||||||
|
|
||||||
|
Content = new MarkdownContentViewModel("Error", errorMessage.ToString());
|
||||||
Dispatcher.UIThread.Post(() => CurrentTab.Header = $"Error: {e.GetType().Name}");
|
Dispatcher.UIThread.Post(() => CurrentTab.Header = $"Error: {e.GetType().Name}");
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
_ = errorMessage.AppendLine($"# {e.HttpRequestError}");
|
{
|
||||||
_ = errorMessage.AppendLine($"Failed to fetch URL: {e.Message}");
|
IsBusy = false;
|
||||||
|
}
|
||||||
Content = new MarkdownContentViewModel("Error", errorMessage.ToString());
|
});
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
StringBuilder errorMessage = new();
|
|
||||||
|
|
||||||
_ = errorMessage.AppendLine($"# {e.GetType().Name}");
|
|
||||||
_ = errorMessage.AppendLine($"Failed to fetch URL: {e.Message}");
|
|
||||||
|
|
||||||
Content = new MarkdownContentViewModel("Error", errorMessage.ToString());
|
|
||||||
Dispatcher.UIThread.Post(() => CurrentTab.Header = $"Error: {e.GetType().Name}");
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IsBusy = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -83,9 +83,8 @@
|
|||||||
<Grid IsEnabled="{Binding !IsBusy}" ColumnDefinitions="Auto, Auto, Auto, Auto, *, Auto">
|
<Grid IsEnabled="{Binding !IsBusy}" ColumnDefinitions="Auto, Auto, Auto, Auto, *, Auto">
|
||||||
<Button Grid.Column="0" i:Attached.Icon="fa-solid fa-caret-left" IsEnabled="{Binding BackEnabled}" Command="{Binding Back}" />
|
<Button Grid.Column="0" i:Attached.Icon="fa-solid fa-caret-left" IsEnabled="{Binding BackEnabled}" Command="{Binding Back}" />
|
||||||
<Button Grid.Column="1" i:Attached.Icon="fa-solid fa-caret-right" IsEnabled="{Binding ForwardEnabled}" Command="{Binding Forward}" />
|
<Button Grid.Column="1" i:Attached.Icon="fa-solid fa-caret-right" IsEnabled="{Binding ForwardEnabled}" Command="{Binding Forward}" />
|
||||||
<Button Grid.Column="2" i:Attached.Icon="fa-solid fa-rotate-right" Command="{Binding Browse}" />
|
<Button Grid.Column="2" i:Attached.Icon="fa-solid fa-rotate-right" Command="{Binding Reload}" />
|
||||||
<Button Grid.Column="3" i:Attached.Icon="fa-solid fa-house" Command="{StaticResource HomeCommand}" />
|
<Button Grid.Column="3" i:Attached.Icon="fa-solid fa-house" Command="{StaticResource HomeCommand}" />
|
||||||
<Button Grid.Column="4" i:Attached.Icon="fa-solid fa-sync" Command="{Binding Reload}" />
|
|
||||||
|
|
||||||
<Grid Grid.Column="4">
|
<Grid Grid.Column="4">
|
||||||
<TextBox IsVisible="{Binding !IsBusy}" Watermark="Search or type a URL" Text="{Binding Url}" BorderThickness="0">
|
<TextBox IsVisible="{Binding !IsBusy}" Watermark="Search or type a URL" Text="{Binding Url}" BorderThickness="0">
|
||||||
|
|||||||
Reference in New Issue
Block a user