diff --git a/Database/BrowsingDatabase.cs b/Database/BrowsingDatabase.cs index f380406..db9b58c 100644 --- a/Database/BrowsingDatabase.cs +++ b/Database/BrowsingDatabase.cs @@ -236,25 +236,23 @@ public bool TryGetCapsule(string hostname, out Capsule capsule) return capsule != null; } - public void AcceptHostCertificate(string host) + public void RemoveHostCertificate(string host) { if (!TryGetHostCertificate(host, out var cert)) { - _logger.LogWarning(@"Cannot accept a host certificate for {Host} that has not yet been stored", host); + _logger.LogWarning(@"Cannot removed stored certificate metadata for unknown host {Host}", host); return; } - _logger.LogDebug(@"Accepting new certificate for host {Host}", host); - - cert.Accepted = true; + _logger.LogDebug(@"Removing certificate metadata for host {Host}", host); try { - _database.Update(cert); + _database.Delete(cert); } catch (Exception e) { - _logger.LogError(e, @"Exception thrown while accepting a new host certificate"); + _logger.LogError(e, @"Exception thrown while removing a host certificate"); } } diff --git a/Interfaces/IBrowsingDatabase.cs b/Interfaces/IBrowsingDatabase.cs index 340a42d..83ce60f 100644 --- a/Interfaces/IBrowsingDatabase.cs +++ b/Interfaces/IBrowsingDatabase.cs @@ -19,7 +19,7 @@ public interface IBrowsingDatabase : INotifyPropertyChanged, ICertificateDatabas IEnumerable GetVisitedPage(int page, out bool lastPage); void AddVisitedPage(Visited visited); bool TryGetHostCertificate(string host, out HostCertificate certificate); - void AcceptHostCertificate(string host); + void RemoveHostCertificate(string host); Task UpdateBookmarkOrder(); Task UpdateTabOrder(); void Update(T obj); diff --git a/Models/Tab.cs b/Models/Tab.cs index 04e9399..108bd2b 100644 --- a/Models/Tab.cs +++ b/Models/Tab.cs @@ -296,4 +296,9 @@ public virtual void OnLocationChanged() { OnPropertyChanged(nameof(Location)); } + + public virtual void OnHasFindNextQueryChanged() + { + OnPropertyChanged(nameof(HasFindNextQuery)); + } } \ No newline at end of file diff --git a/Platforms/Android/ActionMenuClickHandler.cs b/Platforms/Android/ActionMenuClickHandler.cs index 8b62546..c6f8ef6 100644 --- a/Platforms/Android/ActionMenuClickHandler.cs +++ b/Platforms/Android/ActionMenuClickHandler.cs @@ -15,8 +15,6 @@ public ActionMenuClickHandler(T argument, Action action) _action = action; } - public IntPtr Handle { get; } - public bool OnMenuItemClick(IMenuItem item) { _action?.Invoke(_argument); @@ -33,8 +31,6 @@ public ActionMenuClickHandler(Action action) _action = action; } - public IntPtr Handle { get; } - public bool OnMenuItemClick(IMenuItem item) { _action?.Invoke(); diff --git a/Platforms/Android/Resources/values/styles.xml b/Platforms/Android/Resources/values/styles.xml index c85b1ab..c89bf52 100644 --- a/Platforms/Android/Resources/values/styles.xml +++ b/Platforms/Android/Resources/values/styles.xml @@ -2,26 +2,26 @@ diff --git a/Resources/Localization/Text.resx b/Resources/Localization/Text.resx index a5d04e1..62fc776 100644 --- a/Resources/Localization/Text.resx +++ b/Resources/Localization/Text.resx @@ -400,73 +400,73 @@ Share URL - Toggle visible + Toggle visible - Toggle the visibility of the password + Toggle the visibility of the password - Upload + Upload - token + token - Upload Text + Upload Text - Upload File + Upload File - Allow IPv6 requests + Allow IPv6 requests - Preview + Preview - An example of a page rendered using the selected theme + An example of a page rendered using the selected theme - Version + Version - The application's version number + The application's version number - Copy + Copy - Copy the version number + Copy the version number - Information + Information - Display information about the page + Display information about the page - Bookmark + Bookmark - Toggle a bookmark for the current page + Toggle a bookmark for the current page - Home + Home - Hold to set a home page, tap to navigate to the home page + Hold to set a home page, tap to navigate to the home page - Next + Next - Find the next occurrence of the text being searched for + Find the next occurrence of the text being searched for - That address is invalid + That address is invalid - What's New + What's New Swipe to move between tabs diff --git a/Resources/Raw/whats-new.html b/Resources/Raw/whats-new.html index 77b41ac..f4a8141 100644 --- a/Resources/Raw/whats-new.html +++ b/Resources/Raw/whats-new.html @@ -9,6 +9,11 @@ margin-top: 0!important; } +

Version 1.4.8 - July 28th, 2024

+
    +
  • #47 Find in Page now works correctly.
  • +
  • #26, #48 Fixed an issue which was causing the app to repeatedly prompt the user to accept a changed host certificate.
  • +

Version 1.4.7 - January 6th, 2024

Happy new year!

    diff --git a/RosyCrow.csproj b/RosyCrow.csproj index 2fd2f98..1b24277 100644 --- a/RosyCrow.csproj +++ b/RosyCrow.csproj @@ -89,31 +89,31 @@ - - - - - - + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - - - - + + + + + - - - - - + + + + + diff --git a/Views/BrowserView.xaml.cs b/Views/BrowserView.xaml.cs index 5ce3625..2f950ae 100644 --- a/Views/BrowserView.xaml.cs +++ b/Views/BrowserView.xaml.cs @@ -42,6 +42,8 @@ public partial class BrowserView : ContentView private bool _resetFindNext; private Tab _tab; private bool _hasEverLoaded; + private bool _newCertAccepted; + private bool _newCertRejected; public BrowserView() : this(MauiProgram.Services.GetRequiredService(), @@ -72,25 +74,6 @@ public BrowserView(IOpalClient geminiClient, ISettingsDatabase settingsDatabase, _geminiClient.RemoteCertificateUnrecognizedCallback = RemoteCertificateUnrecognizedCallback; } - public bool HasFindNextQuery - { - get => !string.IsNullOrEmpty(FindNextQuery); - } - - public string FindNextQuery - { - get => _findNextQuery; - private set - { - if (value == _findNextQuery) - return; - - _findNextQuery = value; - OnPropertyChanged(); - OnPropertyChanged(nameof(HasFindNextQuery)); - } - } - private async Task RemoteCertificateUnrecognizedCallback(RemoteCertificateUnrecognizedArgs arg) { if (_tab.ParentPage == null) @@ -109,7 +92,14 @@ private async Task RemoteCertificateUnrecognizedCallback(RemoteCertificateUnreco Text.BrowserView_RemoteCertificateUnrecognizedCallback_No); if (arg.AcceptAndTrust) - _browsingDatabase.AcceptHostCertificate(arg.Host); + { + _browsingDatabase.RemoveHostCertificate(arg.Host); + _newCertAccepted = true; + } + else + { + _newCertRejected = true; + } } private async Task RemoteCertificateInvalidCallback(RemoteCertificateInvalidArgs arg) @@ -189,17 +179,17 @@ public void GoBack() public void ClearFindResults() { - FindNextQuery = null; + _tab.FindNextQuery = null; OnClearFindNext(); } public void FindTextInPage(string query) { // if the query is different from the last time, then start the search over from the top of the page - if (query != FindNextQuery) + if (query != _tab.FindNextQuery) _resetFindNext = true; - FindNextQuery = query; + _tab.FindNextQuery = query; OnFindNext(); _resetFindNext = false; @@ -280,6 +270,8 @@ public async Task LoadPage(bool triggeredByRefresh = false, bool useCache = fals _tab.CanShowHostCertificate = false; _hasEverLoaded = true; + _newCertRejected = false; + _newCertAccepted = false; if (_tab.Location == null || _tab.Location.Scheme == Constants.InternalScheme) { @@ -309,14 +301,14 @@ public async Task LoadPage(bool triggeredByRefresh = false, bool useCache = fals _tab.CanPrint = false; - if (HasFindNextQuery) + if (_tab.HasFindNextQuery) ClearFindResults(); _logger.LogInformation(@"Navigating to {URI}", _tab.Location); try { - for (var attempts = 0; attempts < Constants.MaxRequestAttempts; attempts++) + for (var attempts = 0; attempts < Constants.MaxRequestAttempts || _newCertAccepted; attempts++) { if (useCache && !triggeredByRefresh) { @@ -354,6 +346,13 @@ public async Task LoadPage(bool triggeredByRefresh = false, bool useCache = fals _logger.LogInformation(@"Request finished after {Attempts} attempt(s)", attempts + 1); break; } + + if (_newCertAccepted) + { + // the host's certificate changed and was accepted by the user; we should try the request again + _newCertAccepted = false; + continue; + } } } catch (Exception e) @@ -448,6 +447,15 @@ private async Task HandleGeminiResponse(IGeminiResponse response // // Currently this only happens in the case of invalid or rejected remote // certificates, where re-sending the request would not make sense + + if (_tab.ParentPage != null && !_newCertRejected) + { + await _tab.ParentPage.DisplayAlertOnMainThread(Text.BrowserView_LoadPage_Error, + "The page could not be displayed due to a fatal error.", Text.BrowserView_LoadPage_OK); + } + + _logger.LogError(@"A fatal exception occurred when sending the request: {Message}", error.Message); + return ResponseAction.Finished; } @@ -615,6 +623,7 @@ protected virtual void OnFindNext() protected virtual void OnClearFindNext() { ClearMatches?.Invoke(this, EventArgs.Empty); + _tab.OnHasFindNextQueryChanged(); } private string CreateTabLabel() @@ -672,7 +681,7 @@ private void PageWebView_OnHandlerChanged(object sender, EventArgs e) FindNext += (_, _) => { if (_resetFindNext) // new query - webViewHandler.PlatformView.FindAllAsync(FindNextQuery); + webViewHandler.PlatformView.FindAllAsync(_tab.FindNextQuery); else // existing query; continue forward webViewHandler.PlatformView.FindNext(true); }; @@ -685,7 +694,7 @@ private void PageWebView_OnHandlerChanged(object sender, EventArgs e) if (count == 0) { _tab.ParentPage.ShowToast(Text.BrowserView_FindNext_No_instances_found, ToastDuration.Short); - FindNextQuery = null; + _tab.FindNextQuery = null; } else { @@ -722,7 +731,7 @@ private void BrowserView_OnBindingContextChanged(object sender, EventArgs e) tab.FindNext = new Command(query => FindTextInPage((string)query)); tab.Print = new Command(Print, () => _tab.CanPrint); tab.GoBack = new Command(GoBack, () => _tab.RecentHistory.TryPeek(out _)); - tab.ClearFind = new Command(ClearFindResults, () => HasFindNextQuery); + tab.ClearFind = new Command(ClearFindResults, () => _tab.HasFindNextQuery); tab.Load = new Command(async () => await LoadPage(false, true).ConfigureAwait(false), () => !_isLoading && _tab.Selected); tab.Location = tab.Url.ToGeminiUri(); diff --git a/Views/MainPage.xaml.cs b/Views/MainPage.xaml.cs index 726fe1f..f6f4c26 100644 --- a/Views/MainPage.xaml.cs +++ b/Views/MainPage.xaml.cs @@ -577,6 +577,12 @@ protected override bool OnBackButtonPressed() return true; } + if ((CurrentTab?.HasFindNextQuery ?? false) && + (CurrentTab?.ClearFind?.CanExecute(null) ?? false)) + { + CurrentTab.ClearFind.Execute(null); + } + if (CurrentTab?.GoBack.CanExecute(null) ?? false) { CurrentTab.GoBack.Execute(null); @@ -702,8 +708,8 @@ private async Task TryFindInPage() IsMenuExpanded = false; - if (CurrentTab?.FindNext.CanExecute(CurrentTab.FindNextQuery) ?? false) - CurrentTab.FindNext.Execute(CurrentTab.FindNextQuery); + if (CurrentTab?.FindNext.CanExecute(query) ?? false) + CurrentTab.FindNext.Execute(query); } catch (Exception e) {