CloudSharper 0.9.17.1 released Core team

It's release time again! CloudSharper 0.9.17.1 is out with a new feature: workspace-less fsi.

You can now run F# Interactive without having a workspace open, which is quite convenient for quick exploratory programming. Note that your fsi session will be reset as soon as you open a workspace.

You can also dock the interactive window to the right of the main tabset, making it easier to work interactively with a script or a documentation page.



This release also fixes a critical issue where the MSBuild agent on mono would throw an exception when trying to start a build.

As usual, here is the complete change log:
  • #467: Check subprotocol for GlobalCommands too
  • #474: Fix newlines in console output of foreign commands
  • #478: Show the CloudSharper version number on the dashboard
  • #490: Enable fsi in workspace-less scenarios
  • #499: Add "Find in solution explorer" and "Find in file explorer" to tab context menu
  • #503: Dialog layout on viewport resize
  • #504: Fix the new-ws command
  • #505: Fix styling of the FPish account association page
  • #507: Fix exception thrown by the MSBuild agent on mono when triggering a build
  • #509: Correctly connect to a local component running on another machine
  • #510: Allow docking the interactive window

Happy coding!

CloudSharper 0.9.17 released Core team

We just published a bugfix release to CloudSharper Local alpha. This bugfix slightly alters the communication protocol between the web application and the installed component, which is why the version number was bumped to 0.9.17 and upgrading is required.

Change log:
  • #492: On workspace open, only open README.*.md
  • #500: Silent error when deleting a directory
  • #501: Can't delete an open workspace
  • #502: NuGet reference versioning on adding a package

Happy coding!

CloudSharper 0.9.16.1 released Core team

We just released CloudSharper 0.9.16.1, a bugfix release fixing issues both in the GUI and the installed component. It is protocol-compatible, which means that you can still connect to CloudSharper using the 0.9.16.0 local component, but you will not benefit from some of the fixes listed below.

Here is the change log:
  • #479: Use better icons in the solution tree instead of folders.
  • #481: Close/warning on tabs that belong to deleted files.
  • #483: Layout issues in toolbar on Deploy and Split view.
  • #493: Isolate MSBuild in an AppDomain to prevent it from reusing the same WebSharper.Tasks.dll after switching workspaces.
  • #494: Ignore empty lines and comment on code folding.
  • #496: Add "Tools > Nuget sources" menu entry.
  • #497: Add "Tools > Keyboard shortcuts enabled" toggle menu entry.
  • #498: Add a better icon to close/minimize on fsi.

Happy coding!

WebSharper UI.Next Version 0.1.31.32 Community

WebSharper UI.Next Version 0.1.31.32 has been released on NuGet for your experimentation.

This version begins our push toward better handling of input. In particular, the latest version provides views of mouse and keyboard inputs, and combinators to allow snapshots of views and predicated view updates.

View Combinators


1
2
3
    static member SnapshotOn : 'B -> View<'A> -> View<'B> -> View<'B>
    static member UpdateWhile : 'A -> View<bool> -> View<'A> -> View<'A>

The new SnapshotOn combinator allows snapshots to be taken of a view whenever a 'trigger' view updates. This makes it useful for reacting to events, and has helped with our ongoing work to implement Piglets using UI.Next.

The UpdateWhile combinator provides a view which only updates whenever the value of a given predicate view is true.

While we don't provide first-class discrete event streams just yet, such combinators make it possible to emulate them.

You can find more information in the Documentation.

Input Views

The Input module provides views of the mouse and keyboard, such as keys and buttons pressed, and the mouse position. This will be expanded in the near future.

And the rest!


Additionally, there's now support for delayed animation, which is useful when developing visualisations with staggered transitions, and some bugfixes.

You can find samples of the Mouse and Keyboard views, as well as the snapshotting and predicated update functions on the UI.Next website. As ever, if you've been using UI.Next and have any comments, we'd love to hear them.

Bugfixes

  • Animation.Concat sometimes caused "undefined is not a function" errors within JavaScript
  • Computation Expression syntax for Views did not compile with WebSharper

CloudSharper 0.9.16 released Core team

CloudSharper 0.9.16 is out, and it's a big one! In addition to a new website design, we are releasing the first of many features to come allowing you to develop extensions to CloudSharper itself. In this first batch, we are focusing on custom editors for a designated file type.

Custom editors




Here is how CloudSharper customization works:
  • Every user has a special workspace, called Customizations Workspace, in which you can develop and store your CloudSharper extensions. To open it, click the "Open your customizations workspace" button on your dashboard.
  • Extensions take the form of assemblies located in designated subfolders of this workspace. For example, custom editors will be located in the "Editors" directory.
  • To make your first custom editor:
    • Create a project in your Customizations Workspace by selecting "CloudSharper Editor" in the New Project window. This project contains a simple editor for .foo files that simply displays a textarea and responds to Save requests from the UI.
    • Build the solution (Ctrl+B). The resulting assembly is automatically copied into the "Editors" folder.
    • Select "Reload local custom editors" from the Tools menu to activate the newly built editor in your current session. (existing editors are activated on startup)
    • Voilà! You can create a file with extension .foo to see your custom editor in action.

