protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context) { ExtraCssFileUrlProperty.IsSet(this); writer.AddAttribute("class", "dotvvm-crystal-report-viewer-container"); writer.AddAttribute("report-page-url", WebUtility.HtmlEncode(ReportPageUrl)); writer.AddAttribute("display-toolbar", DisplayToolbar.ToString()); writer.AddAttribute("display-page", DisplayPage.ToString()); writer.AddAttribute("display-statusbar", DisplayStatusbar.ToString()); writer.AddAttribute("best-fit-page", BestFitPage.ToString()); if (ExtraCssFileUrlProperty.IsSet(this)) { writer.AddAttribute("extra-css-file-url", WebUtility.HtmlEncode(ExtraCssFileUrl)); } if (WidthProperty.IsSet(this)) { writer.AddAttribute("width", Width); } if (HeightProperty.IsSet(this)) { writer.AddAttribute("height", Height); } writer.AddKnockoutDataBind("crystalReportFile", this, CrystalReportFileProperty, () => { writer.AddKnockoutDataBind("crystalReportFile", KnockoutHelper.MakeStringLiteral(CrystalReportFile)); }); base.AddAttributesToRender(writer, context); }
public void IssueNotificationAsync(string title, string message, string id, Protocol protocol, bool alertUser, DisplayPage displayPage, DateTime triggerDateTime, NSMutableDictionary info, Action <UNNotificationRequest> requestCreated = null) { if (info == null) { info = new NSMutableDictionary(); } info.SetValueForKey(new NSString(id), new NSString(NOTIFICATION_ID_KEY)); info.SetValueForKey(new NSString(displayPage.ToString()), new NSString(DISPLAY_PAGE_KEY)); UNMutableNotificationContent content = new UNMutableNotificationContent { UserInfo = info }; // the following properties are allowed to be null, but they cannot be set to null. if (!string.IsNullOrWhiteSpace(title)) { content.Title = title; } if (!string.IsNullOrWhiteSpace(message)) { content.Body = message; } // protocol might be null when issuing the pending surveys notification. if (alertUser && (protocol == null || !protocol.TimeIsWithinAlertExclusionWindow(triggerDateTime.TimeOfDay))) { content.Sound = UNNotificationSound.Default; } IssueNotificationAsync(id, content, triggerDateTime, requestCreated); }
public void IssueNotificationAsync(string title, string message, string id, bool playSound, DisplayPage displayPage, int delayMS, NSMutableDictionary info, Action <UNNotificationRequest> requestCreated = null) { if (info == null) { info = new NSMutableDictionary(); } info.SetValueForKey(new NSString(id), new NSString(NOTIFICATION_ID_KEY)); info.SetValueForKey(new NSString(displayPage.ToString()), new NSString(DISPLAY_PAGE_KEY)); UNMutableNotificationContent content = new UNMutableNotificationContent { UserInfo = info }; // the following properties are allowed to be null, but they cannot be set to null. if (!string.IsNullOrWhiteSpace(title)) { content.Title = title; } if (!string.IsNullOrWhiteSpace(message)) { content.Body = message; } if (playSound) { content.Sound = UNNotificationSound.Default; } IssueNotificationAsync(id, content, delayMS, requestCreated); }
private PendingIntent CreateCallbackPendingIntent(string callbackId, bool repeating, int repeatDelayMS, bool repeatLag) { DisplayPage displayPage = GetCallbackDisplayPage(callbackId); Intent callbackIntent = new Intent(_service, typeof(AndroidSensusService)); callbackIntent.PutExtra(Notifier.NOTIFICATION_ID_KEY, callbackId); callbackIntent.PutExtra(Notifier.DISPLAY_PAGE_KEY, displayPage.ToString()); callbackIntent.PutExtra(SENSUS_CALLBACK_KEY, true); callbackIntent.PutExtra(SENSUS_CALLBACK_REPEATING_KEY, repeating); callbackIntent.PutExtra(SENSUS_CALLBACK_REPEAT_DELAY_KEY, repeatDelayMS); callbackIntent.PutExtra(SENSUS_CALLBACK_REPEAT_LAG_KEY, repeatLag); return(CreateCallbackPendingIntent(callbackIntent)); }
/// <summary> /// Issues the notification. /// </summary> /// <param name="title">Title.</param> /// <param name="message">Message.</param> /// <param name="id">Identifier of notification.</param> /// <param name="protocolId">Protocol identifier to check for alert exclusion time windows.</param> /// <param name="alertUser">If set to <c>true</c> alert user.</param> /// <param name="displayPage">Display page.</param> public override void IssueNotificationAsync(string title, string message, string id, string protocolId, bool alertUser, DisplayPage displayPage) { if (_notificationManager == null) { return; } Task.Run(() => { if (message == null) { CancelNotification(id); } else { Intent notificationIntent = new Intent(_service, typeof(AndroidSensusService)); notificationIntent.PutExtra(DISPLAY_PAGE_KEY, displayPage.ToString()); PendingIntent notificationPendingIntent = PendingIntent.GetService(_service, 0, notificationIntent, PendingIntentFlags.UpdateCurrent); SensusNotificationChannel notificationChannel = SensusNotificationChannel.Default; if (displayPage == DisplayPage.PendingSurveys) { notificationChannel = SensusNotificationChannel.Survey; } // reset channel to silent if we're not alerting or if we're in an exclusion window if (!alertUser || Protocol.TimeIsWithinAlertExclusionWindow(protocolId, DateTime.Now.TimeOfDay)) { notificationChannel = SensusNotificationChannel.Silent; } Notification.Builder notificationBuilder = CreateNotificationBuilder(_service, notificationChannel) .SetContentTitle(title) .SetContentText(message) .SetSmallIcon(Resource.Drawable.ic_launcher) .SetContentIntent(notificationPendingIntent) .SetAutoCancel(true) .SetOngoing(false); _notificationManager.Notify(id, 0, notificationBuilder.Build()); } }); }
public void IssueNotificationAsync(string title, string message, string id, string protocolId, bool alertUser, DisplayPage displayPage, TimeSpan delay, NSMutableDictionary notificationInfo, Action <UILocalNotification> notificationCreated = null) { SensusContext.Current.MainThreadSynchronizer.ExecuteThreadSafe(() => { CancelNotification(id); if (notificationInfo == null) { notificationInfo = new NSMutableDictionary(); } notificationInfo.SetValueForKey(new NSString(id), new NSString(NOTIFICATION_ID_KEY)); notificationInfo.SetValueForKey(new NSString(displayPage.ToString()), new NSString(DISPLAY_PAGE_KEY)); DateTime fireDateTime = DateTime.Now + delay; // all properties below were introduced in iOS 8.0. we currently target 8.0 and above, so these should be safe to set. UILocalNotification notification = new UILocalNotification { AlertBody = message, TimeZone = null, // null for UTC interpretation of FireDate FireDate = fireDateTime.ToUniversalTime().ToNSDate(), UserInfo = notificationInfo }; // also introduced in 8.0 if (alertUser && !Protocol.TimeIsWithinAlertExclusionWindow(protocolId, fireDateTime.TimeOfDay)) { notification.SoundName = UILocalNotification.DefaultSoundName; } // introduced in iOS 8.2: https://developer.apple.com/reference/uikit/uilocalnotification/1616647-alerttitle if (UIDevice.CurrentDevice.CheckSystemVersion(8, 2) && !string.IsNullOrWhiteSpace(title)) { notification.AlertTitle = title; } notificationCreated?.Invoke(notification); IssueNotificationAsync(notification); }); }
/// <summary> /// Issues the notification. /// </summary> /// <param name="title">Title.</param> /// <param name="message">Message.</param> /// <param name="id">Identifier of notification.</param> /// <param name="protocolId">Protocol identifier to check for alert exclusion time windows.</param> /// <param name="alertUser">If set to <c>true</c> alert user.</param> /// <param name="displayPage">Display page.</param> public override void IssueNotificationAsync(string title, string message, string id, string protocolId, bool alertUser, DisplayPage displayPage) { if (_notificationManager == null) { return; } Task.Run(() => { if (message == null) { CancelNotification(id); } else { Intent notificationIntent = new Intent(_service, typeof(AndroidSensusService)); notificationIntent.PutExtra(DISPLAY_PAGE_KEY, displayPage.ToString()); PendingIntent notificationPendingIntent = PendingIntent.GetService(_service, 0, notificationIntent, PendingIntentFlags.UpdateCurrent); Notification.Builder notificationBuilder = new Notification.Builder(_service) .SetContentTitle(title) .SetContentText(message) .SetSmallIcon(Resource.Drawable.ic_launcher) .SetContentIntent(notificationPendingIntent) .SetAutoCancel(true) .SetOngoing(false); if (alertUser && !Protocol.TimeIsWithinAlertExclusionWindow(protocolId, DateTime.Now.TimeOfDay)) { notificationBuilder.SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification)); notificationBuilder.SetVibrate(new long[] { 0, 250, 50, 250 }); } _notificationManager.Notify(id, 0, notificationBuilder.Build()); } }); }
public void IssueNotificationAsync(string title, string message, string id, string protocolId, bool alertUser, DisplayPage displayPage, TimeSpan delay, NSMutableDictionary info, Action <UNNotificationRequest> requestCreated = null) { if (info == null) { info = new NSMutableDictionary(); } info.SetValueForKey(new NSString(id), new NSString(NOTIFICATION_ID_KEY)); info.SetValueForKey(new NSString(displayPage.ToString()), new NSString(DISPLAY_PAGE_KEY)); UNMutableNotificationContent content = new UNMutableNotificationContent { UserInfo = info }; // the following properties are allowed to be null, but they cannot be set to null. if (!string.IsNullOrWhiteSpace(title)) { content.Title = title; } if (!string.IsNullOrWhiteSpace(message)) { content.Body = message; } // the following calculation isn't perfect because we use DateTime.Now and then use it again in the subsequent call to IssueNotificationAsync. // these two values will be slightly different due to execution time, but the risk is small: the user might hear or not hear the notification // when it comes through, and it's very unlikely that the result will be incorrect. if (alertUser && !Protocol.TimeIsWithinAlertExclusionWindow(protocolId, (DateTime.Now + delay).TimeOfDay)) { content.Sound = UNNotificationSound.Default; } IssueNotificationAsync(id, content, delay, requestCreated); }
public NSMutableDictionary GetCallbackInfo(string callbackId, bool repeating, TimeSpan repeatDelay, bool repeatLag, DisplayPage displayPage) { // we've seen cases where the UserInfo dictionary cannot be serialized because one of its values is null. if this happens, the // callback won't be serviced, and things won't return to normal until Sensus is activated by the user and the callbacks are // refreshed. don't create the UserInfo dictionary if we've got null values. // // see: https://insights.xamarin.com/app/Sensus-Production/issues/64 // if (callbackId == null) { return(null); } List <object> keyValuePairs = new object[] { iOSNotifier.NOTIFICATION_ID_KEY, callbackId, Notifier.DISPLAY_PAGE_KEY, displayPage.ToString(), SENSUS_CALLBACK_REPEATING_KEY, repeating, SENSUS_CALLBACK_REPEAT_DELAY_KEY, repeatDelay.Ticks.ToString(), SENSUS_CALLBACK_REPEAT_LAG_KEY, repeatLag }.ToList(); return(new NSMutableDictionary(new NSDictionary(SENSUS_CALLBACK_KEY, true, keyValuePairs.ToArray()))); }