Beispiel #1
0
        public void TimeZoneConverterTest(string input, string utcInput)
        {
            var utc = DateTime.Parse(utcInput).Normalize();

            Assert.That(TimeParser.TryParse(input, out var result), Is.True, $"{input} failed to parse\nSupported time zones: {string.Join(", ", TimeParser.GetSupportedTimeZoneAbbreviations())}");
            Assert.That(result, Is.EqualTo(utc));
            Assert.That(result.Kind, Is.EqualTo(DateTimeKind.Utc));
        }
Beispiel #2
0
        public void TimeZoneConverterTest(string input, string utcInput)
        {
            var utc = DateTime.Parse(utcInput).Normalize();

            Assert.That(TimeParser.TryParse(input, out var result), Is.True);
            Assert.That(result, Is.EqualTo(utc));
            Assert.That(result.Kind, Is.EqualTo(DateTimeKind.Utc));
        }
        public void TryParse_WhenNullString_ThenReturnsFalse()
        {
            var result = timeParser.TryParse(null, out timeModel);

            Assert.IsFalse(result);
        }
Beispiel #4
0
        private async Task <(bool success, DiscordMessage message)> EditEventPropertiesAsync(CommandContext ctx, EventSchedule evt, string eventName = null)
        {
            var interact     = ctx.Client.GetInteractivity();
            var abort        = DiscordEmoji.FromUnicode("🛑");
            var lastPage     = DiscordEmoji.FromUnicode("↪");
            var firstPage    = DiscordEmoji.FromUnicode("↩");
            var previousPage = DiscordEmoji.FromUnicode("⏪");
            var nextPage     = DiscordEmoji.FromUnicode("⏩");
            var trash        = DiscordEmoji.FromUnicode("🗑");
            var saveEdit     = DiscordEmoji.FromUnicode("💾");

            var            skipEventNameStep = !string.IsNullOrEmpty(eventName);
            DiscordMessage msg      = null;
            string         errorMsg = null;
            DiscordMessage txt;
            MessageReactionAddEventArgs emoji;

step1:
            // step 1: get the new start date
            var embed = FormatEvent(evt, errorMsg, 1).WithDescription($"Example: `{DateTime.UtcNow:yyyy-MM-dd HH:mm} [PST]`\nBy default all times use UTC, only limited number of time zones supported");

            msg = await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Please specify a new **start date and time**", embed : embed).ConfigureAwait(false);

            errorMsg          = null;
            (msg, txt, emoji) = await interact.WaitForMessageOrReactionAsync(msg, ctx.User, InteractTimeout, abort, lastPage, nextPage, (evt.IsComplete() ? saveEdit : null)).ConfigureAwait(false);

            if (emoji != null)
            {
                if (emoji.Emoji == abort)
                {
                    return(false, msg);
                }

                if (emoji.Emoji == saveEdit)
                {
                    return(true, msg);
                }

                if (emoji.Emoji == lastPage)
                {
                    goto step4;
                }
            }
            else if (txt != null)
            {
                if (!TimeParser.TryParse(txt.Content, out var newTime))
                {
                    errorMsg = $"Couldn't parse `{txt.Content}` as a start date and time";
                    goto step1;
                }

                var duration = evt.End - evt.Start;
                evt.Start = newTime.Ticks;
                evt.End   = evt.Start + duration;
                evt.Year  = newTime.Year;
            }
            else
            {
                return(false, msg);
            }

step2:
            // step 2: get the new duration
            embed = FormatEvent(evt, errorMsg, 2).WithDescription("Example: `2d 1h 15m`, or `2.1:00`");
            msg   = await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Please specify a new **event duration**", embed : embed.Build()).ConfigureAwait(false);

            errorMsg          = null;
            (msg, txt, emoji) = await interact.WaitForMessageOrReactionAsync(msg, ctx.User, InteractTimeout, abort, previousPage, nextPage, (evt.IsComplete() ? saveEdit : null)).ConfigureAwait(false);

            if (emoji != null)
            {
                if (emoji.Emoji == abort)
                {
                    return(false, msg);
                }

                if (emoji.Emoji == saveEdit)
                {
                    return(true, msg);
                }

                if (emoji.Emoji == previousPage)
                {
                    goto step1;
                }

                if (skipEventNameStep)
                {
                    goto step4;
                }
            }
            else if (txt != null)
            {
                var newLength = await TryParseTimeSpanAsync(ctx, txt.Content, false).ConfigureAwait(false);

                if (!newLength.HasValue)
                {
                    errorMsg = $"Couldn't parse `{txt.Content}` as a duration";
                    goto step2;
                }

                evt.End = (evt.Start.AsUtc() + newLength.Value).Ticks;
            }
            else
            {
                return(false, msg);
            }

step3:
            // step 3: get the new event name
            embed = FormatEvent(evt, errorMsg, 3);
            msg   = await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Please specify a new **event name**", embed : embed.Build()).ConfigureAwait(false);

            errorMsg          = null;
            (msg, txt, emoji) = await interact.WaitForMessageOrReactionAsync(msg, ctx.User, InteractTimeout, abort, previousPage, (string.IsNullOrEmpty(evt.EventName) ? null : trash), nextPage, (evt.IsComplete() ? saveEdit : null)).ConfigureAwait(false);

            if (emoji != null)
            {
                if (emoji.Emoji == abort)
                {
                    return(false, msg);
                }

                if (emoji.Emoji == saveEdit)
                {
                    return(true, msg);
                }

                if (emoji.Emoji == previousPage)
                {
                    goto step2;
                }

                if (emoji.Emoji == trash)
                {
                    evt.EventName = null;
                }
            }
            else if (txt != null)
            {
                evt.EventName = string.IsNullOrWhiteSpace(txt.Content) || txt.Content == "-" ? null : txt.Content;
            }
            else
            {
                return(false, msg);
            }

step4:
            // step 4: get the new schedule entry name
            embed = FormatEvent(evt, errorMsg, 4);
            msg   = await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Please specify a new **schedule entry title**", embed : embed.Build()).ConfigureAwait(false);

            errorMsg          = null;
            (msg, txt, emoji) = await interact.WaitForMessageOrReactionAsync(msg, ctx.User, InteractTimeout, abort, previousPage, firstPage, (evt.IsComplete() ? saveEdit : null)).ConfigureAwait(false);

            if (emoji != null)
            {
                if (emoji.Emoji == abort)
                {
                    return(false, msg);
                }

                if (emoji.Emoji == saveEdit)
                {
                    return(true, msg);
                }

                if (emoji.Emoji == firstPage)
                {
                    goto step1;
                }

                if (emoji.Emoji == previousPage)
                {
                    if (skipEventNameStep)
                    {
                        goto step2;
                    }
                    goto step3;
                }
            }
            else if (txt != null)
            {
                if (string.IsNullOrEmpty(txt.Content))
                {
                    errorMsg = "Entry title cannot be empty";
                    goto step4;
                }

                evt.Name = txt.Content;
            }
            else
            {
                return(false, msg);
            }

step5:
            // step 5: confirm
            if (errorMsg == null && !evt.IsComplete())
            {
                errorMsg = "Some required properties are not defined";
            }
            embed = FormatEvent(evt, errorMsg);
            msg   = await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Does this look good? (y/n)", embed : embed.Build()).ConfigureAwait(false);

            errorMsg          = null;
            (msg, txt, emoji) = await interact.WaitForMessageOrReactionAsync(msg, ctx.User, InteractTimeout, abort, previousPage, firstPage, (evt.IsComplete() ? saveEdit : null)).ConfigureAwait(false);

            if (emoji != null)
            {
                if (emoji.Emoji == abort)
                {
                    return(false, msg);
                }

                if (emoji.Emoji == saveEdit)
                {
                    return(true, msg);
                }

                if (emoji.Emoji == previousPage)
                {
                    goto step4;
                }

                if (emoji.Emoji == firstPage)
                {
                    goto step1;
                }
            }
            else if (!string.IsNullOrEmpty(txt?.Content))
            {
                if (!evt.IsComplete())
                {
                    goto step5;
                }

                switch (txt.Content.ToLowerInvariant())
                {
                case "yes":
                case "y":
                case "✅":
                case "☑":
                case "✔":
                case "👌":
                case "👍":
                    return(true, msg);

                case "no":
                case "n":
                case "❎":
                case "❌":
                case "👎":
                    return(false, msg);

                default:
                    errorMsg = "I don't know what you mean, so I'll just abort";
                    goto step5;
                }
            }
            else
            {
                return(false, msg);
            }

            return(false, msg);
        }