Note that if you upload your Customizations Workspace to the cloud, then your extensions will be activated on all machines you use!

Bugfixes


Here is the bugfix change log for CloudSharper 0.9.16:
  • #480: Closing tab doesn't check dirty status
  • #482: Deployed apps use the wrong domain in their URL
  • #485: Getting "The documentation page you requested does not exist" on page refresh
  • #487: Add a /doc url to link directly to a documentation page inside the IDE
  • #489: Syncing down meta workspace fails to create missing folders

Happy coding!

WebSharper UI Improvements Community

The WebSharper project has been making significant strides of late in the realm of building composable and reactive user interfaces, especially for the purpose of building SPA-style applications. You can find documentation and demos for WebSharper.UI.Next on its new site hosted on GitHub. Team members have also been blogging about how to build UIs with […]
>> Read the full article on wizardsofsmart.net

CloudSharper 0.9.15.2 released Core team

We just released CloudSharper 0.9.15.2, and as you probably noticed, there have been quite big visual changes with the 0.9.15 series as we switch to Dojo as our UI toolkit.





Change log


Besides this visual update, here are the recent changes:

  • #450: No more unneeded file change notifications when opening a file shortly after opening a workspace.
  • #461: Cancel code completion request when another is sent or the tab is switched.
  • #464: Report error when moving a file/folder failed.
  • #465: Implement file/directory copying. This can be done either using the cp command in the console, or using Ctrl+drag and drop in the file tree.
  • Initial login should now be faster.

Troubleshooting


  • If you experience a slow loading of the solution tree, be sure to dowload the latest installer.
  • If on startup, the local component shows the following error followed by a stack trace:
    1
    2
    3
    4
    5
    
    System.TypeInitializationException: The type initializer for
    '<StartupCode$CloudSharper-Backend-Local>.$LocalBackend' threw an exception.
    ---> System.IO.FileNotFoundException: Could not load file or assembly
    'IntelliFactory.IO, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
    or one of its dependencies. The system cannot find the file specified.
    Then you need to run the installer again and select "Repair"; things should run smoothly from there.

Happy coding!

Tachyus Core team

I am joining Tachyus F# team starting next week, and moving to San Mateo, CA. I am both excited and a little sad. During my time at IntelliFactory I learned pretty much all the skills I now have as a programmer. I met, worked with and learned from amazing hackers. It is time for me to move on, but IntelliFactory will always be a very special memory for me, and Budapest a special place. Thanks Adam Granicz, Diego Echeverri, Joel Bjornson, Loic Denuziere, Andras Janko, and many others for an[...]
>> Read the full article on t0yv0.blogspot.com

WebSharper UI.Next: Animating Single-Page Applications Community

Introduction

In my previous blog, I was asked about how easy it would be to tie in custom animations to the flowlet I described. In this post I hope to convince you that the answer to that is, well... Pretty easy!

If you haven't checked out Anton's blog on declarative animation in UI.Next, it provides a good introduction and is a bit more in-depth than this one. It'll also help to check out the blog on structuring single-page applications.

A brief introduction for those who haven't read up on UI.Next just yet: UI.Next is a dataflow-backed reactive DOM framework for WebSharper. By defining reactive variables (which are a bit like reference cells) and views on these (which allow you to 'peer into' the variable as it changes), it's possible to create DOM fragments which change with the variable.

This makes it really good for constructing single-page applications (SPAs), and we've cooked up some patterns and abstractions to make this feel pretty natural. Of course, with SPAs, some kind of animation between page transitions is quite nice -- and very doable. Of course, you could do this with CSS -- but I hope you'll agree that it's nicer and more powerful in F# :)

Fade Transitions for a Mini-Site

Earlier, I showed a pattern to create mini-sites consisting of multiple pages. To do this, we create an ADT to show the different types of pages you can have, and a rendering function for each. Once this is done, we get a view of the variable, map the rendering function onto it, then embed it into the document.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 // Here we define the minisite.
    let Main () =
        // We first create a variable to hold our current page.
        let m = Var.Create BobsleighHome

        // Here, we render the current page using a view of the current page variable
        let ctx = {Go = Var.Set m}
        View.FromVar m
        |> View.Map (fun pg ->
            match pg with
            | BobsleighHome -> HomePage ctx
            | BobsleighHistory -> History ctx
            | BobsleighGovernance -> Governance ctx
            | BobsleighTeam -> Team ctx)
        |> Doc.EmbedView // Finally, we can embed it to get a Doc

Okay, so what we want is for each page to fade out, and a new one to fade in. You can see this live here.

To do this, we'll take a look at a few things in the Animation module: if you're interested in looking into this a bit more deeply, then check out the API Reference.

The first thing to do is create an Anim, which specifies the basic properties about the animation:

  • Interpolation: How to calculate the intermediate values given the current time. This is parameterised over the type we want to interpolate -- we'll just use the inbuilt Double interpolation.
  • Easing : How to "distort" the interpolation, to give more interesting effects. We'll use the CubicInOut easing.
  • Time : The amount of time the animation will last.

