fabulous-dev / fabulous Goto Github PK
View Code? Open in Web Editor NEWDeclarative UI framework for cross-platform mobile & desktop apps, using MVU and F# functional programming
Home Page: https://fabulous.dev
License: Apache License 2.0
Declarative UI framework for cross-platform mobile & desktop apps, using MVU and F# functional programming
Home Page: https://fabulous.dev
License: Apache License 2.0
This should have a few advantages :-
~/.nuget/packages/Elmish.XamarinForms.LiveUpdate/0.14.2/tools/fscd.exe
The state record:
type Model =
{ TempF: double
TempC: double
Error: string option }
works fine for small pages and little components but when your page becomes large (for example when you have a form) having multiple error flags clutters the model and forces the developer to keep the fields values in-sync with their error flags. A better solution in my experience is to encode the value in a single explicit type:
type Temperature =
| Value of double
| ValidationError of string
type State =
{ TempF : Temperature
TempC : Temperature }
this way you can't possibly use the data from Temperature
if there was a parse/validation error
First of all, I want to say thank you @dsyme for such an amazing project!
Here is a question:
How can I use the SearchBar control? I found that there are no arguments in the searchComannd, and textChanged event is not implemented. How can use value of the searchBar then?
The Readme file says to create F# Forms application on VS Code
Could you elaborate this step? Is it possible to use VS Code at the moment?
Feedback from @migueldeicaza and others:
rename
Xaml.FooBar
to something else, e.g.UI.FooBar
orXF.FooBar
orForms.FooBar
Of these I think I would prefer XF.Label
, XF.Button
etc., but please chime in if you have a preference.
#if directives are ignored in the code created by the template. They need to be marked with a flag to say they should be emitted as is.
Just to report that I was able to make it work with https://github.com/aosoft/Xamarin.Forms.WinForms, a WinForms implementation of Xamarin.Forms!
It already works with the Nuget release, but I have made 2 PRs, 1 accepted, to the repo, so I recompile, and that is the gist showing the necessary to make it work:
https://gist.github.com/gibranrosa/6bc75fdc0ccb787f51fa726a64246047
One note: There is some Big file names in the library, so I could compile it only putting it in the root dir.
Using Program.withConsoleTrace
logs out the update messages and models to the console.
It would be nice if there was a withAppCenterTrace
method to log to AppCenter events as well.
The linker can/should automatically remove any .NET manifest assembly resources named FSharpSignatureData.* and FSharpOptimizationData.* during linking.
These are only ever needed for F# compilation which doesn't happen on-device and given the aims of the linker it is reasonable to assume this data is unreachable.
My understanding is that removing these would trim about 1.5MB off the size of all applications using FSharp.Core.dll, and about 3MB off all applications using Elmish.XamarinForms.dll.
As per the title - create a Full-Elmish app with multiple pages and run it on Android. The navigation bar is way too big...
For the "half elmish" approach of having static XAML files, but still using an elmish model, it would be very compelling to have Xamarin Live Reload support.
At the moment if I add the live reload package to this project, the ResolveAssembly
task in Xamarin.Android.Common.targets
fails with:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(1590,2): error : Exception while loading assemblies: System.IO.FileNotFoundException: Could not load assembly 'Xamarin.Live.Reload, Version=0.3.27.0, Culture=neutral, PublicKeyToken='. Perhaps it doesn't exist in the Mono for Android profile?
File name: 'Xamarin.Live.Reload.dll'
I think I can work around this, but then I spotted some targets in the live reload package that looks like it will only work in C# & VB projects, it tries to inject some attributes into the assembly, however I don't think F# uses the same targets (yet? see here: dotnet/fsharp#3113).
I might have a dabble with this later this week to see what I can get working.
If you're looking to contribute, the work items are documented in the "Roadmap"
There are a couple of bugs in the LiveUpdate interpreter
TryGetValue
callsfix in progress
The package dependencies for Elmish.XamarinForms
and so on are missing, we need to fix this.
This is because we are using a mix of dotnet CLI and Paket commands
@jimbobbennett mentioned that modal pages are not fully available in the framework and we need to give examples of these
I'm trying understand how a multi page application is going to look.
Logically, a multi page application should be split on files where each file represents a page or a subset of the application. However, in the AllControls
sample I've seen that the navigation stack and all pages are maintained in the same file.
It makes me wonder, how will a complex application will look like? Will it have only one file with init
, update
and view
and ViewElements will be split on modules, or it will have a few modules with init
, update
and view
?
The AllControls sample works fairly well but there are some issues (this is testing with iPhone X)
The samples need to use the iOS safe area settings for most pages - there are controls overlapping with the thing at the top of the iOS screen
The TabbedPage sample is showing more tabs than fit on the bottom of the normal iPhone, only 4-5 fit, better to split to multiple samples
The ListView sample uses some formatted text which doesn't look very nice
The fact the Slider is on the Carousel page makes it really hard to move the slider as the page takes the events more often than not
The layout on the NavigationPage sample doesn't use the appropriate SafeArea at the bottom
The master detail page looks and feels very different to the Android one. This is maybe OK and expected, but could be made to look nicer
We need a way to specify canExecute
, e.g.
Xaml.Button(text="Reset", ..., command= (fun () -> dispatch Reset), canExecute = false)
See discussion here: elmish/Elmish.WPF#33. Basically, if your Xamarin Xaml wires up an event then you end up dropping out of the Elmish programming model, which feels wrong
Conversation with Xamarin.Forms archtiects:
I am wondering if it would make sense to allow
ItemSelected=“{Binding [ItemSelected]}”
where the view model property returns a delegate of an appropriate type. XF would store this as if it were a one-way property binding, and invoke the delegate as needed when firing the event. That seems to make sense, at least in theory.
The readme.md refers to downloading Elmish.XamarinForms from nuget, but there does not appear to be any package of that name on the public nuget feed
Does this refer to a separate nuget feed?
From slack discussion with @charlesroddie and @mydogisbox
The pre-release of Xamarin.WPF is just out. It seems to be usable with glitches here or there as you would expect. It has all the stock controls in Xamarin.Forms. There is almost no support in 3rd party controls at the moment. (edited)
Let's add a sample under https://github.com/fsprojects/Elmish.XamarinForms/tree/master/Samples/CounterApp
I'd like to also see WinForms and Mac nodes under there.
Here's a sample from @mydogisbox:
type CounterApp () as app =
inherit Application ()
let program = Program.mkProgram App.init App.update App.view
let runner =
program
|> Program.withConsoleTrace
|> Program.withDynamicView app
|> Program.run
type MainWindow() as this =
inherit FormsApplicationPage()
do Forms.Init()
do this.LoadApplication(new CounterApp())
[<STAThread>]
[<EntryPoint>]
do (new System.Windows.Application()).Run(MainWindow()) |> ignore
Add simple docs on making web requests akin to this:
https://github.com/SAFE-Stack/SAFE-BookStore/blob/master/src/Client/pages/Login.fs#L57
Very nice piece of work. Played around with the CounterApp sample and noticed that it is currently broken.
CounterApp throws an invalid operation exception when setting up the binding context for the page.(Combinators.fs:187)
It looks up the page's name ,"Page"
, in the ViewModels props
, which will fail.
In the end I got the sample to work, but I do not have a good solution for that, as the props
on the ViewModel do not seem to be aware of application pages.
Have you considered parameterising the constructor of ViewModel over the list of pages?
I'm trying to adapt one of the samples into a reusable template for new projects. My difficulty is that the master branch is currently API-incompatible with the NuGet package currently available, version 0.4.4, specifically because the property ProgramRunner.Model was replaced by an immutable property and a setter method as part of the commit titled "reduce size of generated code" (011cb1f). I realize that Elmish.XamarinForms is still in an early stage and that the API is still volatile, but I have two questions:
The structure of the fsproj file seems to not fall in line with what NUGET expects when it tries to update libraries.
1)dotnet new elmish-forms-app -lang F# -n SqueakyApp
2) open SqueakyApp in vsmac (also tested this on vs windows)
3) update Xamarin forms
4) you'll now get an error about multiple targets being imported
If you open the fsproj file for the Android project you'll notice there still exists an import statement for 3.0 even though project was updated to 3.1
I tested a blank template F# project and it was able to update to 3.1 without any issues
I tested this on vsmac alpha as well
At the moment it is just a theoretical issue. On Elmish that is not a problem because if there is an error the original state is reverted, but in this case, the new model is set before the commands are dispatched. So having an exception on the first command can prevent the other commands to be dispatched risking having the model in between states that can't be updated.
Probably that would work ok:
for sub in newCommands do
try
sub dispatch
with ex ->
program.onError ("Error executing commands:", ex)
As a plus, with that change I would be able to create a client for Elmish.Bridge using the onError
to send server messages without needing to rewrite features of the parent library as I needed with Elmish. I couldn't use the onError
because of the model reverting on error and that also made the model trapped between states on a test project.
FileSystemWatcher is known to be flaky on OSX, i.e. not triggering, triggering too many times, uses too many resources (can starve the system of file handles which in turn causes VSMac to stop saving files)
Consider something like this instead and dependencies - it's a wrapper around .Net Core FileSystemWatcher with some tweaks (as that too has issues)
I've just installed dotnet template
dotnet new -i Elmish.XamarinForms.Templates
and run
dotnet new elmish-forms-app -lang F# -n Xelmish
Then I opened solution with VS 2017 Community for Mac (VS 7.5.1, macOS Mojave 10.14 beta, dotnet --version = 2.1.300) and it gives me the next error:
/Users/azazeo/Xamarin/Projects/Xelmish/Xelmish/FSC: Error FS0193: The module/namespace 'Microsoft.FSharp.Core' from compilation unit 'FSharp.Core' did not contain the namespace, module or type 'voption`1' (FS0193) (Xelmish)
My demo code is like below
type Msg = Next
type Model = { Count: int }
let init () = { Count = 0 }, Cmd.none
let update msg model =
match msg with | Next -> { Count = if model.Count > 0 then 0 else 1 }, Cmd.none
let view model dispatch =
Xaml.ContentPage(
title = "Demo",
content =
if model.Count = 0 then
Xaml.Button(text = "Next1", command = fun _ -> dispatch Next)
else
Xaml.StackLayout(
children = [
Xaml.Label(text = "Finished")
Xaml.Button(text = "Go back", command = fun _ -> dispatch Next) ]
)
)
When I click next the Count is change to 1 and program is also running in to else block, but the UI is not updated.
Is there a XAML multi-page sample?
With ASP.NET Core hosting and PWA capability options
The template needs a solution.
Some properties are bound like obj
in the json file to allow implicit conversion just like we would do in XAML.
E.g. Image.Source can be set as a string
or as an ImageSource
.
Or GridRowDefinition can be either "*"
or GridLength.Star
Same with View.Margin
But when using such types, IntelliSense only shows that the property is obj
.
Developers don't know about the implicit conversions (if they didn't check the samples) and must look into the documentation of Xamarin.Forms to know what type exactly is allowed.
Wouldn't changing those obj
to discriminated unions be better?
It would make typing explicit to developers, while allowing the compiler to check if there's nothing funny going on.
And cherry on top, converters would output warnings if we're missing a case (which is not the case currently with type matching)
What do you think?
When the LiveUpdate gets a code update the model is reset to initial. It should be possible to have the interpreter convert the current model object into a new, interpreted model object (subject to various limitations)
I was reading the code presented in the Readme file and noticed this funcion:
let clockUpdate (msg:ClockMsg) (model:ClockModel) =
match msg with
| Tick t -> { model with Time = t }
Given that ClockModel is a record type with only one member, then the use of with
here seems moot. And the model parameter can be unused completely. Wouldn't we want this function to be simplified to...:
let clockUpdate (msg:ClockMsg) =
match msg with
| Tick t -> { Time = t }
Or am I missing something? Also I don't understand why the match
block is incomplete.
It is possible to map arbitrary XF elements into the XamlElement model, either with or without incremental update, just by hand-writing code that implements XamlElement
We should document this and put some examples in the repo
I'm trying to make a simple form with some fields and a Save button.
Is it possible when clicking the Save button to retrieve the current text of an Entry, without listening to TextChanged and putting the value into the Model?
Doing this means reconstructing all the UI just to update the values available in the button's callback.
Applies to: Android & iOS (devices and simulators)
Description:
It seems there's a bug with the way how the view is reused between updates.
It happens only after navigating to the "NavigationPage with push/pop" of the AllControls sample.
For a split second, we can see TabbedPage #2
, TabbedPage #3
and CarouselPage
instead of the buttons Push Page A
, Push Page B
and Main page
on the NavigationPage sample.
When clicking Main page
to go back, same thing. For a split second, there's still the text from the previous page.
But this time those 3 buttons also have a wrong HorizontalOptions value, despite the code not being different than the other buttons.
Repro:
After working around #47 and restoring packages successfully, I am not able to build the solution from Visual Studio 2017 latest and I get errors from the fsharp compiler that look like related to type providers:
Severity | Code | Description | Project | File | Line | Suppression State |
---|---|---|---|---|---|---|
Error | FS0193 | Could not find file 'C:\projects\elmish-xamarin-forms\Samples\AllControls\Droid\ProvidedTypes5c2b5dd0-36e9-4067-97f5-fdfe2f421972.dll'. | AllControls.Droid | FSC | 1 | Active |
Error | FS0193 | Could not find file 'C:\projects\elmish-xamarin-forms\Samples\TicTacToe\Droid\ProvidedTypes9f0bff89-67dd-46c2-a040-82a1e59c9ec5.dll'. | TicTacToe.Droid | FSC | 1 | Active |
I was going to add a missing property ListView.SelectionMode, but found this was new in XF 3.1 (link).
So my question is:
Can we update EXF to use the latest version of XF (templates and all), or is it tied to XF 3.0 for a reason?
FSharp.Data started supporting Dotnet Core. So, technically it should work. I was trying Xmlprovider in simple project https://github.com/kunjee17/functional-cat
It did compile and also gave intellisense from XML. But while running the project, it crashed. I don't know whose issue it is exactly so filing it here.
cc/ @dsyme
Is there a way to do some sort of "edit-and-continue" to edit the code while the app is running and have the changes reflect in the next render?
Something similar to the way people work with Flutter or how JavaScript people get "instant" changes in the UI after code modifications. It really helps with development flow in some situations.
Thank you!
The source
property on the Image is currently a string. This should be an ImageSource
to allow stream image sources to be used.
It would be great to have a consistent back button on all the pages of the AllControls sample, because currently it is quite painful to browse all the controls in the sample.
Most pages require to shutdown the app to go back to the RootPage.
Examples:
TabbedPage #1
has a back button hidden in the Grid
tabTabbedPage #3
has no back button at allProblem: The fscd.exe do not detect a saving of a file in Visual Studio 2017 (Windows).
The file is recognized by the watcher.
Other editors like notpad++ or Visual Studio Code are working. The saving will be detected.
I am currently use the newest version of Visual Studio 2017 (15.7.5).
Error:
/Users/sam.williams/Projects/SqueakyApp/SqueakyApp/FSC: Error FS0193: The module/namespace 'Microsoft.FSharp.Core' from compilation unit 'FSharp.Core' did not contain the namespace, module or type 'voption
1' (FS0193) (SqueakyApp)`
Occurs in all projects - Core, Droid and iOS
Expected:
all projects build successfully
Steps:
dotnet new elmish-forms-app -lang F# -n SqueakyApp
create an sln file and add the three projects
open sln file in Visual Studio for Mac
build project (I used DEBUG | AnyCPU
as the configuration)
also tried changed FSharp.Core version in the .NET Standard project using both 4.3.4 and 4.5.0. The .NET Standard project still fails to build.
also tried adding the fsc.props file
Environment:
=== Visual Studio Professional 2017 for Mac ===
Version 7.5.3 (build 7)
Installation UUID: 82dffde3-8fbe-456a-90d8-d8692da1f7d9
Runtime:
Mono 5.10.1.57 (2017-12/ea8a24b1bbf) (64-bit)
GTK+ 2.24.23 (Raleigh theme)
Xamarin.Mac 4.4.1.178 (master / eeaeb7e6)
Package version: 510010057
=== NuGet ===
Version: 4.3.1.4445
=== .NET Core ===
Runtime: /usr/local/share/dotnet/dotnet
Runtime Versions:
2.1.0
2.0.5
2.0.0
1.1.2
1.1.1
1.1.0
1.0.5
1.0.4
SDK: /usr/local/share/dotnet/sdk/2.1.300/Sdks
SDK Versions:
2.1.300
2.1.4
2.0.0
1.0.4
1.0.1
1.0.0-preview2-1-003177
MSBuild SDKs: /Library/Frameworks/Mono.framework/Versions/5.10.1/lib/mono/msbuild/15.0/bin/Sdks
=== Xamarin.Profiler ===
Version: 1.6.2
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler
=== Xamarin.Android ===
Version: 8.3.3.2 (Visual Studio Professional)
Android SDK: /Users/sam.williams/Library/Developer/Xamarin/android-sdk-macosx
Supported Android versions:
4.0.3 (API level 15)
5.1 (API level 22)
6.0 (API level 23)
7.1 (API level 25)
8.0 (API level 26)
8.1 (API level 27)
SDK Tools Version: 26.1.1
SDK Platform Tools Version: 27.0.1
SDK Build Tools Version: 27.0.3
Java SDK: /usr
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL
=== Apple Developer Tools ===
Xcode 9.3.1 (14154.1)
Build 9E501
=== Xamarin.Mac ===
Version: 4.4.1.193 (Visual Studio Professional)
=== Xamarin.iOS ===
Version: 11.12.0.4 (Visual Studio Professional)
Hash: 64fece5f
Branch: d15-7
Build date: 2018-05-29 20:00:44-0400
=== Xamarin Inspector ===
Version: 1.4.0
Hash: b3f92f9
Branch: master
Build date: Fri, 19 Jan 2018 22:00:34 GMT
Client compatibility: 1
=== Build Information ===
Release ID: 705030007
Git revision: 13cecd02aceddf29a1ed57b86f81c02994df1483
Build date: 2018-06-14 15:48:08-04
Xamarin addins: 7065de97cf22c9038fdc39dd627f2c30790fd8af
Build lane: monodevelop-lion-d15-7
=== Operating System ===
Mac OS X 10.13.3
Darwin 17.4.0 Darwin Kernel Version 17.4.0
Sun Dec 17 09:19:54 PST 2017
root:xnu-4570.41.2~1/RELEASE_X86_64 x86_64
=== Enabled user installed addins ===
Straight8's SpecFlow Intergration 1.11.0.0
Internet of Things (IoT) development (Preview) 7.5
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.