Skip to content

Instantly share code, notes, and snippets.

View worldbeater's full-sized avatar
☦️

Artyom V. Gorchakov worldbeater

☦️
View GitHub Profile
@worldbeater
worldbeater / Commands.fs
Last active March 17, 2019 20:34
Funogram Greetings Bot
module Program
open Funogram.Bot
open Funogram.Api
open ExtCore.Control
open System
/// Handler for '/hello'.
let onHello context =
maybe {
module Program
open System
open Funogram.Bot
/// Handles all Telegram events.
let update context =
context.Update.UpdateId
|> printfn "Received update: %i"
[Fact]
public void ShouldValidateFormAndSendFeedback()
{
// Create stubs for all dependencies and inject them.
var sender = Substitute.For<ISender>();
var clock = Substitute.For<IClock>();
var feedback = new FeedbackViewModel(sender, clock);
feedback.HasErrors.Should().BeTrue();
// Emulate user input.
<StackLayout Margin="20">
<Entry Text="{Binding Title, Mode=TwoWay}" Placeholder="Title"/>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding TitleLength, Mode=OneWay}"/>
<Label Text="letters used from"/>
<Label Text="{Binding TitleLengthMax, Mode=OneWay}"/>
</StackLayout>
<Entry Text="{Binding Message, Mode=TwoWay}" Placeholder="Message"/>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding MessageLength, Mode=OneWay}"/>
<StackPanel Width="300" VerticalAlignment="Center">
<TextBlock Text="Feedback" Style="{StaticResource TitleTextBlockStyle}" />
<TextBox Text="{x:Bind ViewModel.Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
MaxLength="{x:Bind ViewModel.TitleLengthMax}"
PlaceholderText="Title" />
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Margin="0 5">
<Run Text="{x:Bind ViewModel.TitleLength, Mode=OneWay}"/>
<Run Text="letters used from"/>
<Run Text="{x:Bind ViewModel.TitleLengthMax}"/>
</TextBlock>
public sealed class FeedbackViewModel : ReactiveObject, IActivatableViewModel
{
public ViewModelActivator Activator { get; } = new ViewModelActivator();
public ReactiveCommand<Unit, Unit> Submit { get; }
[Reactive] public bool HasErrors { get; private set; }
[Reactive] public string Elapsed { get; private set; } = string.Empty;
[Reactive] public string Title { get; set; } = string.Empty;
[Reactive] public int TitleLength { get; private set; }
[AddINotifyPropertyChangedInterface]
public class FodyReactiveViewModel
{
public ReactiveCommand<Unit, Unit> Clear { get; }
public string Greeting { get; private set; }
public string Name { get; set; } = string.Empty;
public FodyReactiveViewModel()
{
Clear = ReactiveCommand.Create(() => { Name = string.Empty; });
<StackPanel>
<!-- Note the ".Value" suffix added to "Name" and "Greeting" properties. -->
<TextBox Text="{Binding Name.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="{Binding Greeting.Value, Mode=OneWay}"/>
<Button Content="Clear" Command="{Binding Clear}"/>
</StackPanel>
public class ReactivePropertyViewModel
{
public ReadOnlyReactiveProperty<string> Greeting { get; }
public ReactiveProperty<string> Name { get; }
public ReactiveCommand Clear { get; }
public ReactivePropertyViewModel()
{
Clear = new ReactiveCommand();
Clear.Subscribe(() => Name.Value = string.Empty);
public class ReactiveViewModel : ReactiveObject
{
public ReactiveViewModel()
{
Clear = ReactiveCommand.Create(() => { Name = string.Empty; });
this.WhenAnyValue(x => x.Name)
.Select(name => $"Hello, {name}!")
.ToProperty(this, x => x.Greeting, out greeting);
}