Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check for updates automatically (but don't install) #13437

Merged
merged 12 commits into from
Apr 6, 2023
66 changes: 66 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#include <LibraryResources.h>
#include <TerminalCore/ControlKeyStates.hpp>
#include <til/latch.h>
#include <WtExeUtils.h>

#include <winrt/Windows.Services.Store.h>

#include "../../types/inc/utils.hpp"
#include "ColorHelper.h"
Expand Down Expand Up @@ -727,12 +730,75 @@ namespace winrt::TerminalApp::implementation
}
}

bool TerminalPage::UpdatesAvailable() const
{
return _pendingUpdateVersion.size() > 0;
}

winrt::hstring TerminalPage::PendingUpdateVersion() const
{
return _pendingUpdateVersion;
}

void TerminalPage::_SetPendingUpdateVersion(const winrt::hstring& version)
{
_pendingUpdateVersion = version;
_PropertyChangedHandlers(*this, WUX::Data::PropertyChangedEventArgs{ L"PendingUpdateVersion" });
_PropertyChangedHandlers(*this, WUX::Data::PropertyChangedEventArgs{ L"UpdatesAvailable" });
}

winrt::fire_and_forget TerminalPage::_QueueUpdateCheck()
{
auto strongThis = get_strong();
auto now{ std::chrono::system_clock::now() };
if (now - _lastUpdateCheck < std::chrono::days{ 1 })
{
co_return;
}
_lastUpdateCheck = now;

if (!IsPackaged())
{
co_return;
}

co_await wil::resume_foreground(strongThis->_tabView.Dispatcher());
_SetPendingUpdateVersion({});
CheckingForUpdates(true);

try
{
#ifdef WT_BRANDING_DEV
co_await winrt::resume_after(std::chrono::seconds{ 3 });
co_await wil::resume_foreground(strongThis->_tabView.Dispatcher());
_SetPendingUpdateVersion(L"X.Y.Z");
#else // release build, likely has a store context
auto storeContext = winrt::Windows::Services::Store::StoreContext::GetDefault();
auto updates = co_await storeContext.GetAppAndOptionalStorePackageUpdatesAsync();
co_await wil::resume_foreground(strongThis->_tabView.Dispatcher());
if (updates.Size() > 0)
{
auto version = updates.GetAt(0).Package().Id().Version();
_SetPendingUpdateVersion(fmt::format(L"{0}.{1}.{2}", version.Major, version.Minor, version.Revision));
}
#endif
}
catch (...)
{
// do nothing on failure
}

co_await wil::resume_foreground(strongThis->_tabView.Dispatcher());
CheckingForUpdates(false);
}

// Method Description:
// - Show a dialog with "About" information. Displays the app's Display
// Name, version, getting started link, documentation link, release
// Notes link, and privacy policy link.
void TerminalPage::_ShowAboutDialog()
{
_QueueUpdateCheck();
_ShowDialogHelper(L"AboutDialog");
}

Expand Down
10 changes: 10 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,13 @@ namespace winrt::TerminalApp::implementation

void OpenSettingsUI();

bool UpdatesAvailable() const;
winrt::hstring PendingUpdateVersion() const;

WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);

WINRT_OBSERVABLE_PROPERTY(bool, CheckingForUpdates, _PropertyChangedHandlers, false);

// -------------------------------- WinRT Events ---------------------------------
TYPED_EVENT(TitleChanged, IInspectable, winrt::hstring);
TYPED_EVENT(LastTabClosed, IInspectable, winrt::TerminalApp::LastTabClosedEventArgs);
Expand Down Expand Up @@ -231,6 +236,11 @@ namespace winrt::TerminalApp::implementation
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowMultiLinePasteWarningDialog();
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowLargePasteWarningDialog();

winrt::fire_and_forget _QueueUpdateCheck();
void _SetPendingUpdateVersion(const winrt::hstring& pendingUpdateVersion);
std::chrono::system_clock::time_point _lastUpdateCheck{};
winrt::hstring _pendingUpdateVersion;

void _CreateNewTabFlyout();
void _OpenNewTabDropdown();
HRESULT _OpenNewTab(const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs, winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection existingConnection = nullptr);
Expand Down
4 changes: 4 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.idl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ namespace TerminalApp

TaskbarState TaskbarState{ get; };

Boolean CheckingForUpdates { get; };
Boolean UpdatesAvailable { get; };
String PendingUpdateVersion { get; };

event Windows.Foundation.TypedEventHandler<Object, String> TitleChanged;
event Windows.Foundation.TypedEventHandler<Object, LastTabClosedEventArgs> LastTabClosed;
event Windows.Foundation.TypedEventHandler<Object, Windows.UI.Xaml.UIElement> SetTitleBarContent;
Expand Down
14 changes: 14 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,20 @@
<Run x:Uid="AboutDialog_VersionLabel" />
<Run Text="{x:Bind ApplicationVersion}" />
</TextBlock>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal" Visibility="{x:Bind CheckingForUpdates, Mode=OneWay}" Padding="0,4,0,4" VerticalAlignment="Center">
<mux:ProgressRing Width="16" Height="16" IsIndeterminate="True" IsActive="True" />
<TextBlock Text="Checking for updates..." Padding="4,0,0,0"/>
</StackPanel>
<StackPanel Orientation="Vertical" Visibility="{x:Bind UpdatesAvailable, Mode=OneWay}" Padding="0,4,0,4" VerticalAlignment="Center">
<TextBlock IsTextSelectionEnabled="True">
<Run Text="An update is available." /> <LineBreak />
<Run x:Uid="AboutDialog_VersionLabel" />
<Run Text="{x:Bind PendingUpdateVersion, Mode=OneWay}" />
</TextBlock>
<Button Content="Install now" Margin="0"></Button>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.... Do we know how to force the store to install an update for us? StoreContext.RequestDownloadAndInstallStorePackageUpdatesAsync presumably? Can we even locally test if that works?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you mean without user confirmation (silently) this could help according to docs: https://docs.microsoft.com/en-us/windows/uwp/packaging/self-install-package-updates#download-and-install-package-updates-silently

But why didn't you only opening the updates page in store? And what happened if stire isn't available/removed?

</StackPanel>
</StackPanel>
<HyperlinkButton x:Uid="AboutDialog_DocumentationLink"
NavigateUri="https://go.microsoft.com/fwlink/?linkid=2125416" />
<HyperlinkButton x:Uid="AboutDialog_ReleaseNotesLink"
Expand Down