Without further ado...

1
2
3
4
    let fadeTime = 300.0
    let Fade =
        Anim.Simple Interpolation.Double Easing.CubicInOut fadeTime

The next step is to define a Transition, which will trigger the animation. We want to fade in when the page gets shown (meaning we'll need an enter transition) and out when the page gets removed (meaning we'll need an exit transition). When this happens, we'll want to play the Fade animation, changing the opacity style from 0.0 to 1.0 for a fade in, and 1.0 to 0.0 for a fade out.

You'll notice that Trans.Enter and Trans.Exit take a function providing a value. This allows the transition to depend on a time-varying element -- in this case, since the transition will be the same each time, we don't need this. It comes in really handy for data-driven animations though, as you can see in the object constancy sample.

1
2
3
4
5
    let FadeTransition =
        Trans.Create Fade
        |> Trans.Enter (fun i -> Fade 0.0 1.0)
        |> Trans.Exit (fun i -> Fade 1.0 0.0)

The final step is to create an animation attribute, and attach it to the element we want to animate. This is done as follows, using the Attr.Animated and Attr.AnimatedStyle functions.

1
2
3
4
5
6
7
8
let MakePage var pg =
    Doc.Concat [
        NavBar var
        Div [Attr.AnimatedStyle "opacity" FadeTransition (View.Const 1.0) string] [
            pg
        ]
    ]

The function firstly takes the appropriate attribute we want to change as a result of the animation -- in the case of a fade, this will be opacity. We then specify our transition, and a constant view to be passed to the transition. Recall that since this animation doesn't depend on state, it's pretty much irrelevant in this case, but can come in handy at other points. The final argument is a function to change the double we're animating to a string, so that it can be displayed as an attribute.

All that's left now is to pipe the pages to the MakePage function, which also adds a navigation bar, and we're done!

1
2
3
4
5
6
7
8
9
10
11
12
13
let Main () =
    let m = Var.Create BobsleighHome
    let ctx = {Go = Var.Set m}
    View.FromVar m
    |> View.Map (fun pg ->
        match pg with
        | BobsleighHome -> HomePage ctx
        | BobsleighHistory -> History ctx
        | BobsleighGovernance -> Governance ctx
        | BobsleighTeam -> Team ctx
        |> MakePage m)
    |> Doc.EmbedView

Animating Flowlets

It's also very possible to combine animations. Flowlets allow us to easily construct "wizard-like" forms, where each page that has been shown may depend on previous pages. Now, a nice thing to do in such a case is to have a swipe-style animation that's triggered upon clicking the "next" button of the form, for example. You can see this example live here.

The first thing to do is to define a new swipe animation and transition, much as before: the code is pretty much the same, but we'll move 400px to the right, so we'll interpolate between 0.0 and 400.0 this time instead. The transition will also only be triggered when the node is removed, so we'll only need an exit transition this time.

1
2
3
4
5
6
7
8
9
10
// It's a similar story for swipes -- we're wanting to swipe 400px left.
let swipeTime = 300.0
let Swipe =
    Anim.Simple Interpolation.Double Easing.CubicInOut swipeTime

// We're only swiping out -- so we only specify an exit transition here
let SwipeTransition =
    Trans.Create Swipe
    |> Trans.Exit (fun i -> Swipe 0.0 400.0)

We'll use the same <div> trick as before to attach the animation to each flowlet page: since each animation is added as an attribute, it's possible to add the flow one in, too:

1
2
3
4
5
6
7
8
9
10
    let AnimateFlow pg =
        Div
            [
                Attr.Style "position" "relative"
                Attr.AnimatedStyle "opacity" FadeTransition (View.Const 1.0) string
                Attr.AnimatedStyle "left" SwipeTransition (View.Const 0.0) (fun x -> (string x) + "px")
            ]

            [ pg ]

And finally, all we need to do to animate a flowlet page is to pipe it to the AnimateFlow function we just defined:

1
2
3
4
5
6
7
8
9
10
let personFlowlet =
    Flow.Define (fun cont ->
        let rvName = Var.Create ""
        let rvAddress = Var.Create ""
        Form [cls "form-horizontal" ; "role" ==> "form"] [
            ...
        ]
        |> AnimateFlow
    )

...and we're done!

Finishing Up

Thanks for reading, and I hope I've shown how you can use the declarative animation functionality in UI.Next to animate single-page applications. Of course, I'm only scratching the surface here! Expect some more samples and posts in the coming weeks.

Any questions and comments are very welcome as ever!

UI.Next available Core team

UI.Next is available for experimentation as a public WebSharper.UI.Next NuGet package. You can build examples from source - just get WebSharper first. UI.Next addresses most shortcomings we felt WebSharper had for single-page JavaScript applications. The most interesting part is a dataflow model integrated with DOM for defining reactive UI, but we also provide support for client-side routing and animation. If you play with it, Simon and I will be very interested in your feedback.  Next week w[...]
>> Read the full article on t0yv0.blogspot.com