diff --git a/Azure-Pipelines/BurntToast-Template.psm1 b/Azure-Pipelines/BurntToast-Template.psm1 index 193abc2..791caab 100644 --- a/Azure-Pipelines/BurntToast-Template.psm1 +++ b/Azure-Pipelines/BurntToast-Template.psm1 @@ -1,31 +1,38 @@ $WinMajorVersion = (Get-CimInstance -ClassName Win32_OperatingSystem -Property Version).Version.Split('.')[0] -if ($WinMajorVersion -ge 10) -{ +if ($WinMajorVersion -ge 10) { $Library = @( Get-ChildItem -Path $PSScriptRoot\lib\*.dll -Recurse -ErrorAction SilentlyContinue ) + # Add one class from each expected DLL here: + $LibraryMap = @{ + 'Microsoft.Toolkit.Uwp.Notifications.dll' = 'Microsoft.Toolkit.Uwp.Notifications.ToastContent' + } + $Script:Config = Get-Content -Path $PSScriptRoot\config.json -ErrorAction SilentlyContinue | ConvertFrom-Json - $Script:DefaultImage = "$PSScriptRoot$($Script:Config.AppLogo)" + $Script:DefaultImage = if ($Script:Config.AppLogo -match '^[.\\]') { + "$PSScriptRoot$($Script:Config.AppLogo)" + } else { + $Script:Config.AppLogo + } - Foreach($Type in $Library) - { - Try { - Add-Type -Path $Type.FullName - } Catch { + foreach ($Type in $Library) { + try { + if (-not ($LibraryMap[$Type.Name] -as [type])) { + Add-Type -Path $Type.FullName -ErrorAction Stop + } + } catch { Write-Error -Message "Failed to load library $($Type.FullName): $_" } } Export-ModuleMember -Alias 'Toast' Export-ModuleMember -Function $PublicFunctions - + # Register default AppId New-BTAppId $null = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] -} -else -{ +} else { throw 'This version of BurntToast will only work on Windows 10. If you would like to use BurntToast on Windows 8, please use version 0.4' } diff --git a/Azure-Pipelines/build.ps1 b/Azure-Pipelines/build.ps1 index 0cef473..33b9241 100644 --- a/Azure-Pipelines/build.ps1 +++ b/Azure-Pipelines/build.ps1 @@ -81,8 +81,6 @@ if($Test.IsPresent) { $RelevantFiles = (Get-ChildItem ./BurntToast -Recurse -Include "*.psm1","*.ps1").FullName - $RelevantFiles = (Get-ChildItem ./BurntToast -Recurse -Include "*.psm1","*.ps1").FullName - if ($env:TF_BUILD) { $res = Invoke-Pester "./Tests" -OutputFormat NUnitXml -OutputFile TestResults.xml -CodeCoverage $RelevantFiles -PassThru if ($res.FailedCount -gt 0) { throw "$($res.FailedCount) tests failed." } diff --git a/BurntToast/BurntToast.psd1 b/BurntToast/BurntToast.psd1 index 9e4370e..cb36d04 100644 --- a/BurntToast/BurntToast.psd1 +++ b/BurntToast/BurntToast.psd1 @@ -1,6 +1,6 @@ @{ RootModule = 'BurntToast.psm1' - ModuleVersion = '0.7.0' + ModuleVersion = '0.7.1' # Can only use CompatiblePSEditions if PowerShellVersion is set to 5.1, not sure about limiting this to that version yet. # CompatiblePSEditions = @('Desktop') GUID = '751a2aeb-a68f-422e-a2ea-376bdd81612a' @@ -40,18 +40,19 @@ LicenseUri = 'https://github.com/Windos/BurntToast/blob/master/LICENSE' ProjectUri = 'https://github.com/Windos/BurntToast' IconUri = 'https://raw.githubusercontent.com/Windos/BurntToast/master/Media/BurntToast-Logo.png' - ReleaseNotes = '# 0.7.0 + ReleaseNotes = '# 0.7.1 -* HEADLINE FEATURE: My People "Shoulder Tap" notifications have been implemented -* You can now specify images on the network via UNC paths. Fix for #56 -* We''re now properly supporting bindable text, and removing the curly braces more gracefully -* Get a list of all toasts you''ve sent, which have not been dismissed by the user, using Get-BTHistory -* Remove toasts you''ve sent, using Remove-BTNotification -* Set expiration times on toasts using the new ExpirationTime parameter on New-BurntToastNotification and Submit-BTNotification - * Toasts which have expired are removed from the Action Center -* Send toasts directly to the Action Center, and avoid showing them on screen, with the new SuppressPopup switch on New-BurntToastNotification and Submit-BTNotification -* You can now adjust a toasts timestamp (both past and future) using the CustomTimestamp parameter on New-BurntToastNotification and New-BTContent - * If not specified, the system uses the time at which the toast was received and this may not accuratly reflect the intent of the notification +* Update: Microsoft Community Toolkit to 6.0.0 +* New: Support relative paths on images +* New: "ScheduledToast" switch added to `Get-BTHistory` which returns scheduled or snoozed toast notifications +* Enhancement: Libraries only loaded on module import if libraries not already loaded +* Enhancement: Validate that image paths exist +* Fix: Reverted to XML clean up to remove curly braces if databindings are not being used (Issue #72) + +## Known Issues + +* Regardless of what snooze option is chosen, a snoozed toast will re-appear after 9 minutes + * Cause is unknown and isn''t unique to v0.7.1, will be investigated while working on v0.7.2 ' } } diff --git a/BurntToast/BurntToast.psm1 b/BurntToast/BurntToast.psm1 index 24bceb2..99012c5 100644 --- a/BurntToast/BurntToast.psm1 +++ b/BurntToast/BurntToast.psm1 @@ -1,34 +1,36 @@ $WinMajorVersion = (Get-CimInstance -ClassName Win32_OperatingSystem -Property Version).Version.Split('.')[0] -if ($WinMajorVersion -ge 10) -{ - $Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue ) +if ($WinMajorVersion -ge 10) { + $Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue ) $Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue ) $Library = @( Get-ChildItem -Path $PSScriptRoot\lib\*.dll -Recurse -ErrorAction SilentlyContinue ) + # Add one class from each expected DLL here: + $LibraryMap = @{ + 'Microsoft.Toolkit.Uwp.Notifications.dll' = 'Microsoft.Toolkit.Uwp.Notifications.ToastContent' + } + $Script:Config = Get-Content -Path $PSScriptRoot\config.json -ErrorAction SilentlyContinue | ConvertFrom-Json - $Script:DefaultImage = "$PSScriptRoot$($Script:Config.AppLogo)" + $Script:DefaultImage = if ($Script:Config.AppLogo -match '^[.\\]') { + "$PSScriptRoot$($Script:Config.AppLogo)" + } else { + $Script:Config.AppLogo + } - Foreach($Import in @($Public + $Private)) - { - Try - { + foreach ($Import in @($Public + $Private)) { + try { . $Import.FullName - } - Catch - { + } catch { Write-Error -Message "Failed to import function $($Import.FullName): $_" } } - Foreach($Type in $Library) - { - Try - { - Add-Type -Path $Type.FullName - } - Catch - { + foreach ($Type in $Library) { + try { + if (-not ($LibraryMap[$Type.Name] -as [type])) { + Add-Type -Path $Type.FullName -ErrorAction Stop + } + } catch { Write-Error -Message "Failed to load library $($Type.FullName): $_" } } @@ -40,8 +42,6 @@ if ($WinMajorVersion -ge 10) New-BTAppId $null = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] -} -else -{ +} else { throw 'This version of BurntToast will only work on Windows 10. If you would like to use BurntToast on Windows 8, please use version 0.4' } diff --git a/BurntToast/Private/Optimize-BTImageSource.ps1 b/BurntToast/Private/Optimize-BTImageSource.ps1 index 414c3fc..f41cfee 100644 --- a/BurntToast/Private/Optimize-BTImageSource.ps1 +++ b/BurntToast/Private/Optimize-BTImageSource.ps1 @@ -19,6 +19,10 @@ function Optimize-BTImageSource { $NewFilePath } else { - $Source + try { + (Get-Item -Path $Source -ErrorAction Stop).FullName + } catch { + Write-Warning -Message "The image source '$Source' doesn't exist, failed back to icon." + } } } diff --git a/BurntToast/Public/Get-BTHistory.ps1 b/BurntToast/Public/Get-BTHistory.ps1 index 6fe058a..da0fc83 100644 --- a/BurntToast/Public/Get-BTHistory.ps1 +++ b/BurntToast/Public/Get-BTHistory.ps1 @@ -8,11 +8,14 @@ function Get-BTHistory { The object returned includes tag and group information which can be used with the Remove-BTNotification function to clear specific notification from the Action Center. + Using the ScheduledToast switch you can get all toast notifications that have been scheduled to display, whether by scheduling outright or snoozing. + .INPUTS STRING .OUTPUTS - TODO + ToastNotification + ScheduledToastNotification .EXAMPLE Get-BTHistory @@ -28,18 +31,25 @@ function Get-BTHistory { # A string that uniquely identifies a toast notification. Submitting a new toast with the same identifier as a previous toast will replace the previous toast. # # This is useful when updating the progress of a process, using a progress bar, or otherwise correcting/updating the information on a toast. - [string] $UniqueIdentifier + [string] $UniqueIdentifier, + + # Specified that you need to see scheduled toast notifications, rather the those in the Action Center. + [switch] $ScheduledToast ) if (!(Test-Path -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Notifications\Settings\$AppId")) { throw "The AppId $AppId is not present in the registry, please run New-BTAppId to avoid inconsistent Toast behaviour." } else { - $History = [Windows.UI.Notifications.ToastNotificationManager]::History.GetHistory($AppId) + $Toasts = if ($ScheduledToast) { + [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($AppId).GetScheduledToastNotifications() + } else { + [Windows.UI.Notifications.ToastNotificationManager]::History.GetHistory($AppId) + } if ($UniqueIdentifier) { - $History | Where-Object {$_.Tag -eq $UniqueIdentifier -or $_.Group -eq $UniqueIdentifier} + $Toasts | Where-Object {$_.Tag -eq $UniqueIdentifier -or $_.Group -eq $UniqueIdentifier} } else { - $History + $Toasts } } } diff --git a/BurntToast/Public/Submit-BTNotification.ps1 b/BurntToast/Public/Submit-BTNotification.ps1 index dd037f4..0f3447b 100644 --- a/BurntToast/Public/Submit-BTNotification.ps1 +++ b/BurntToast/Public/Submit-BTNotification.ps1 @@ -57,73 +57,85 @@ $ToastXml = [Windows.Data.Xml.Dom.XmlDocument]::new() - $ToastXml.LoadXml($Content.GetContent()) - $Toast = [Windows.UI.Notifications.ToastNotification]::new($ToastXml) - - if ($UniqueIdentifier) { - $Toast.Group = $UniqueIdentifier - $Toast.Tag = $UniqueIdentifier - } - - if ($ExpirationTime) { - $Toast.ExpirationTime = $ExpirationTime - } - - if ($SuppressPopup.IsPresent) { - $Toast.SuppressPopup = $SuppressPopup + if (-not $DataBinding) { + $CleanContent = $Content.GetContent().Replace('{', '') + $CleanContent = $CleanContent.Replace('}', '') + $CleanContent = $CleanContent.Replace('="{', '="') + $CleanContent = $CleanContent.Replace('}" ', '" ') + + $ToastXml.LoadXml($CleanContent) + } else { + $ToastXml.LoadXml($Content.GetContent()) } - $DataDictionary = New-Object 'system.collections.generic.dictionary[string,string]' + $Toast = [Windows.UI.Notifications.ToastNotification]::new($ToastXml) if ($DataBinding) { - foreach ($Key in $DataBinding.Keys) { - $DataDictionary.Add($Key, $DataBinding.$Key) - } - } - - foreach ($Child in $Content.Visual.BindingGeneric.Children) { - if ($Child.GetType().Name -eq 'AdaptiveText') { - $BindingName = $Child.Text.BindingName + $DataDictionary = New-Object 'system.collections.generic.dictionary[string,string]' - if (!$DataDictionary.ContainsKey($BindingName)) { - $DataDictionary.Add($BindingName, $BindingName) + if ($DataBinding) { + foreach ($Key in $DataBinding.Keys) { + $DataDictionary.Add($Key, $DataBinding.$Key) } - } elseif ($Child.GetType().Name -eq 'AdaptiveProgressBar') { - if ($Child.Title) { - $BindingName = $Child.Title.BindingName + } + + foreach ($Child in $Content.Visual.BindingGeneric.Children) { + if ($Child.GetType().Name -eq 'AdaptiveText') { + $BindingName = $Child.Text.BindingName if (!$DataDictionary.ContainsKey($BindingName)) { $DataDictionary.Add($BindingName, $BindingName) } - } + } elseif ($Child.GetType().Name -eq 'AdaptiveProgressBar') { + if ($Child.Title) { + $BindingName = $Child.Title.BindingName - if ($Child.Value) { - $BindingName = $Child.Value.BindingName + if (!$DataDictionary.ContainsKey($BindingName)) { + $DataDictionary.Add($BindingName, $BindingName) + } + } - if (!$DataDictionary.ContainsKey($BindingName)) { - $DataDictionary.Add($BindingName, $BindingName) + if ($Child.Value) { + $BindingName = $Child.Value.BindingName + + if (!$DataDictionary.ContainsKey($BindingName)) { + $DataDictionary.Add($BindingName, $BindingName) + } } - } - if ($Child.ValueStringOverride) { - $BindingName = $Child.ValueStringOverride.BindingName + if ($Child.ValueStringOverride) { + $BindingName = $Child.ValueStringOverride.BindingName - if (!$DataDictionary.ContainsKey($BindingName)) { - $DataDictionary.Add($BindingName, $BindingName) + if (!$DataDictionary.ContainsKey($BindingName)) { + $DataDictionary.Add($BindingName, $BindingName) + } } - } - if ($Child.Status) { - $BindingName = $Child.Status.BindingName + if ($Child.Status) { + $BindingName = $Child.Status.BindingName - if (!$DataDictionary.ContainsKey($BindingName)) { - $DataDictionary.Add($BindingName, $BindingName) + if (!$DataDictionary.ContainsKey($BindingName)) { + $DataDictionary.Add($BindingName, $BindingName) + } } } } + + $Toast.Data = [Windows.UI.Notifications.NotificationData]::new($DataDictionary) } - $Toast.Data = [Windows.UI.Notifications.NotificationData]::new($DataDictionary) + if ($UniqueIdentifier) { + $Toast.Group = $UniqueIdentifier + $Toast.Tag = $UniqueIdentifier + } + + if ($ExpirationTime) { + $Toast.ExpirationTime = $ExpirationTime + } + + if ($SuppressPopup.IsPresent) { + $Toast.SuppressPopup = $SuppressPopup + } if ($SequenceNumber) { $Toast.Data.SequenceNumber = $SequenceNumber diff --git a/BurntToast/lib/Microsoft.Toolkit.Uwp.Notifications/Microsoft.Toolkit.Uwp.Notifications.dll b/BurntToast/lib/Microsoft.Toolkit.Uwp.Notifications/Microsoft.Toolkit.Uwp.Notifications.dll index 93f4267..06fb90f 100644 Binary files a/BurntToast/lib/Microsoft.Toolkit.Uwp.Notifications/Microsoft.Toolkit.Uwp.Notifications.dll and b/BurntToast/lib/Microsoft.Toolkit.Uwp.Notifications/Microsoft.Toolkit.Uwp.Notifications.dll differ diff --git a/BurntToast/lib/Microsoft.Toolkit.Uwp.Notifications/Microsoft.Toolkit.Uwp.Notifications.xml b/BurntToast/lib/Microsoft.Toolkit.Uwp.Notifications/Microsoft.Toolkit.Uwp.Notifications.xml index e7bb003..bd3bde9 100644 --- a/BurntToast/lib/Microsoft.Toolkit.Uwp.Notifications/Microsoft.Toolkit.Uwp.Notifications.xml +++ b/BurntToast/lib/Microsoft.Toolkit.Uwp.Notifications/Microsoft.Toolkit.Uwp.Notifications.xml @@ -573,12 +573,6 @@ The notification XML content as a string. - - - Retrieves the notification XML content as a WinRT Xml document. - - The notification XML content as a WinRT Xml document. - The types of glyphs that can be placed on a badge. @@ -689,24 +683,12 @@ The notification Xml content as a string. - - - Retrieves the notification Xml content as a WinRT Xml document. - - The notification Xml content as a WinRT Xml document. - Retrieves the notification XML content as a string. The notification XML content as a string. - - - Retrieves the notification XML content as a WinRT XML document. - - The notification XML content as a WinRT XML document. - Base notification content interface to retrieve notification Xml as a string. @@ -718,12 +700,6 @@ The notification Xml content as a string. - - - Retrieves the notification Xml content as a WinRT Xml document. - - The notification Xml content as a WinRT Xml document. - Exception returned when invalid notification content is provided. @@ -744,6 +720,393 @@ The absolute value, if any. The provided binding value, if it exists. Otherwise, falls back to the absolute value. + + + Manages the toast notifications for an app including the ability the clear all toast history and removing individual toasts. + + + + + Initializes a new instance of the class. + Do not call this. Instead, call to obtain an instance. + + An AUMID that uniquely identifies your application. + + + + Removes all notifications sent by this app from action center. + + + + + Gets all notifications sent by this app that are currently still in Action Center. + + A collection of toasts. + + + + Removes an individual toast, with the specified tag label, from action center. + + The tag label of the toast notification to be removed. + + + + Removes a toast notification from the action using the notification's tag and group labels. + + The tag label of the toast notification to be removed. + The group label of the toast notification to be removed. + + + + Removes a group of toast notifications, identified by the specified group label, from action center. + + The group label of the toast notifications to be removed. + + + + Helper for .NET Framework applications to display toast notifications and respond to toast events + + + + + A constant that is used as the launch arg when your EXE is launched from a toast notification. + + + + + If not running under the Desktop Bridge, you must call this method to register your AUMID with the Compat library and to + register your COM CLSID and EXE in LocalServer32 registry. Feel free to call this regardless, and we will no-op if running + under Desktop Bridge. Call this upon application startup, before calling any other APIs. + + Your implementation of NotificationActivator. Must have GUID and ComVisible attributes on class. + An AUMID that uniquely identifies your application. + + + + Registers the activator type as a COM server client so that Windows can launch your activator. + + Your implementation of NotificationActivator. Must have GUID and ComVisible attributes on class. + + + + Creates a toast notifier. You must have called first (and also if you're a classic Win32 app), or this will throw an exception. + + + + + + Gets the object. You must have called first (and also if you're a classic Win32 app), or this will throw an exception. + + + + + Gets a value indicating whether http images can be used within toasts. This is true if running under Desktop Bridge. + + + + + Code from https://github.com/qmatteoq/DesktopBridgeHelpers/edit/master/DesktopBridge.Helpers/Helpers.cs + + + + + Apps must implement this activator to handle notification activation. + + + + + + + + This method will be called when the user clicks on a foreground or background activation on a toast. Parent app must implement this method. + + The arguments from the original notification. This is either the launch argument if the user clicked the body of your toast, or the arguments from a button on your toast. + Text and selection values that the user entered in your toast. + Your AUMID. + + + + A single user input key/value pair. + + + + + The key of the user input. + + + + + The value of the user input. + + + + + The COM callback that is triggered when your notification is clicked. + + + + + The method called when your notification is clicked. + + The app id of the app that sent the toast. + The activation arguments from the toast. + The user input from the toast. + The number of user inputs. + + + + Text and selection values that the user entered on your notification. The Key is the ID of the input, and the Value is what the user entered. + + + + + Gets the value of an input with the given key. + + The key of the inpupt. + The value of the input. + + + + Gets all the keys of the inputs. + + + + + Gets all the values of the inputs. + + + + + Gets how many inputs there were. + + + + + Checks whether any inpupts have the given key. + + The key to look for. + A boolean representing whether any inputs have the given key. + + + + Gets an enumerator of the inputs. + + An enumerator of the inputs. + + + + Tries to get the input value for the given key. + + The key of the input to look for. + The value of the input. + True if found an input with the specified key, else false. + + + + Builder class used to create + + + Builder class used to create + + + + + Flag used to create all tile size (Small , Medium, Large and Wide) + + + + + Gets internal instance of . This is equivalent to the call to . + + + + + Initializes a new instance of the class. + + + + + Add a tile layout size that the notification will be displayed on. + + The size of tile that the notification will be displayed on. + Specialized tile content. Use for special tile template. Default to NULL. + The current instance of + + + + Set how the tile notification should display the application branding. + + How branding should appear on the tile + The tile size that the parameter should be applied to. Default to all currently supported tile size. + The current instance of + + + + Set the name that will be used to override the application's name on the tile notification. + + Custom name to display on the tile in place of the application's name + The tile size that parameter should be applied to. Default to all currently supported tile size. + The current instance of + + + + Set the optional background image that stays behind the tile notification. + + Source of the background image + The tile size that the background image should be applied to. Default to all currently supported tile size. + Description of the background image, for user of assistance technology + + Indicating whether Windows should append a query string to the image URI supplied in the Tile notification. + Use this attribute if your server hosts images and can handle query strings, either by retrieving an image variant based on the query strings or by ignoring the query string and returning the image as specified without the query string. + This query string specifies scale, contrast setting, and language. + + The opacity of the black overlay on the background image. + Desired cropping of the image. + The current instance of + + + + Set the optional background image that stays behind the tile notification. + + An instance of as the background image for the tile. + The tile size that the background image should be applied to. Default to all currently supported tile size. + The current instance of + + + + Set the Tile's Peek Image that animate from the top of the tile notification. + + Source of the peek image + The tile size that the peek image should be applied to. Default to all currently supported tile size. + Description of the peek image, for user of assistance technology + + Indicating whether Windows should append a query string to the image URI supplied in the Tile notification. + Use this attribute if your server hosts images and can handle query strings, either by retrieving an image variant based on the query strings or by ignoring the query string and returning the image as specified without the query string. + This query string specifies scale, contrast setting, and language. + + The opacity of the black overlay on the peek image. + Desired cropping of the image. + The current instance of + + + + Set the Tile's Peek Image that animate from the top of the tile notification. + + An instance of for the Tile's peek image + The tile size that the peek image should be applied to. Default to all currently supported tile size. + The current instance of + + + + Set the text stacking (vertical alignment) of the entire binding element. + + Text Stacking Option + The tile size that the peek image should be applied to. Default to all currently supported tile size. + The current instance of + + + + Set the tile's activation arguments for chasable tile notification. + + App-Defined custom arguments that will be passed in when the user click on the tile when this tile notification is being displayed. + The tile size that the custom argument should be applied to. Default to all currently supported tile size. + The current instance of + + + + Add a custom text that will appear on the tile notification. + + Custom text to display on the tile. + The tile size that the custom text would be added to. Default to all currently supported tile size. + Style that controls the text's font size, weight, and opacity. + Indicating whether text wrapping is enabled. For Tiles, this is false by default. + The maximum number of lines the text element is allowed to display. For Tiles, this is infinity by default + The minimum number of lines the text element must display. + The horizontal alignment of the text + + The target locale of the XML payload, specified as a BCP-47 language tags such as "en-US" or "fr-FR". The locale specified here overrides any other specified locale, such as that in binding or visual. + + The current instance of + + + + Add an adaptive child to the tile notification. + + An adaptive child to add + Tile size that the adaptive child should be added to. Default to all currently supported tile size. + The current instance of + + This can be used to add Group and Subgroup to the tile. + + + + + Get the instance of that has been built by the builder with specified configuration so far. + + An instance of that can be used to create tile notification. + + + + Helper method for creating a tile notification content for using Contact tile template. + + Source for the contact picture + Name of the contact + A description of the contact image, for users of assistive technologies. + Indicating whether Windows should append a query string to the image URI supplied in the Tile notification. + Gets or sets the target locale of the XML payload, specified as a BCP-47 language tags such as "en-US" or "fr-FR". The locale specified here overrides any other specified locale, such as that in binding or visual. + An instance of represent a payload of a tile notification. + + + + Helper method for creating a tile notification content for using Iconic tile template. + + Source of the icon image. + A description of the icon image, for users of assistive technologies. + Indicating whether Windows should append a query string to the image URI supplied in the Tile notification. + An instance of represent a payload of a tile notification. + + + + Helper method for creating a tile notification content for using People tile template. + + Sources of pictures that will be used on the people tile. + An instance of represent a payload of a tile notification. + + + + Helper method for creating a tile notification content for using People tile template. + + Sources of pictures with description and image query indicator that will be used on the people tile. + An instance of represent a payload of a tile notification. + + + + Helper method for creating a tile notification content for using People tile template. + + Pictures that will be used on the people tile. + An instance of represent a payload of a tile notification. + + + + Helper method for creating a tile notification content for using Photos tile template. + + Sources of pictures that will be used on the photos tile. + An instance of represent a payload of a tile notification. + + + + Helper method for creating a tile notification content for using Photos tile template. + + Sources of pictures with description and addImageQuery indicator that will be used for the photos tile. + An instance of represent a payload of a tile notification. + + + + Helper method for creating a tile notification content for using Photos tile template. + + Pictures that will be used for the photos tile. + An instance of represent a payload of a tile notification. + Gets or sets a value whether Windows should append a query string to the image URI supplied in the Tile notification. Use this attribute if your server hosts images and can handle query strings, either by retrieving an image variant based on the query strings or by ignoring the query string and returning the image as specified without the query string. This query string specifies scale, contrast setting, and language; for instance, a value of @@ -1031,6 +1394,31 @@ Desktop-only. Both the DisplayName and Square44x44Logo will be shown. On Mobile, this will fallback to Name. + + + Represent the all tile sizes that are available. + + + + + Small Square Tile + + + + + Medium Square Tile + + + + + Wide Rectangle Tile + + + + + Large Square Tile + + Base Tile element, which contains a single visual element. @@ -1047,12 +1435,6 @@ The notification XML content as a string. - - - Retrieves the notification XML content as a WinRT XmlDocument, so that it can be used with a local Tile notification's constructor on either or . - - The notification XML content as a WinRT XmlDocument. - Specify the desired cropping of the image. @@ -1238,6 +1620,238 @@ The binding to look in for matches. True if could re-use existing text element, otherwise false. + + + Builder class used to create + + + Builder class used to create + + + Builder class used to create + + + + + Add a button to the current toast. + + Text to display on the button. + Type of activation this button will use when clicked. Defaults to Foreground. + App-defined string of arguments that the app can later retrieve once it is activated when the user clicks the button. + Optional image icon for the button to display (required for buttons adjacent to inputs like quick reply). + The current instance of + + + + Add a button to the current toast. + + An instance of class that implement for the button that will be used on the toast. + The current instance of + + + + Add an button to the toast that will be display to the right of the input text box, achieving a quick reply scenario. + + ID of an existing in order to have this button display to the right of the input, achieving a quick reply scenario. + Text to display on the button. + Type of activation this button will use when clicked. Defaults to Foreground. + App-defined string of arguments that the app can later retrieve once it is activated when the user clicks the button. + An optional image icon for the button to display (required for buttons adjacent to inputs like quick reply) + The current instance of + + + + Add an input text box that the user can type into. + + Required ID property so that developers can retrieve user input once the app is activated. + Placeholder text to be displayed on the text box when the user hasn't typed any text yet. + Title text to display above the text box. + The current instance of + + + + Add a combo box / drop-down menu that contain options for user to select. + + Required ID property used so that developers can retrieve user input once the app is activated. + List of choices that will be available for user to select. + The current instance of + + + + Add a combo box / drop-down menu that contain options for user to select. + + Required ID property used so that developers can retrieve user input once the app is activated. + Sets which item is selected by default, and refers to the Id property of . If you do not provide this or null, the default selection will be empty (user sees nothing). + List of choices that will be available for user to select. + The current instance of + + + + Add a combo box / drop-down menu that contain options for user to select. + + Required ID property used so that developers can retrieve user input once the app is activated. + Title text to display above the Combo Box. + Sets which item is selected by default, and refers to the Id property of . If you do not provide this or null, the default selection will be empty (user sees nothing). + List of choices that will be available for user to select. + The current instance of + + + + Add a combo box / drop-down menu that contain options for user to select. + + Required ID property used so that developers can retrieve user input once the app is activated. + Title text to display above the Combo Box. + Sets which item is selected by default, and refers to the Id property of . If you do not provide this or null, the default selection will be empty (user sees nothing). + List of choices that will be available for user to select. + The current instance of + + + + Add an input option to the Toast. + + An instance of a class that impmement that will be used on the toast. + The current instance of + + + + Gets internal instance of . This is equivalent to the call to . + + + + + Initializes a new instance of the class. + + + + + Add custom time stamp on the toast to override the time display on the toast. + + Custom Time to be displayed on the toast + The current instance of + + + + Add a header to a toast. + + A developer-created identifier that uniquely identifies this header. If two notifications have the same header id, they will be displayed underneath the same header in Action Center. + A title for the header. + A developer-defined string of arguments that is returned to the app when the user clicks this header. + The current instance of + More info about toast header: https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/toast-headers + + + + Add info that can be used by the application when the app was activated/launched by the toast. + + Custom app-defined launch arguments to be passed along on toast activation + Set the activation type that will be used when the user click on this toast + The current instance of + + + + Sets the amount of time the Toast should display. You typically should use the + Scenario attribute instead, which impacts how long a Toast stays on screen. + + Duration of the toast + The current instance of + + + + Sets the scenario, to make the Toast behave like an alarm, reminder, or more. + + Scenario to be used for the toast's behavior + The current instance of + + + + Set custom audio to go along with the toast. + + Source to the media that will be played when the toast is pop + Indicating whether sound should repeat as long as the Toast is shown; false to play only once (default). + Indicating whether sound is muted; false to allow the Toast notification sound to play (default). + The current instance of + + + + Get the instance of that has been built by the builder with specified configuration so far. + + An instance of that can be used to create tile notification. + + + + Add an Attribution Text to be displayed on the toast. + + Text to be displayed as Attribution Text + The target locale of the XML payload, specified as a BCP-47 language tags such as "en-US" or "fr-FR". + The current instance of + + + + Override the app logo with custom image of choice that will be displayed on the toast. + + The URI of the image. Can be from your application package, application data, or the internet. Internet images must be less than 200 KB in size. + Specify how the image should be cropped. + A description of the image, for users of assistive technologies. + A value whether Windows is allowed to append a query string to the image URI supplied in the Tile notification. + The current instance of + + + + Add a hero image to the toast. + + The URI of the image. Can be from your application package, application data, or the internet. Internet images must be less than 200 KB in size. + A description of the image, for users of assistive technologies. + A value whether Windows is allowed to append a query string to the image URI supplied in the Tile notification. + The current instance of + + + + Add an image inline with other toast content. + + The URI of the image. Can be from your application package, application data, or the internet. Internet images must be less than 200 KB in size. + A description of the image, for users of assistive technologies. + A value whether Windows is allowed to append a query string to the image URI supplied in the Tile notification. + A value whether a margin is removed. images have an 8px margin around them. + the horizontal alignment of the image.This is only supported when inside an . + The current instance of + + + + Add a progress bar to the toast. + + Title of the progress bar. + Value of the progress bar. Default is 0 + Determine if the progress bar value should be indeterminate. Default to false. + An optional string to be displayed instead of the default percentage string. If this isn't provided, something like "70%" will be displayed. + A status string which is displayed underneath the progress bar. This string should reflect the status of the operation, like "Downloading..." or "Installing...". Default to empty. + The current instance of + More info at: https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/toast-progress-bar + + + + Add text to the toast. + + Custom text to display on the tile. + Style that controls the text's font size, weight, and opacity. + Indicating whether text wrapping is enabled. For Tiles, this is false by default. + The maximum number of lines the text element is allowed to display. For Tiles, this is infinity by default + The minimum number of lines the text element must display. + The horizontal alignment of the text + + The target locale of the XML payload, specified as a BCP-47 language tags such as "en-US" or "fr-FR". The locale specified here overrides any other specified locale, such as that in binding or visual. + + The current instance of + Throws when attempting to add/reserve more than 4 lines on a single toast. + Throws when value is larger than 2. + More info at: https://docs.microsoft.com/en-us/windows/uwp/design/shell/tiles-and-notifications/adaptive-interactive-toasts#text-elements + + + + Add a visual element to the toast. + + An instance of a class that implement . + The current instance of + The amount of time the Toast should display. @@ -1831,12 +2445,6 @@ The notification XML content as a string. - - - Retrieves the notification XML content as a WinRT XmlDocument, so that it can be used with a local Toast notification's constructor on either or . - - The notification XML content as a WinRT XmlDocument. - A Toast context menu item. diff --git a/Examples/Example09/Get-ChocoUpgradeNotification.ps1 b/Examples/Example09/Get-ChocoUpgradeNotification.ps1 index a96f580..127bb89 100644 --- a/Examples/Example09/Get-ChocoUpgradeNotification.ps1 +++ b/Examples/Example09/Get-ChocoUpgradeNotification.ps1 @@ -1,22 +1,29 @@ Import-Module BurntToast -if (!(Get-Command choco -ErrorAction SilentlyContinue)) { - New-BurntToastNotification -Text "choco not available!" - throw "choco.exe is required to run this script!" +# check if chocolatey is installed and the commands are executeable +if (!(Get-Command choco -ErrorAction SilentlyContinue)) { + New-BurntToastNotification -Text "choco not available!" + throw "choco.exe is required to run this script!" } +# get a list of chocolatey packages that can be updated $pkgs = choco outdated --ignore-pinned --ignore-unfound -r $total = $pkgs.Count -if ($total.Count -eq 0) { - New-BurntToastNotification -Text "all Chocolatey packages are up-to-date!" +if ($total -eq 0) { + New-BurntToastNotification -Text "All Chocolatey packages are up-to-date!" } else { - $pkgText = "" - $pkgs | % { $pkgText += "$($_ -split "\|" | Select-Object -First 1), " } - if ($pkgText.Length -gt 103) { - $pkgText = $pkgText.Substring(0, 100) - $pkgText += "..." - } - New-BurntToastNotification -Text "there are $total package updates available", $pkgText -} + $pkgText = "" + foreach ($package in $pkgs) + { + $pkgText += "$($package -split "\|" | Select-Object -First 1), " + } + + # cut the list of entries after 103, else the New-BurntToastNotification will throw an MethodInvocationException + if ($pkgText.Length -gt 103) { + $pkgText = $pkgText.Substring(0, 100) + $pkgText += "..." + } + New-BurntToastNotification -Text "There are $total package updates available:", $pkgText +} \ No newline at end of file diff --git a/Notes-0.7.2.txt b/Notes-0.7.2.txt new file mode 100644 index 0000000..bec5f4c --- /dev/null +++ b/Notes-0.7.2.txt @@ -0,0 +1,20 @@ +# Dev Notes + +## BurntToast 0.7.2 + + +## Pipeline + +Stages: + + PSAnalyzer + Compile + Test - Pester + Windows 2019 + Windows 2016 + Windows 10? 19/18* + Approval for release + Release + PowerShell Gallery + GitHub + Send Tweet - Customizable? diff --git a/README.md b/README.md index bd797f5..5cbe271 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ Download [BurntToast.zip](https://github.com/Windos/BurntToast/releases/download ![Example: API Call](/Examples/Example08/ApiToast.png) ### [Windows 10 Shoulder Tap Notification](/Examples/Example10) + ```powershell $Image = 'https://i.imgur.com/WKiNp5o.gif' $Contact = 'stormy@example.com' @@ -116,13 +117,33 @@ $Text = 'First Shoulder Tap', 'This is for the fallback toast.' New-BurntToastShoulderTap -Image $Image -Person $Contact -Text $Text ``` + ![Example: Shoulder Tap feature in Windows 10](/Examples/Example10/result.gif) ## Releases **Please note:** as of v0.5.0, BurntToast no longer works on Windows 8. -- [Bleeding Edge](https://github.com/Windos/BurntToast/archive/v0.7.1.zip) (Development/Raw Repo) +- [Bleeding Edge](https://github.com/Windos/BurntToast/archive/v0.7.2.zip) (Development/Raw Repo) + +- [v0.7.1](https://github.com/Windos/BurntToast/releases/download/v0.7.1/BurntToast.zip) + + - Update: Microsoft Community Toolkit to 6.0.0 + + - New: Support relative paths on images + + - New: "ScheduledToast" switch added to `Get-BTHistory` which returns scheduled or snoozed toast notifications + + - Enhancement: Libraries only loaded on module import if libraries not already loaded + + - Enhancement: Validate that image paths exist + + - Fix: Reverted to XML clean up to remove curly braces if databindings are not being used (Issue #72) + + - Known Issues: + + - Regardless of what snooze option is chosen, a snoozed toast will re-appear after 9 minutes + - Cause is unknown and isn''t unique to v0.7.1, will be investigated while working on v0.7.2 - [v0.7.0](https://github.com/Windos/BurntToast/releases/download/v0.7.0/BurntToast.zip) diff --git a/Tests/BurntToast.Tests.ps1 b/Tests/BurntToast.Tests.ps1 index a6e6034..005482b 100644 --- a/Tests/BurntToast.Tests.ps1 +++ b/Tests/BurntToast.Tests.ps1 @@ -17,11 +17,11 @@ Describe 'Get-BTHistory' { Mock Test-Path { $true } -ModuleName BurntToast -Verifiable -ParameterFilter { $Path -eq 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Notifications\Settings\{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe' } - + It 'should not throw' { { Get-BTHistory } | Should -Not -Throw } - + It 'tested the correct path' { Assert-VerifiableMock } @@ -256,10 +256,12 @@ Describe 'New-BTHeader' { } Describe 'New-BTImage' { + $ImagePath = Resolve-Path -Path $PSScriptRoot\..\BurntToast\Images\BurntToast.png + Context 'standard image' { Start-Transcript tmp.log try { - New-BTImage -Source $PSScriptRoot\..\Media\BurntToast.png -WhatIf + New-BTImage -Source $ImagePath -WhatIf } finally { Stop-Transcript @@ -267,14 +269,14 @@ Describe 'New-BTImage' { Remove-Item tmp.log } It 'has consitent WhatIf response' { - $Expected = "What if: Performing the operation ""New-BTImage"" on target ""returning: [AdaptiveImage]:Source=$PSScriptRoot\..\Media\BurntToast.png:AlternateText=:HintCrop=Default:HintRemoveMargin=False:HintAlign=Default:AddImageQuery=""." + $Expected = "What if: Performing the operation ""New-BTImage"" on target ""returning: [AdaptiveImage]:Source=$($ImagePath):AlternateText=:HintCrop=Default:HintRemoveMargin=False:HintAlign=Default:AddImageQuery=""." $Log | Should -Be $Expected } } Context 'application logo override' { Start-Transcript tmp.log try { - New-BTImage -Source $PSScriptRoot\..\Media\BurntToast.png -AppLogoOverride -Crop Circle -WhatIf + New-BTImage -Source $ImagePath -AppLogoOverride -Crop Circle -WhatIf } finally { Stop-Transcript @@ -282,14 +284,14 @@ Describe 'New-BTImage' { Remove-Item tmp.log } It 'has consitent WhatIf response' { - $Expected = "What if: Performing the operation ""New-BTImage"" on target ""returning: [ToastGenericAppLogo]:Source=$PSScriptRoot\..\Media\BurntToast.png:AlternateText=:HintCrop=Circle:AddImageQuery=""." + $Expected = "What if: Performing the operation ""New-BTImage"" on target ""returning: [ToastGenericAppLogo]:Source=$($ImagePath):AlternateText=:HintCrop=Circle:AddImageQuery=""." $Log | Should -Be $Expected } } Context 'hero image' { Start-Transcript tmp.log try { - New-BTImage -Source $PSScriptRoot\..\Media\BurntToast.png -HeroImage -WhatIf + New-BTImage -Source $ImagePath -HeroImage -WhatIf } finally { Stop-Transcript @@ -297,7 +299,7 @@ Describe 'New-BTImage' { Remove-Item tmp.log } It 'has consitent WhatIf response' { - $Expected = "What if: Performing the operation ""New-BTImage"" on target ""returning: [ToastGenericHeroImage]:Source=$PSScriptRoot\..\Media\BurntToast.png:AlternateText=:AddImageQuery=""." + $Expected = "What if: Performing the operation ""New-BTImage"" on target ""returning: [ToastGenericHeroImage]:Source=$($ImagePath):AlternateText=:AddImageQuery=""." $Log | Should -Be $Expected } } @@ -608,9 +610,11 @@ Describe 'New-BTVisual' { } Describe 'New-BTContent' { + $ImagePath = Resolve-Path -Path $PSScriptRoot\..\BurntToast\Images\BurntToast.png + $Text1 = New-BTText -Content 'This is a test' $Text2 = New-BTText -Content 'This more testing' - $Image2 = New-BTImage -Source $PSScriptRoot\..\Media\BurntToast.png -AppLogoOverride -Crop Circle + $Image2 = New-BTImage -Source $ImagePath -AppLogoOverride -Crop Circle $Binding1 = New-BTBinding -Children $Text1, $Text2 -AppLogoOverride $Image2 $Visual1 = New-BTVisual -BindingGeneric $Binding1 @@ -625,7 +629,7 @@ Describe 'New-BTContent' { Remove-Item tmp.log } It 'has consitent WhatIf response' { - $Expected = "What if: Performing the operation ""New-BTContent"" on target ""returning: [ToastContent] with XML: {This is a test}{This more testing}""." + $Expected = "What if: Performing the operation ""New-BTContent"" on target ""returning: [ToastContent] with XML: {This is a test}{This more testing}""." $Log | Should -Be $Expected } } @@ -640,7 +644,7 @@ Describe 'New-BTContent' { Remove-Item tmp.log } It 'has consitent WhatIf response' { - $Expected = "What if: Performing the operation ""New-BTContent"" on target ""returning: [ToastContent] with XML: {This is a test}{This more testing}""." + $Expected = "What if: Performing the operation ""New-BTContent"" on target ""returning: [ToastContent] with XML: {This is a test}{This more testing}""." $Log | Should -Be $Expected } } @@ -763,7 +767,7 @@ Describe 'New-BurntToastNotification' { Remove-Item tmp.log } It 'has consitent WhatIf response' { - $Expected = 'What if: Performing the operation "Submit-BTNotification" on target "submitting: [ToastNotification] with AppId {1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe, Id , Sequence Number 0 and XML: {Default Notification}via Pester".' + $Expected = 'What if: Performing the operation "Submit-BTNotification" on target "submitting: [ToastNotification] with AppId {1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe, Id , Sequence Number and XML: {Default Notification}via Pester".' $Log | Should -Be $Expected } }