/// <summary> /// Updates the tile with the notification. If the tile payload has an error, the tile will not be updated. The first error, or multiple warnings, will be reported via the returned ParseResult. /// </summary> /// <param name="notification"></param> /// <returns></returns> public JsonParseTileResult UpdateFromJson(string content) { JsonParseTileResult result = JsonParser.ParseTile(content, _previewTile.CurrFeatureSet); if (result.IsOkForRender()) { _previewTile.Show(result.Content, true, result); } return(result); }
internal void Show(object tile, bool animate, JsonParseTileResult result = null) { // Ensure valid object passed in if (tile != null && !(tile is ITile) && !(tile is JsonTileContent)) { throw new InvalidOperationException("tile must be of type ITile or JsonTileContent"); } // If animations are disabled, set animate to false if (!IsAnimationEnabled) { animate = false; } // Store the current tile data, so that when the size changes, we can re-render using the data _notificationData = tile; // If we're already animating, we'll wait till current animation is done, and then render/animate the new content if (animate && _isAnimating) { _isWaitingToShow = true; return; } // Otherwise we'll render/animate now _isWaitingToShow = false; // Reset things that a previous notification might have changed, like DisplayName ResetDisplayProperties(); // If nothing to display, revert to default if (tile == null) { ShowDefault(animate); return; } // Find the first matching template for the current size, or if none, revert to default if (tile is ITile) { var xmlTile = tile as ITile; var binding = xmlTile.Visual.Bindings.FirstOrDefault(m => GetValidTemplateValues().Contains(m.Template)); if (binding == null) { ShowDefault(animate); return; } _hasNotificationForCurrentSize = true; // Custom display name from visual level if (xmlTile.Visual.DisplayName != null) { _customDisplayName = xmlTile.Visual.DisplayName; UpdateDisplayName(); } // Custom display name from binding level (which overrides visual) if (binding.DisplayName != null) { _customDisplayName = binding.DisplayName; UpdateDisplayName(); } // Update branding from notification _notificationBranding = xmlTile.Visual.Branding; // first attempt to use branding specified in the visual if (binding.Branding != null) { _notificationBranding = binding.Branding; // and then branding has a chance to override it } UpdateBranding(); // Generate the actual notification content PreviewTileNotification notificationContent = new PreviewTileNotification() { RequestedTheme = ElementTheme.Dark }; notificationContent.InitializeFromXml( tileSize: TileSize, //tilePixelSize: TilePixelSize, binding: binding, visualElements: VisualElements, isBrandingVisible: Branding.Visibility == Visibility.Visible); // And then show it ShowElement(notificationContent, animate); } #if CARDS else if (tile is JsonTileContent) { var jsonTile = tile as JsonTileContent; var binding = GetContentForCurrentSize(jsonTile); if (binding == null) { ShowDefault(animate); return; } _hasNotificationForCurrentSize = true; // Custom display name from binding level (which overrides visual) if (binding.DisplayName != null) { _customDisplayName = binding.DisplayName.Text; UpdateDisplayName(); } // Custom display name from visual level else if (jsonTile.Visual.DisplayName != null) { _customDisplayName = jsonTile.Visual.DisplayName.Text; UpdateDisplayName(); } // Update branding from notification _notificationBranding = ConvertJsonBrandingToXmlBranding(jsonTile.Visual.Branding); // first attempt to use branding specified in the visual if (binding.Branding != null) { _notificationBranding = ConvertJsonBrandingToXmlBranding(binding.Branding.Value); // and then branding has a chance to override it } UpdateBranding(); // Generate the actual notification content PreviewTileNotification notificationContent = new PreviewTileNotification() { RequestedTheme = ElementTheme.Dark }; notificationContent.Initialize( tileSize: TileSize, //tilePixelSize: TilePixelSize, content: binding, visualElements: VisualElements, isBrandingVisible: Branding.Visibility == Visibility.Visible, result: result); // And then show it ShowElement(notificationContent, animate); } #endif }
/// <summary> /// This should only be called once. For new tile notification content, create a new instance of this element. /// </summary> /// <param name="tileSize"></param> /// <param name="tilePixelSize"></param> /// <param name="visualElements"></param> /// <param name="isBrandingVisible"></param> /// <param name="binding"></param> public void Initialize(TileSize tileSize, PreviewTileVisualElements visualElements, bool isBrandingVisible, JsonTileCardContent content, JsonParseTileResult result) { if (content == null) { throw new ArgumentNullException(nameof(content)); } _tileSize = tileSize; // Set the background color TileContentContainer.Background = new SolidColorBrush(visualElements.BackgroundColor); UsingPeek = false; { // Calculate the tile margin Thickness margin = new Thickness(GetExternalMargin()); if (isBrandingVisible) { switch (tileSize) { case TileSize.Small: margin.Bottom = BRANDING_HEIGHT - 4; break; default: margin.Bottom = BRANDING_HEIGHT; break; } } // Render the adaptive if (content.Content != null && content.Content.Length > 0) { string finalCardJson; var adaptiveVisual = CardRenderer.RenderBody(content.Content, content.BaseUrl, null, null, out finalCardJson); if (adaptiveVisual != null && (adaptiveVisual as Panel).Children.Count > 0) { TileContent.Child = new Border() { Child = adaptiveVisual, Padding = new Thickness(margin.Left - 1, margin.Top - 4, margin.Right - 1, margin.Bottom) }; } else { result?.Errors.Add(new ParseError(ParseErrorType.ErrorButRenderAllowed, "Failed to render adaptive content.")); } } // Background image var backgroundImage = content.BackgroundImage; var peekImage = content.PeekContent?.BackgroundImage; // If we don't support both peek and background, then just peek is used //if (!binding.SupportedFeatures.BackgroundAndPeekImage && backgroundImage != null && peekImage != null) // backgroundImage = null; // Calculate overlays double backgroundOverlay = 0; if (backgroundImage != null) { if (backgroundImage.Overlay != null) { backgroundOverlay = backgroundImage.Overlay.Value; } else { //// If there's text on the tile, defaults to 20 //if (container.GetAllDescendants().OfType<AdaptiveTextField>().Any()) // backgroundOverlay = 20; //// Else defaults to no overlay //else // backgroundOverlay = 0; } } double peekOverlay = 0; if (peekImage != null) { if (peekImage.Overlay != null) { peekOverlay = peekImage.Overlay.Value; } } if (backgroundImage != null) { switch (backgroundImage.Style) { case JsonTileBackgroundImageStyle.Person: BackgroundImageContainer.Child = new CircleImage() { Source = ImageHelper.GetBitmap(backgroundImage.Url), Margin = tileSize == TileSize.Small ? new Thickness(4) : new Thickness(8), OverlayOpacity = backgroundOverlay / 100.0 }; break; default: BackgroundImageContainer.Child = new Image() { Source = ImageHelper.GetBitmap(backgroundImage.Url), Stretch = Stretch.UniformToFill }; BackgroundImageOverlay.Opacity = backgroundOverlay / 100.0; BackgroundImageOverlay.Visibility = Visibility.Visible; break; } } if (peekImage != null) { UsingPeek = true; switch (peekImage.Style) { case JsonTileBackgroundImageStyle.Person: PeekImageContainer.Child = new CircleImage() { Source = ImageHelper.GetBitmap(peekImage.Url), Margin = tileSize == TileSize.Small ? new Thickness(4) : new Thickness(8), OverlayOpacity = peekOverlay / 100.0 }; break; default: PeekImageContainer.Child = new Grid() { Children = { new Image() { Source = ImageHelper.GetBitmap(peekImage.Url), Stretch = Stretch.UniformToFill }, // Overlay new Rectangle() { Fill = new SolidColorBrush(Colors.Black), Opacity = peekOverlay / 100.0 } } }; break; } PeekRow.Height = new GridLength(1, GridUnitType.Star); } } }
/// <summary> /// This should only be called once. For new tile notification content, create a new instance of this element. /// </summary> /// <param name="tileSize"></param> /// <param name="tilePixelSize"></param> /// <param name="visualElements"></param> /// <param name="isBrandingVisible"></param> /// <param name="content"></param> /// <param name=""></param> /// <param name="binding"></param> public void Initialize(TileSize tileSize, PreviewTileVisualElements visualElements, bool isBrandingVisible, JsonTileCardContent content, JsonParseTileResult result) { if (content == null) { throw new ArgumentNullException(nameof(content)); } PreviewTileNotificationRaw raw = new PreviewTileNotificationRaw(); raw.Initialize(tileSize, visualElements, isBrandingVisible, content, result); if (raw.UsingPeek) { base.Content = new PeekDisplayerControl() { PreviewTileNotificationRaw = raw, PeekStartsOn = PeekContentDisplayed.Content } } ; else { base.Content = raw; } }