From: Shivam Varshney/Core S/W Group /SRI-Delhi/Engineer/Samsung Electronics Date: Wed, 28 Jun 2023 05:18:53 +0000 (+0530) Subject: Added Clearing Notifications Feature and Notification Added/Deleted Events. X-Git-Tag: accepted/tizen/unified/20230823.173931~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=709dfd8cf005dbce0e135fc28470abcf285bbf58;p=profile%2Fiot%2Fapps%2Fdotnet%2Fnotifications.git Added Clearing Notifications Feature and Notification Added/Deleted Events. Change-Id: Icd48156f7e9745276aa8260ec62253ff994105a6 Signed-off-by: Shivam Varshney/Core S/W Group /SRI-Delhi/Engineer/Samsung Electronics --- diff --git a/Notifications/Common/AppConstants.cs b/Notifications/Common/AppConstants.cs index a76428b..2fedf8f 100644 --- a/Notifications/Common/AppConstants.cs +++ b/Notifications/Common/AppConstants.cs @@ -9,13 +9,19 @@ namespace Notifications.Common public const string DarkPlatformThemeId = "org.tizen.default-dark-theme"; public static Size2D DefaultWindowSize = new Size2D(960, 540); + public static Size2D IconSize = new Size2D(48, 48); + public static Size2D SmallIconSize = new Size2D(32, 32); + public static Size2D TextButtonSize = new Size2D(150, 48); + public static Position2D DefaultWindowPosition = new Position2D(480, 170); + public const int BorderHeight = 52; + public const int HeaderHeight = 64; + public const int TitlePixelSize = 24; public static Vector4 BaseViewCornerRadius = new Vector4(24, 24, 24, 24); - public const int HeaderHeight = 64; + + public static Extents BaseViewPadding = new Extents(0, 0, 20, 20); public static Extents HeaderPadding = new Extents(16, 16, 8, 8); - public static Size2D IconSize = new Size2D(48, 48); - public const int TitlePixelSize = 24; } } diff --git a/Notifications/CustomBorder.cs b/Notifications/CustomBorder.cs index d03922a..bd7b293 100644 --- a/Notifications/CustomBorder.cs +++ b/Notifications/CustomBorder.cs @@ -19,7 +19,7 @@ namespace Notifications public override void CreateBorderView(View borderView) { this.borderView = borderView; - borderView.CornerRadius = new Vector4(0.03f, 0.03f, 0.03f, 0.03f); + borderView.CornerRadius = new Vector4(24, 24, 24, 24); borderView.CornerRadiusPolicy = VisualTransformPolicyType.Relative; borderView.BackgroundColor = new Color(1, 1, 1, 0.3f); } diff --git a/Notifications/Models/NotificationsModel.cs b/Notifications/Models/NotificationsModel.cs index cb05755..541d273 100644 --- a/Notifications/Models/NotificationsModel.cs +++ b/Notifications/Models/NotificationsModel.cs @@ -1,14 +1,25 @@ -using System.ComponentModel; +using System; +using System.ComponentModel; +using Tizen.Applications.NotificationEventListener; +using Tizen.NUI.Binding; +using Notifications.Common; namespace Notifications.Models { class NotificationsModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; - public NotificationsModel(string title, string content) + + private readonly string appId; + private readonly int uniqueNumber; + + public NotificationsModel(string appId, int uniqueNumber, string title, string content) { + this.appId = appId; + this.uniqueNumber = uniqueNumber; this.title = title ?? string.Empty; subTitle = content ?? string.Empty; + ClearNotificationCommand = new Command(OnNotificationCleared); } private void OnPropertyChanged(string propertyName) @@ -37,5 +48,28 @@ namespace Notifications.Models OnPropertyChanged("SubTitle"); } } + + private Command clearNotificationCommand; + public Command ClearNotificationCommand + { + get => clearNotificationCommand; + set + { + clearNotificationCommand = value; + OnPropertyChanged("ClearNotificationCommand"); + } + } + + private void OnNotificationCleared() + { + try + { + NotificationListenerManager.Delete(appId, uniqueNumber); + } + catch (Exception ex) + { + Tizen.Log.Error(AppConstants.LogTag, "Exception: " + ex.Message); + } + } } } diff --git a/Notifications/Notifications.cs b/Notifications/Notifications.cs index 70cedef..aabc806 100644 --- a/Notifications/Notifications.cs +++ b/Notifications/Notifications.cs @@ -2,6 +2,7 @@ using Tizen.NUI; using Notifications.Common; using Notifications.Views; +using Tizen.Applications; namespace Notifications { @@ -93,6 +94,12 @@ namespace Notifications } } + protected override void OnAppControlReceived(AppControlReceivedEventArgs e) + { + base.OnAppControlReceived(e); + Tizen.Log.Info(AppConstants.LogTag, "AppControl Received"); + } + protected override void OnTerminate() { Tizen.Log.Info(AppConstants.LogTag, "On App Terminate"); diff --git a/Notifications/ViewModels/NotificationsListViewModel.cs b/Notifications/ViewModels/NotificationsListViewModel.cs index 1d9aeaf..8b42222 100644 --- a/Notifications/ViewModels/NotificationsListViewModel.cs +++ b/Notifications/ViewModels/NotificationsListViewModel.cs @@ -13,7 +13,7 @@ namespace Notifications.ViewModels CreateData(); } - private void CreateData() + public void CreateData() { Clear(); try @@ -26,7 +26,7 @@ namespace Notifications.ViewModels foreach (var item in notificationsList) { Tizen.Log.Info(AppConstants.LogTag, "Notifications Title:" + item.Title); - Add(new NotificationsModel(item.Title, item.Content)); + Add(new NotificationsModel(item.AppID, item.UniqueNumber, item.Title, item.Content)); } } catch (Exception ex) diff --git a/Notifications/ViewModels/NotificationsViewModel.cs b/Notifications/ViewModels/NotificationsViewModel.cs index 75c4ffd..5d7e051 100644 --- a/Notifications/ViewModels/NotificationsViewModel.cs +++ b/Notifications/ViewModels/NotificationsViewModel.cs @@ -1,11 +1,103 @@ -namespace Notifications.ViewModels +using System; +using System.ComponentModel; +using Tizen.Applications.NotificationEventListener; +using Tizen.NUI; +using Tizen.NUI.Binding; + +namespace Notifications.ViewModels { - class NotificationsViewModel + class NotificationsViewModel : IDisposable, INotifyPropertyChanged { + public event PropertyChangedEventHandler PropertyChanged; + public NotificationsViewModel() { NotificationsListSource = new NotificationsListViewModel(); + IsNotificationsPresent = NotificationsListSource.Count > 0; + + BackCommand = new Command(OnBackPressed); + ClearAllNotificationsCommand = new Command(OnAllNotificationsCleared); + + NotificationListenerManager.Added += OnNotificationAdded; + NotificationListenerManager.Deleted += OnNotificationDeleted; + NotificationListenerManager.Updated += OnNotificationUpdated; } + public NotificationsListViewModel NotificationsListSource { get; set; } + + private bool isNotificationsPresent; + public bool IsNotificationsPresent + { + get => isNotificationsPresent; + set + { + isNotificationsPresent = value; + OnPropertyChanged("IsNotificationsPresent"); + } + } + + public void Dispose() + { + NotificationListenerManager.Added -= OnNotificationAdded; + NotificationListenerManager.Deleted -= OnNotificationDeleted; + NotificationListenerManager.Updated -= OnNotificationUpdated; + NotificationsListSource.Clear(); + NotificationsListSource = null; + } + + private void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + private void OnNotificationUpdated(object sender, NotificationEventArgs e) + { + NotificationsListSource.CreateData(); + IsNotificationsPresent = NotificationsListSource.Count > 0; + } + + private void OnNotificationDeleted(object sender, NotificationDeleteEventArgs e) + { + NotificationsListSource.CreateData(); + IsNotificationsPresent = NotificationsListSource.Count > 0; + } + + private void OnNotificationAdded(object sender, NotificationEventArgs e) + { + NotificationsListSource.CreateData(); + IsNotificationsPresent = NotificationsListSource.Count > 0; + } + + private Command backCommand; + public Command BackCommand + { + get => backCommand; + set + { + backCommand = value; + OnPropertyChanged("BackCommand"); + } + } + + private void OnBackPressed() + { + NUIApplication.Current.Exit(); + } + + private Command clearAllNotificationsCommand; + public Command ClearAllNotificationsCommand + { + get => clearAllNotificationsCommand; + set + { + clearAllNotificationsCommand = value; + OnPropertyChanged("ClearAllNotificationsCommand"); + } + } + + private void OnAllNotificationsCleared() + { + NotificationListenerManager.DeleteAll(); + } } } diff --git a/Notifications/Views/BaseView.cs b/Notifications/Views/BaseView.cs index b62c0a7..bb44e71 100644 --- a/Notifications/Views/BaseView.cs +++ b/Notifications/Views/BaseView.cs @@ -8,10 +8,28 @@ namespace Notifications.Views { class BaseView : View { + public static BindableProperty IsContentAvailableProperty = BindableProperty.Create(nameof(IsContentAvailable), typeof(bool), typeof(BaseView), false, propertyChanged: (bindable, oldValue, newValue) => + { + BaseView instance = bindable as BaseView; + if (instance == null) + { + return; + } + if (newValue != oldValue) + { + instance.isContentAvailable = (bool)newValue; + instance.UpdateContent(); + } + }, defaultValueCreator: (bindable) => (bindable as BaseView).isContentAvailable); + private View topView; private Button backButton; private TextLabel titleText; private CollectionView notificationsView; + private View bottomView; + private Button clearAllButton; + private TextLabel noNotificationsText; + public BaseView() : base() { Size2D = new Size2D(Window.Instance.WindowSize.Width, Window.Instance.WindowSize.Height); @@ -22,10 +40,11 @@ namespace Notifications.Views LinearOrientation = LinearLayout.Orientation.Vertical, HorizontalAlignment = HorizontalAlignment.Begin, VerticalAlignment = VerticalAlignment.Top, + Padding = AppConstants.BaseViewPadding, }; AddTopView(); - AddNotificationsView(); - + UpdateContent(); + this.SetBinding(IsContentAvailableProperty, "IsNotificationsPresent"); } private void AddTopView() @@ -54,6 +73,7 @@ namespace Notifications.Views backButton.Icon.Size2D = AppConstants.IconSize.SpToPx(); RelativeLayout.SetVerticalAlignment(backButton, RelativeLayout.Alignment.Center); RelativeLayout.SetHorizontalAlignment(backButton, RelativeLayout.Alignment.Start); + backButton.SetBinding(Control.CommandProperty, "BackCommand"); topView.Add(backButton); titleText = new TextLabel() @@ -70,30 +90,122 @@ namespace Notifications.Views topView.Add(titleText); } + private void UpdateContent() + { + RemoveContent(); + + if (IsContentAvailable == true) + { + AddNotificationsView(); + AddBottomView(); + } + else + { + AddNoNotificationsText(); + } + } + + private void RemoveContent() + { + Remove(noNotificationsText); + Remove(notificationsView); + Remove(bottomView); + } + private void AddNotificationsView() { - notificationsView = new CollectionView() + if (notificationsView == null) { - ItemsLayouter = new LinearLayouter(), - ItemTemplate = new DataTemplate(() => + notificationsView = new CollectionView() { - DefaultLinearItem item = new DefaultLinearItem(); - item.WidthSpecification = LayoutParamPolicies.MatchParent; - item.Label.SetBinding(TextLabel.TextProperty, "Title"); - item.Label.HorizontalAlignment = HorizontalAlignment.Begin; - item.Label.FontFamily = "BreezeSans"; - item.SubLabel.SetBinding(TextLabel.TextProperty, "SubTitle"); - item.SubLabel.HorizontalAlignment = HorizontalAlignment.Begin; - item.SubLabel.FontFamily = "BreezeSans"; - return item; - }), - ScrollingDirection = ScrollableBase.Direction.Vertical, - WidthSpecification = LayoutParamPolicies.MatchParent, - HeightSpecification = LayoutParamPolicies.MatchParent, - SelectionMode = ItemSelectionMode.Single, - }; - notificationsView.SetBinding(RecyclerView.ItemsSourceProperty, "NotificationsListSource"); + ItemsLayouter = new LinearLayouter(), + ItemTemplate = new DataTemplate(() => + { + DefaultLinearItem item = new DefaultLinearItem(); + item.WidthSpecification = LayoutParamPolicies.MatchParent; + item.Label.SetBinding(TextLabel.TextProperty, "Title"); + item.Label.HorizontalAlignment = HorizontalAlignment.Begin; + item.Label.FontFamily = "BreezeSans"; + item.SubLabel.SetBinding(TextLabel.TextProperty, "SubTitle"); + item.SubLabel.HorizontalAlignment = HorizontalAlignment.Begin; + item.SubLabel.FontFamily = "BreezeSans"; + item.Extra = new Button() + { + Size2D = AppConstants.SmallIconSize.SpToPx().SpToPx(), + IconURL = Resources.GetImagePath() + "/light/clear.png", + BackgroundColor = Color.Transparent, + }; + (item.Extra as Button).Icon.Size2D = AppConstants.SmallIconSize.SpToPx().SpToPx(); + item.Extra.SetBinding(Control.CommandProperty, "ClearNotificationCommand"); + return item; + }), + ScrollingDirection = ScrollableBase.Direction.Vertical, + WidthSpecification = LayoutParamPolicies.MatchParent, + HeightSpecification = LayoutParamPolicies.MatchParent, + SelectionMode = ItemSelectionMode.Single, + }; + notificationsView.SetBinding(RecyclerView.ItemsSourceProperty, "NotificationsListSource"); + } Add(notificationsView); } + + private void AddBottomView() + { + if (bottomView == null) + { + bottomView = new View() + { + WidthSpecification = LayoutParamPolicies.MatchParent, + HeightSpecification = AppConstants.HeaderHeight.SpToPx(), + Layout = new RelativeLayout() + { + Padding = AppConstants.HeaderPadding.SpToPx(), + }, + }; + } + if (clearAllButton == null) + { + clearAllButton = new Button() + { + Size2D = AppConstants.TextButtonSize.SpToPx(), + Text = "Clear All", + TextColor = new Color("#FF6200"), + FontFamily = "BreezeSans", + BackgroundColor = Color.Transparent, + TextAlignment = HorizontalAlignment.Center, + }; + RelativeLayout.SetVerticalAlignment(clearAllButton, RelativeLayout.Alignment.Center); + RelativeLayout.SetHorizontalAlignment(clearAllButton, RelativeLayout.Alignment.End); + clearAllButton.SetBinding(Control.CommandProperty, "ClearAllNotificationsCommand"); + bottomView.Add(clearAllButton); + } + Add(bottomView); + } + + private void AddNoNotificationsText() + { + if (noNotificationsText == null) + { + noNotificationsText = new TextLabel() + { + Text = "You don't have notifications", + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + FontFamily = "BreezeSans", + PixelSize = AppConstants.TitlePixelSize.SpToPx(), + TextColor = new Color("#090E21"), + WidthSpecification = LayoutParamPolicies.MatchParent, + HeightSpecification = LayoutParamPolicies.MatchParent, + }; + } + Add(noNotificationsText); + } + + private bool isContentAvailable; + public bool IsContentAvailable + { + get => (bool)GetValue(IsContentAvailableProperty); + set => SetValue(IsContentAvailableProperty, value); + } } } diff --git a/Notifications/res/images/light/clear.png b/Notifications/res/images/light/clear.png new file mode 100644 index 0000000..7240e82 Binary files /dev/null and b/Notifications/res/images/light/clear.png differ diff --git a/packaging/org.tizen.Notifications-1.0.0.tpk b/packaging/org.tizen.Notifications-1.0.0.tpk index 7507a3e..c58b8f2 100644 Binary files a/packaging/org.tizen.Notifications-1.0.0.tpk and b/packaging/org.tizen.Notifications-1.0.0.tpk differ