Commit 83940968 by Sebastián Katzer

Added support for repeating notifications on Windows (WIP)

parent 1552ffc9
...@@ -347,14 +347,18 @@ exports.clone = function (obj) { ...@@ -347,14 +347,18 @@ exports.clone = function (obj) {
* @return [ LocalNotification.Options ] * @return [ LocalNotification.Options ]
*/ */
exports.parseOptions = function (obj) { exports.parseOptions = function (obj) {
var opts = new LocalNotification.Options(); var opts = new LocalNotification.Options(),
ignore = ['actions', 'trigger'];
for (var prop in opts) { for (var prop in opts) {
if (prop != 'actions' && obj[prop]) { if (!ignore.includes(prop) && obj[prop]) {
opts[prop] = obj[prop]; opts[prop] = obj[prop];
} }
} }
var trigger = exports.parseTrigger(obj);
opts.trigger = trigger;
var actions = exports.parseActions(obj); var actions = exports.parseActions(obj);
opts.actions = actions; opts.actions = actions;
...@@ -362,6 +366,28 @@ exports.parseOptions = function (obj) { ...@@ -362,6 +366,28 @@ exports.parseOptions = function (obj) {
}; };
/** /**
* Parse trigger spec into instance of prefered type.
*
* @param [ Object ] obj The notification options map.
*
* @return [ LocalNotification.Trigger ]
*/
exports.parseTrigger = function (obj) {
var trigger = new LocalNotification.Trigger(),
spec = obj.trigger, val;
if (!spec) return trigger;
for (var prop in trigger) {
val = spec[prop];
if (!val) continue;
trigger[prop] = prop == 'every' ? val.toString() : val;
}
return trigger;
};
/**
* Parse action specs into instances of prefered types. * Parse action specs into instances of prefered types.
* *
* @param [ Object ] obj The notification options map. * @param [ Object ] obj The notification options map.
......
...@@ -30,22 +30,27 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -30,22 +30,27 @@ namespace LocalNotificationProxy.LocalNotification
/// Initializes a new instance of the <see cref="Builder"/> class. /// Initializes a new instance of the <see cref="Builder"/> class.
/// </summary> /// </summary>
/// <param name="options">Notification properties to set.</param> /// <param name="options">Notification properties to set.</param>
internal Builder(Options options) public Builder(Options options)
{ {
this.Content = new Notification(options); this.Content = new Notification(options);
} }
/// <summary> /// <summary>
/// Gets content /// Gets the content.
/// </summary> /// </summary>
public Notification Content { get; private set; } public Notification Content { get; private set; }
/// <summary> /// <summary>
/// Gets options /// Gets the options.
/// </summary> /// </summary>
private Options Options { get => this.Content.Options; } private Options Options { get => this.Content.Options; }
/// <summary> /// <summary>
/// Gets the trigger.
/// </summary>
private Trigger Trigger { get => this.Options.Trigger; }
/// <summary>
/// Build a toast notification specified by the options. /// Build a toast notification specified by the options.
/// </summary> /// </summary>
/// <returns>A fully configured toast notification instance.</returns> /// <returns>A fully configured toast notification instance.</returns>
...@@ -60,6 +65,17 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -60,6 +65,17 @@ namespace LocalNotificationProxy.LocalNotification
} }
/// <summary> /// <summary>
/// If there is at least one more toast variant to build.
/// </summary>
/// <returns>True if there are more toasts to build.</returns>
public bool HasNext() => this.Trigger.Count > this.Trigger.Occurrence;
/// <summary>
/// Moves the flag to the next toast variant.
/// </summary>
public void MoveNext() => this.Trigger.Occurrence += this.HasNext() ? 1 : 0;
/// <summary>
/// Gets the initialize skeleton for a toast notification. /// Gets the initialize skeleton for a toast notification.
/// </summary> /// </summary>
/// <returns>Basic skeleton with sound, image and text.</returns> /// <returns>Basic skeleton with sound, image and text.</returns>
...@@ -137,21 +153,16 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -137,21 +153,16 @@ namespace LocalNotificationProxy.LocalNotification
{ {
var xml = toast.GetXml(); var xml = toast.GetXml();
var at = this.Content.Date; var at = this.Content.Date;
ScheduledToastNotification notification; var notification = new ScheduledToastNotification(xml, at);
if (this.Content.IsRepeating()) notification.Id = this.Content.Id;
{ notification.Tag = this.Options.Id.ToString();
var interval = this.Content.Interval;
notification = new ScheduledToastNotification(xml, at, interval, 5); if (this.Trigger.Occurrence > 1)
}
else
{ {
notification = new ScheduledToastNotification(xml, at); notification.Group = notification.Tag;
} }
notification.Id = this.Options.ID.ToString();
notification.Tag = notification.Id;
return notification; return notification;
} }
} }
......
...@@ -46,8 +46,15 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -46,8 +46,15 @@ namespace LocalNotificationProxy.LocalNotification
{ {
foreach (Options options in notifications) foreach (Options options in notifications)
{ {
var toast = new Builder(options).Build(); var builder = new Builder(options);
ToastNotifier.AddToSchedule(toast); ScheduledToastNotification toast;
do
{
toast = builder.Build();
ToastNotifier.AddToSchedule(toast);
builder.MoveNext();
} while (builder.HasNext());
} }
} }
...@@ -98,29 +105,29 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -98,29 +105,29 @@ namespace LocalNotificationProxy.LocalNotification
public List<Options> Cancel(int[] ids) public List<Options> Cancel(int[] ids)
{ {
var scheduled = ToastNotifier.GetScheduledToastNotifications(); var scheduled = ToastNotifier.GetScheduledToastNotifications();
var tags = new List<int>(ids); var toRemove = new List<int>(ids);
var toClear = new List<int>(ids);
var toasts = new List<Options>(); var toasts = new List<Options>();
foreach (var toast in scheduled) foreach (var toast in scheduled)
{ {
var id = int.Parse(toast.Tag); var id = int.Parse(toast.Tag);
if (tags.Contains(id)) if (toRemove.Contains(id))
{ {
tags.Remove(id); toClear.Remove(id);
toasts.Add(new Notification(toast).Options);
ToastNotifier.RemoveFromSchedule(toast); ToastNotifier.RemoveFromSchedule(toast);
}
if (tags.Count == 0) if (!this.IsPhantom(toast))
{ {
break; toasts.Add(new Notification(toast).Options);
}
} }
} }
if (tags.Count > 0) if (toClear.Count > 0)
{ {
toasts.AddRange(this.Clear(tags.ToArray())); toasts.AddRange(this.Clear(toClear.ToArray()));
} }
return toasts; return toasts;
...@@ -165,7 +172,10 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -165,7 +172,10 @@ namespace LocalNotificationProxy.LocalNotification
foreach (var toast in toasts) foreach (var toast in toasts)
{ {
ids.Add(int.Parse(toast.Tag)); if (!this.IsPhantom(toast))
{
ids.Add(int.Parse(toast.Tag));
}
} }
} }
...@@ -175,7 +185,10 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -175,7 +185,10 @@ namespace LocalNotificationProxy.LocalNotification
foreach (var toast in toasts) foreach (var toast in toasts)
{ {
ids.Add(int.Parse(toast.Tag)); if (!this.IsPhantom(toast))
{
ids.Add(int.Parse(toast.Tag));
}
} }
} }
...@@ -206,7 +219,10 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -206,7 +219,10 @@ namespace LocalNotificationProxy.LocalNotification
foreach (var toast in toasts) foreach (var toast in toasts)
{ {
notifications.Add(new Notification(toast)); if (!this.IsPhantom(toast))
{
notifications.Add(new Notification(toast));
}
} }
} }
...@@ -216,7 +232,10 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -216,7 +232,10 @@ namespace LocalNotificationProxy.LocalNotification
foreach (var toast in toasts) foreach (var toast in toasts)
{ {
notifications.Add(new Notification(toast)); if (!this.IsPhantom(toast))
{
notifications.Add(new Notification(toast));
}
} }
} }
...@@ -358,5 +377,25 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -358,5 +377,25 @@ namespace LocalNotificationProxy.LocalNotification
return Notification.Type.Unknown; return Notification.Type.Unknown;
} }
/// <summary>
/// If the specified toast is only for internal reason.
/// </summary>
/// <param name="toast">The toast notification to test for.</param>
/// <returns>True if its an internal ("phantom") one.</returns>
private bool IsPhantom(ToastNotification toast)
{
return toast.Group.Length > 0;
}
/// <summary>
/// If the specified toast is only for internal reason.
/// </summary>
/// <param name="toast">The toast notification to test for.</param>
/// <returns>True if its an internal ("phantom") one.</returns>
private bool IsPhantom(ScheduledToastNotification toast)
{
return toast.Group.Length > 0;
}
} }
} }
...@@ -49,9 +49,17 @@ ...@@ -49,9 +49,17 @@
All, Scheduled, Triggered, Unknown All, Scheduled, Triggered, Unknown
} }
/// <summary>
/// Gets the wrapped notification options.
/// </summary>
public Options Options { get; private set; } public Options Options { get; private set; }
/// <summary> /// <summary>
/// Gets the unique identifier for the toast.
/// </summary>
public string Id => $"{this.Options.Id}#{this.Options.Trigger.Occurrence}";
/// <summary>
/// Gets a ToastAudio object based on the specified sound uri. /// Gets a ToastAudio object based on the specified sound uri.
/// </summary> /// </summary>
public ToastAudio Sound public ToastAudio Sound
...@@ -260,9 +268,13 @@ ...@@ -260,9 +268,13 @@
{ {
get get
{ {
var date = DateTimeOffset.FromUnixTimeMilliseconds(this.Options.At * 1000).LocalDateTime; var trigger = this.Options.Trigger;
var time = trigger.At;
var date = DateTimeOffset.FromUnixTimeMilliseconds(time * 1000).LocalDateTime;
var minDate = DateTime.Now.AddSeconds(0.1); var minDate = DateTime.Now.AddSeconds(0.1);
date = date.AddTicks(this.Interval.Ticks * (trigger.Occurrence - 1));
return (date < minDate) ? minDate : date; return (date < minDate) ? minDate : date;
} }
} }
...@@ -274,7 +286,7 @@ ...@@ -274,7 +286,7 @@
{ {
get get
{ {
switch (this.Options.Every) switch (this.Options.Trigger.Every)
{ {
case "minute": case "minute":
return new TimeSpan(TimeSpan.TicksPerMinute); return new TimeSpan(TimeSpan.TicksPerMinute);
...@@ -296,16 +308,5 @@ ...@@ -296,16 +308,5 @@
{ {
return this.Options.GetXml(); return this.Options.GetXml();
} }
/// <summary>
/// If the notification shall be repeating.
/// </summary>
/// <returns>True if the Every property has some value.</returns>
public bool IsRepeating()
{
var every = this.Options.Every;
return every != null && every.Length > 0 && !every.Equals("0");
}
} }
} }
...@@ -33,7 +33,7 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -33,7 +33,7 @@ namespace LocalNotificationProxy.LocalNotification
/// <summary> /// <summary>
/// Gets or sets notification ID. /// Gets or sets notification ID.
/// </summary> /// </summary>
public int ID { get; set; } public int Id { get; set; }
/// <summary> /// <summary>
/// Gets or sets notification title. /// Gets or sets notification title.
...@@ -61,14 +61,9 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -61,14 +61,9 @@ namespace LocalNotificationProxy.LocalNotification
public string Image { get; set; } public string Image { get; set; }
/// <summary> /// <summary>
/// Gets or sets the notification fire date. /// Gets or sets the notification trigger.
/// </summary> /// </summary>
public long At { get; set; } public Trigger Trigger { get; set; }
/// <summary>
/// Gets or sets the notification repeat interval.
/// </summary>
public string Every { get; set; }
/// <summary> /// <summary>
/// Gets or sets the notification user data. /// Gets or sets the notification user data.
...@@ -98,9 +93,8 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -98,9 +93,8 @@ namespace LocalNotificationProxy.LocalNotification
var options = new Options(); var options = new Options();
var node = doc.DocumentElement; var node = doc.DocumentElement;
options.ID = int.Parse(node.GetAttribute("id")); options.Id = int.Parse(node.GetAttribute("id"));
options.Badge = int.Parse(node.GetAttribute("badge")); options.Badge = int.Parse(node.GetAttribute("badge"));
options.At = int.Parse(node.GetAttribute("at"));
if (node.GetAttributeNode("text") != null) if (node.GetAttributeNode("text") != null)
{ {
...@@ -122,11 +116,6 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -122,11 +116,6 @@ namespace LocalNotificationProxy.LocalNotification
options.Image = node.GetAttribute("image"); options.Image = node.GetAttribute("image");
} }
if (node.GetAttributeNode("every") != null)
{
options.Every = node.GetAttribute("every");
}
if (node.GetAttributeNode("data") != null) if (node.GetAttributeNode("data") != null)
{ {
options.Data = node.GetAttribute("data"); options.Data = node.GetAttribute("data");
...@@ -158,9 +147,8 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -158,9 +147,8 @@ namespace LocalNotificationProxy.LocalNotification
{ {
var node = new XmlDocument().CreateElement("options"); var node = new XmlDocument().CreateElement("options");
node.SetAttribute("id", this.ID.ToString()); node.SetAttribute("id", this.Id.ToString());
node.SetAttribute("badge", this.Badge.ToString()); node.SetAttribute("badge", this.Badge.ToString());
node.SetAttribute("at", this.At.ToString());
if (this.Title != null) if (this.Title != null)
{ {
...@@ -182,11 +170,6 @@ namespace LocalNotificationProxy.LocalNotification ...@@ -182,11 +170,6 @@ namespace LocalNotificationProxy.LocalNotification
node.SetAttribute("image", this.Image); node.SetAttribute("image", this.Image);
} }
if (this.Every != null)
{
node.SetAttribute("every", this.Every);
}
if (this.Data != null) if (this.Data != null)
{ {
node.SetAttribute("data", this.Data); node.SetAttribute("data", this.Data);
......
/*
* Apache 2.0 License
*
* Copyright (c) Sebastian Katzer 2017
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apache License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/Apache-2.0/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*/
namespace LocalNotificationProxy.LocalNotification
{
public sealed class Trigger
{
/// <summary>
/// Gets trigger type.
/// </summary>
public string Type { get; } = "calendar";
/// <summary>
/// Gets or sets trigger date.
/// </summary>
public long At { get; set; }
/// <summary>
/// Gets or sets trigger count.
/// </summary>
public int Count { get; set; } = 1;
/// <summary>
/// Gets trigger occurrence.
/// </summary>
public int Occurrence { get; internal set; } = 1;
/// <summary>
/// Gets or sets trigger interval.
/// </summary>
public string Every { get; set; }
}
}
...@@ -118,6 +118,7 @@ ...@@ -118,6 +118,7 @@
<Compile Include="LocalNotification\Input.cs" /> <Compile Include="LocalNotification\Input.cs" />
<Compile Include="LocalNotification\Manager.cs" /> <Compile Include="LocalNotification\Manager.cs" />
<Compile Include="LocalNotification\Options.cs" /> <Compile Include="LocalNotification\Options.cs" />
<Compile Include="LocalNotification\Trigger.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
......
{ {
"version": 2, "version": 3,
"targets": { "targets": {
"UAP,Version=v10.0": { "UAP,Version=v10.0.10240": {
"Microsoft.CSharp/4.0.1": { "Microsoft.CSharp/4.0.1": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
...@@ -2173,7 +2173,7 @@ ...@@ -2173,7 +2173,7 @@
} }
} }
}, },
"UAP,Version=v10.0/win10-arm": { "UAP,Version=v10.0.10240/win10-arm": {
"Microsoft.CSharp/4.0.1": { "Microsoft.CSharp/4.0.1": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
...@@ -4428,7 +4428,7 @@ ...@@ -4428,7 +4428,7 @@
} }
} }
}, },
"UAP,Version=v10.0/win10-arm-aot": { "UAP,Version=v10.0.10240/win10-arm-aot": {
"Microsoft.CSharp/4.0.1": { "Microsoft.CSharp/4.0.1": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
...@@ -5006,9 +5006,6 @@ ...@@ -5006,9 +5006,6 @@
}, },
"runtime.win10-arm-aot.runtime.native.System.IO.Compression/4.0.1": { "runtime.win10-arm-aot.runtime.native.System.IO.Compression/4.0.1": {
"type": "package", "type": "package",
"compile": {
"runtimes/win10-arm-aot/lib/netcore50/_._": {}
},
"runtime": { "runtime": {
"runtimes/win10-arm-aot/lib/netcore50/clrcompression.dll": {} "runtimes/win10-arm-aot/lib/netcore50/clrcompression.dll": {}
} }
...@@ -6722,7 +6719,7 @@ ...@@ -6722,7 +6719,7 @@
} }
} }
}, },
"UAP,Version=v10.0/win10-x64": { "UAP,Version=v10.0.10240/win10-x64": {
"Microsoft.CSharp/4.0.1": { "Microsoft.CSharp/4.0.1": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
...@@ -8986,7 +8983,7 @@ ...@@ -8986,7 +8983,7 @@
} }
} }
}, },
"UAP,Version=v10.0/win10-x64-aot": { "UAP,Version=v10.0.10240/win10-x64-aot": {
"Microsoft.CSharp/4.0.1": { "Microsoft.CSharp/4.0.1": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
...@@ -9567,9 +9564,6 @@ ...@@ -9567,9 +9564,6 @@
}, },
"runtime.win10-x64-aot.runtime.native.System.IO.Compression/4.0.1": { "runtime.win10-x64-aot.runtime.native.System.IO.Compression/4.0.1": {
"type": "package", "type": "package",
"compile": {
"runtimes/win10-x64-aot/lib/netcore50/_._": {}
},
"runtime": { "runtime": {
"runtimes/win10-x64-aot/lib/netcore50/clrcompression.dll": {} "runtimes/win10-x64-aot/lib/netcore50/clrcompression.dll": {}
} }
...@@ -11289,7 +11283,7 @@ ...@@ -11289,7 +11283,7 @@
} }
} }
}, },
"UAP,Version=v10.0/win10-x86": { "UAP,Version=v10.0.10240/win10-x86": {
"Microsoft.CSharp/4.0.1": { "Microsoft.CSharp/4.0.1": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
...@@ -13553,7 +13547,7 @@ ...@@ -13553,7 +13547,7 @@
} }
} }
}, },
"UAP,Version=v10.0/win10-x86-aot": { "UAP,Version=v10.0.10240/win10-x86-aot": {
"Microsoft.CSharp/4.0.1": { "Microsoft.CSharp/4.0.1": {
"type": "package", "type": "package",
"dependencies": { "dependencies": {
...@@ -14134,9 +14128,6 @@ ...@@ -14134,9 +14128,6 @@
}, },
"runtime.win10-x86-aot.runtime.native.System.IO.Compression/4.0.1": { "runtime.win10-x86-aot.runtime.native.System.IO.Compression/4.0.1": {
"type": "package", "type": "package",
"compile": {
"runtimes/win10-x86-aot/lib/netcore50/_._": {}
},
"runtime": { "runtime": {
"runtimes/win10-x86-aot/lib/netcore50/clrcompression.dll": {} "runtimes/win10-x86-aot/lib/netcore50/clrcompression.dll": {}
} }
...@@ -22044,7 +22035,7 @@ ...@@ -22044,7 +22035,7 @@
"Microsoft.NETCore.UniversalWindowsPlatform >= 5.2.3", "Microsoft.NETCore.UniversalWindowsPlatform >= 5.2.3",
"StyleCop.Analyzers >= 1.0.0" "StyleCop.Analyzers >= 1.0.0"
], ],
"UAP,Version=v10.0": [] "UAP,Version=v10.0.10240": []
}, },
"packageFolders": { "packageFolders": {
"C:\\Users\\katze\\.nuget\\packages\\": {} "C:\\Users\\katze\\.nuget\\packages\\": {}
...@@ -22055,14 +22046,24 @@ ...@@ -22055,14 +22046,24 @@
"projectName": "Microsoft.Toolkit.Uwp.Notifications.UWP", "projectName": "Microsoft.Toolkit.Uwp.Notifications.UWP",
"projectPath": "Z:\\Documents\\github\\cordova-plugin-local-notifications\\src\\windows\\Microsoft.Toolkit.Uwp.Notifications.UWP\\Microsoft.Toolkit.Uwp.Notifications.UWP.csproj", "projectPath": "Z:\\Documents\\github\\cordova-plugin-local-notifications\\src\\windows\\Microsoft.Toolkit.Uwp.Notifications.UWP\\Microsoft.Toolkit.Uwp.Notifications.UWP.csproj",
"projectJsonPath": "Z:\\Documents\\github\\cordova-plugin-local-notifications\\src\\windows\\Microsoft.Toolkit.Uwp.Notifications.UWP\\project.json", "projectJsonPath": "Z:\\Documents\\github\\cordova-plugin-local-notifications\\src\\windows\\Microsoft.Toolkit.Uwp.Notifications.UWP\\project.json",
"projectStyle": "ProjectJson" "packagesPath": "C:\\Users\\katze\\.nuget\\packages\\",
"outputPath": "Z:\\Documents\\github\\cordova-plugin-local-notifications\\src\\windows\\Microsoft.Toolkit.Uwp.Notifications.UWP\\obj\\",
"projectStyle": "ProjectJson",
"configFilePaths": [
"C:\\Users\\katze\\AppData\\Roaming\\NuGet\\NuGet.Config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
],
"sources": {
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
"https://api.nuget.org/v3/index.json": {}
}
}, },
"dependencies": { "dependencies": {
"Microsoft.NETCore.UniversalWindowsPlatform": "5.2.3", "Microsoft.NETCore.UniversalWindowsPlatform": "5.2.3",
"StyleCop.Analyzers": "1.0.0" "StyleCop.Analyzers": "1.0.0"
}, },
"frameworks": { "frameworks": {
"uap10.0": {} "uap10.0.10240": {}
}, },
"runtimes": { "runtimes": {
"win10-arm": { "win10-arm": {
......
...@@ -213,6 +213,14 @@ exports.convertTrigger = function (options) { ...@@ -213,6 +213,14 @@ exports.convertTrigger = function (options) {
trigger.every = options.every; trigger.every = options.every;
} }
if (!trigger.count && device.platform == 'windows') {
trigger.count = trigger.every ? 5 : 1;
}
if (trigger.every && device.platform == 'windows') {
trigger.every = trigger.every.toString();
}
if (!isCal) { if (!isCal) {
trigger.notifyOnEntry = !!trigger.notifyOnEntry; trigger.notifyOnEntry = !!trigger.notifyOnEntry;
trigger.notifyOnExit = trigger.notifyOnExit === true; trigger.notifyOnExit = trigger.notifyOnExit === true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment