fabulous-dev / fabulous.xamarinforms Goto Github PK
View Code? Open in Web Editor NEWDeclarative UIs for Xamarin.Forms with F# and MVU, using Fabulous
Home Page: https://docs.fabulous.dev/xamarinforms
License: Apache License 2.0
Declarative UIs for Xamarin.Forms with F# and MVU, using Fabulous
Home Page: https://docs.fabulous.dev/xamarinforms
License: Apache License 2.0
Hello! I'm back with another possibly silly question.
I have a situation where I need to add child views to - preferably - a FlexLayout or StackLayout, at runtime, after the first init
call, based on user input. The child views can be of different types, depending on the user input and values that are periodically retrieved/updated from a remote source and saved into an SQLite database in the app.
I had hoped that I could just wrap a FlexLayout in a ScrollView and when I insert the new child views, things would expand to accomodate, even if the overall height ends up taller than the device screen. It seems that FlexLayout does not do this. What I'm seeing is that the ScrollView does seem to account for the height of the newly inserted elements but neither a FlexLayout or StackLayout do. So the result is that after the new child views are inserted, any child views that end up below the overall height of the screen are not shown, but the ScrollView none the less acts like they are there and one can scroll "below the fold" to see only empty space.
Before I start tearing out code wholesale to try and find a completely different way to do this, can anyone point me in the direction of a good way to dynamically insert heterogeneous child views like this, with Fabulous?
A simplified and contrived example of what I'm trying to do (based off the Fabulous example app):
// Copyright Fabulous contributors. See LICENSE.md for license.
namespace FabXamApp
open System
open Fabulous
open Fabulous.XamarinForms
open Xamarin.Forms
module App =
type Model =
{ Values: Tuple<string, string> list }
type Msg =
| Insert
| Reset
let initModel = { Values = [] }
let init () = initModel, Cmd.none
let update msg model =
match msg with
| Insert ->
// In reality these values come from a database and can change from time to time.
// Sometimes there could be quite a lot of values, other times not so much.
let values = [ ("Label 1", "Placeholder 1"); ("Label 2", "Placeholder 2"); ("Label 3", "Placeholder 3"); ("Label 4", "Placeholder 4") ]
{ model with Values = values }, Cmd.none
| Reset -> init ()
let insertView value =
match value with
| v when v = ("Label 2", "Placeholder 2") ->
View.Grid(
width = 250.,
height = 200.,
rowdefs = [ Absolute 200. ],
coldefs = [ Star; Star ],
children = [
View.Label(
verticalOptions = LayoutOptions.FillAndExpand,
verticalTextAlignment = TextAlignment.Center,
text = (v |> fst)
).Row(0).Column(0)
View.Switch(
verticalOptions = LayoutOptions.FillAndExpand,
horizontalOptions = LayoutOptions.End,
isToggled = true
).Row(0).Column(1)
]
)
| _ ->
View.StackLayout(
height = 200.,
horizontalOptions = LayoutOptions.Center,
padding = Thickness (0., 10., 0., 10.),
children = [
View.Label(
height = 42.,
width = 200.,
text = (value |> fst)
)
View.Editor(
height = 42.,
width = 200.,
placeholder = (value |> snd)
)
]
)
let view (model: Model) dispatch =
View.ContentPage(
content =
View.ScrollView(
View.FlexLayout(
direction = FlexDirection.Column,
alignItems = FlexAlignItems.Center,
justifyContent = FlexJustify.SpaceEvenly,
children = [
// In reality, user input is more variable than just a button and this input will ultimately
// decide whether labels, switches, entries, etc. are inserted.
View.Button(text = "Insert", horizontalOptions = LayoutOptions.Center, command = (fun () -> dispatch Insert))
View.Button(text = "Reset", horizontalOptions = LayoutOptions.Center, command = (fun () -> dispatch Reset))
match model.Values.Length with
| l when l > 0 ->
for value in model.Values do
insertView value
| _ -> ()
View.Label(text = "I'm near the bottom and may not be visible after you tap 'Insert'", horizontalOptions = LayoutOptions.Center, width=200.0, horizontalTextAlignment=TextAlignment.Center)
]
)
)
)
// Note, this declaration is needed if you enable LiveUpdate
let program =
XamarinFormsProgram.mkProgram init update view
#if DEBUG
|> Program.withConsoleTrace
#endif
type App () as app =
inherit Application ()
let runner =
App.program
|> XamarinFormsProgram.run app
Hi, I am trying to create a Share Extension for a Fabulous app. The process of creating these extensions are explained here: https://docs.microsoft.com/en-us/xamarin/ios/platform/extensions
I am wondering how to create and call a Fabulous program loop from these extensions. Are there any existing samples of this and/or do we know if this feasible to do with a Fabulous approach vs native or Xamarin.Forms?
Thanks for the help,
Ben
I'm brand new to both Xamarin and Fabulous and trying to get my feet wet, but I can't compile the default Android project in the template without making any modifications.
Tested with these Fabulous template versions:
dotnet SDK version: 5.0.100
Visual Studio version:
Microsoft Visual Studio Community 2019
Version 16.8.0
VisualStudio.16.Release/16.8.0+30709.132
Microsoft .NET Framework
Version 4.8.04084
Installed Version: Community
Run these steps (I did it from within PowerShell, but I assume a regular command prompt would work as well):
> dotnet new -i Fabulous.XamarinForms.Templates::0.60.0-preview3
> dotnet new fabulous-xf-app -n FabulousTest --iOS=false
The template "Fabulous Xamarin.Forms App v0.60.0-preview3" was created successfully.
Processing post-creation actions...
Template is configured to run the following action:
Description:
Manual instructions: Run 'dotnet tool restore' to install fabulous-cli
Actual command: dotnet tool restore
Do you want to run this action (Y|N)?
y
Running command 'dotnet tool restore'...
Command succeeded.
Now, open the solution in Visual Studio and try to build the Android project. Below is the output I get in the Build window:
1>------ Build started: Project: FabulousTest, Configuration: Debug Any CPU ------
1>C:\Users\UserName\.nuget\packages\xamarin.forms\4.8.0.1269\buildTransitive\Xamarin.Forms.targets(227,5): warning : Xamarin.Forms recommends TargetPlatformMinVersion >= 10.0.14393.0 (current project is -1)
1>C:\Users\UserName\.nuget\packages\xamarin.forms\4.8.0.1269\buildTransitive\Xamarin.Forms.targets(233,5): warning : Xamarin.Forms recommends TargetPlatformVersion >= 10.0.17763.0 (current project is -1)
1>FabulousTest -> D:\Documents\Projects\FabulousTest\FabulousTest\bin\Debug\netstandard2.0\FabulousTest.dll
1>Done building project "FabulousTest.fsproj".
2>------ Build started: Project: FabulousTest.Android, Configuration: Debug Any CPU ------
2> No way to resolve conflict between "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" and "mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e". Choosing "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" arbitrarily.
2>FSC: error CS1703: An assembly with the same identity 'System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' has already been imported. Try removing one of the duplicate references.]
2>parse error FS3053: error : The type provider constructor has thrown an exception: [error CS1703: An assembly with the same identity 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' has already been imported. Try removing one of the duplicate references.;� error CS1703: An assembly with the same identity 'System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' has already been imported. Try removing one of the duplicate references.]
2>FSC: warning FS3005: Referenced assembly 'D:\Documents\Projects\FabulousTest\packages\Xamarin.Android.FSharp.ResourceProvider.1.0.0.28\lib\monoandroid81\Xamarin.Android.FSharp.ResourceProvider.Runtime.dll' has assembly level attribute 'Microsoft.FSharp.Core.CompilerServices.TypeProviderAssemblyAttribute' but no public type provider classes were found
2>Done building project "FabulousTest.Android.fsproj" -- FAILED.
2>
2>Build FAILED.
========== Build: 1 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I'm assuming I'm just doing something wrong - surely if the template was broken, someone else would have reported it by now - but I have no idea what. Is there anything I can do to troubleshoot this issue?
Maintaining a Xamarin Forms (5.0.0.2545) Fabulous 1.1.0 app and I think I've been hit with this XF bug. A workaround is mentioned, add await Task.Delay(50)
before setting items in the CollectionView. I'm having trouble translating this in a way that works, in the context of a Fabulous 1.1.0 XF app. A simplified example of the page:
View.ContentPage(
title = "Content Page"
content =
View.ScrollView(
View.CollectionView(
items = // ???
)
)
)
What might be the best approach here?
I have a ListView like this:
View.ListView (
selectionMode = ListViewSelectionMode.Single,
selectedItem = model.SelectedIndex,
itemSelected = Option.iter (UpdateSelectedIndex >> dispatch),
items = [ for name in model.Names do yield itemView name ]
)
Problem is that the items (with new content) are shown immediately in the UI, but the selected item is highlighted a little bit late due to the animation.
How to disable this animation?
Description:
Steps to reproduce:
SwipeView(
(Grid() {
Label("Swipe left or Right")
.centerTextHorizontal ()
})
.centerHorizontal()
.centerVertical()
.size(300., 60.)
)
.leftItems(
SwipeItems() {
SwipeItem(Increment)
.text("About")
.backgroundColor(Xamarin.Forms.Color.Red.ToFabColor())
.icon("icon.png")
SwipeItem(Increment)
.text("About")
.backgroundColor(Xamarin.Forms.Color.Green.ToFabColor())
SwipeItem(Decrement)
.text("github")
.backgroundColor(Xamarin.Forms.Color.Blue.ToFabColor())
}
)//.onSwipeStarted(SwipeStarted)
Expected outcome:
Actual outcome:
Environment:
Hi everyone,
when trying to build a fresh app from the current Fabulous.XamarinForms.Templates 2.1.3 I do receive an error from Visual Studio saying that it can not find Fabulous 2.1.3.
NuGet Package restore failed for project SplitApp.Android: Unable to find version '2.1.3' of package 'Fabulous'.
C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\: Package 'Fabulous.2.1.3' is not found on source 'C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\'.
https://api.nuget.org/v3/index.json: Package 'Fabulous.2.1.3' is not found on source 'https://api.nuget.org/v3/index.json'.
. Please see Error List window for detailed warnings and errors.
same goes for App.IOS
Further looking into it, it looks like FabulousPkgsVersion
is used for the package.config
<packages>
<package id="Fabulous" version="FabulousPkgsVersion" targetFramework="monoandroid11.0" />
<package id="Fabulous.XamarinForms" version="FabulousPkgsVersion" targetFramework="monoandroid11.0" />
...
<packages>
But I think here is the issue.
While Fabulous.XamarinForms
is released as 2.1.3
Fabulous
is not. (current 2.1.0)
dotnet new fabulous-xf-app -n SqueakyApp
Debug Any CPU
for SqueakyApp.Android
.Should be able to deploy the app to android emulator.
Getting the following build error:
Build started...
1>------ Build started: Project: SqueakyApp.Android, Configuration: Debug Any CPU ------
1>packages.config: warning XA0101: @(Content) build action is not supported
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\Android\Xamarin.Android.Aapt2.targets(157,3): error APT2260: resource style/Theme.AppCompat.Light.Dialog (aka com.companyname:style/Theme.AppCompat.Light.Dialog) not found.
1>Resources\values\styles.xml(4,0): error APT2260: style attribute 'attr/colorAccent (aka com.companyname:attr/colorAccent)' not found.
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\Android\Xamarin.Android.Aapt2.targets(157,3): error APT2260: resource style/Theme.AppCompat.Light.DarkActionBar (aka com.companyname:style/Theme.AppCompat.Light.DarkActionBar) not found.
1>Resources\values\styles.xml(2,0): error APT2260: style attribute 'attr/windowNoTitle (aka com.companyname:attr/windowNoTitle)' not found.
1>Resources\values\styles.xml(2,0): error APT2260: style attribute 'attr/windowActionBar (aka com.companyname:attr/windowActionBar)' not found.
1>Resources\values\styles.xml(2,0): error APT2260: style attribute 'attr/colorPrimary (aka com.companyname:attr/colorPrimary)' not found.
1>Resources\values\styles.xml(2,0): error APT2260: style attribute 'attr/colorPrimaryDark (aka com.companyname:attr/colorPrimaryDark)' not found.
1>Resources\values\styles.xml(3,0): error APT2260: style attribute 'attr/colorAccent (aka com.companyname:attr/colorAccent)' not found.
1>Resources\values\styles.xml(4,0): error APT2260: style attribute 'attr/windowActionModeOverlay (aka com.companyname:attr/windowActionModeOverlay)' not found.
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\Android\Xamarin.Android.Aapt2.targets(157,3): error APT2062: failed linking references.
1>Done building project "SqueakyApp.Android.fsproj" -- FAILED.
1>
1>Build FAILED.
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========
========== Deploy: 0 succeeded, 0 failed, 0 skipped ========
Microsoft Visual Studio Community 2019 (2)
Version 16.11.10
VisualStudio.16.Release/16.11.10+32126.315
Microsoft .NET Framework
Version 4.8.04161
Installed Version: Community
Azure App Service Tools v3.0.0 16.11.106.23128
Azure App Service Tools v3.0.0
C# Tools 3.11.0-4.21602.3+fc14a1355c0461af5110b74b26f6478f22d26565
C# components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.
Common Azure Tools 1.10
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.
Extensibility Message Bus 1.2.6 (master@34d6af2)
Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.
IntelliCode Extension 1.0
IntelliCode Visual Studio Extension Detailed Info
Microsoft JVM Debugger 1.0
Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines
Microsoft MI-Based Debugger 1.0
Provides support for connecting Visual Studio to MI compatible debuggers
Mono Debugging for Visual Studio 16.10.15 (552afdf)
Support for debugging Mono processes with Visual Studio.
NuGet Package Manager 5.11.0
NuGet Package Manager in Visual Studio. For more information about NuGet, visit https://docs.nuget.org/
ProjectServicesPackage Extension 1.0
ProjectServicesPackage Visual Studio Extension Detailed Info
Visual Basic Tools 3.11.0-4.21602.3+fc14a1355c0461af5110b74b26f6478f22d26565
Visual Basic components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.
Visual F# Tools 16.11.0-beta.21514.6+b6c2c4f53ea3a08fa603ea93d6d2f808a62a21d1
Microsoft Visual F# Tools
Visual Studio Code Debug Adapter Host Package 1.0
Interop layer for hosting Visual Studio Code debug adapters in Visual Studio
VisualStudio.DeviceLog 1.0
Information about my package
VisualStudio.Foo 1.0
Information about my package
VisualStudio.Mac 1.0
Mac Extension for Visual Studio
Xamarin 16.11.000.197 (d16-11@6934992)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.
Xamarin Designer 16.11.0.47 (remotes/origin/d16-11@e0d612363)
Visual Studio extension to enable Xamarin Designer tools in Visual Studio.
Xamarin Templates 16.10.5 (355b57a)
Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.
Xamarin.Android SDK 12.0.0.3 (d16-11/f0e3c2d)
Xamarin.Android Reference Assemblies and MSBuild support.
Mono: c633fe9
Java.Interop: xamarin/java.interop/d16-11@476bb5b
ProGuard: Guardsquare/proguard@912d149
SQLite: xamarin/sqlite@85460d3
Xamarin.Android Tools: xamarin/xamarin-android-tools/d16-11@87af37b
Xamarin.iOS and Xamarin.Mac SDK 15.2.0.17 (738fde344)
Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.
Have pasted above under Actual Result
section.
Build error issue; no screenshots.
Tried installing the app locally.
No workaround so far.
While working on Fabulous.Maui fabulous-dev/Fabulous#919, I noticed the Maui team opened up the implementation of NavigationPage
via the new IStackNavigationView
interface (https://github.com/dotnet/maui/blob/main/src/Core/src/Core/IStackNavigation.cs). This interface gives us way more flexibility in how we want to make the navigation work inside Fabulous.
So it got me thinking: what would be a good navigation experience in Fabulous?
Today in Fabulous.XamarinForms, we are simply mapping 1-to-1 the NavigationPage
. This NavigationPage uses the Push/Pop method to add or remove pages from the stack.
In order to make it play nicely with MVU, we hid the Push/Pop calls by implicitly calling them as users add and remove child pages under NavigationPage.
NavigationPage() {
// First page
ContentPage(...)
// Second page
if model.UserHasNavigatedToSecondPage then
ContentPage(...)
}
Here, we will only push the second page if model.UserHasNavigatedToSecondPage = true
.
As soon as model.UserHasNavigatedToSecondPage
reverts back to false
, we will call pop - only showing the 1st screen.
This model is nice but lacks flexibility. You need to explicitly define the whole navigation hierarchy of your app.
If you need to navigate to any page in any order, it is not currently possible in Fabulous.
NavigationPage() {
// First page
ContentPage(...)
// Second page
if showSecondPage then
ContentPage(...)
// Third page
if showThirdPage then
ContentPage(...)
// Fourth page
if showFourthPage then
ContentPage(...)
(...)
}
Fabulous uses the MVU architecture.
This means ideally the complete state of the application MUST BE stored in the Model
record so we can ensure consistency and repeatability.
This also means the view function needs to explicitly list all the subviews, including all pages in the navigation stack.
SwiftUI, Compose and Flutter all choose to let an external party handle their navigation. This means it breaks the 2 rules above.
I would like to introduce 3 new types:
NavigationStack
that will be in charge of keeping a list of all pages visited and their models; will be stored in the App.ModelRoute
, a widget taking a page key and the related page view function to be called when the navigation requires itNavigationView
, a new widget that will use one or more Route
to describe which pages are available for navigation and NavigationStack
to know which pages to actually show on screenRoute
is only here to describe a page and won't ever make it to the UI tree.
type NavigationStack private () =
// We need to enforce the initialisation with at least 1 page
static member init(key, model)
member this.push(...)
member this.pop(...)
member [<Event>] this.Pushed
member [<Event>] this.Popped
let view model =
NavigationView(stack: NavigationStack, onPushPop: NavigationStack -> 'msg) {
Route(key: string, viewFn: obj -> WidgetBuilder<'pageMsg, #IView>, mapMsgFn: int * 'pageMsg -> 'rootMsg)
Route(...)
Route(...)
}
The implementation will require a new RouteBuilder
computation expression that only accepts Route
.
When compiling this CE, it would instead for
-loop into the stack, call the corresponding Route
view function and append the resulting view into the NavigationView.Pages
attribute.
module Pages =
let [<Literal>] home = "home"
let [<Literal>] list = "list"
let [<Literal>] detail = "detail"
module AppRoot =
type Model = { Stack: NavigationStack }
type Msg =
| NavStackUpdated of NavigationStack
| HomePageMsg of (...)
| ListPageMsg of (...)
| DetailPageMsg of (...)
let init() =
{ Stack = NavigationStack.init(Pages.home, HomePage.init()) }
let update msg model = (...)
let view model =
NavigationView(model.Stack, NavStackUpdated) {
Route(Pages.home, HomePage.view, HomePageMsg)
Route(Pages.list, ListPage.view, ListPageMsg)
Route(Pages.detail, DetailPage.view, DetailPageMsg)
}
type Msg =
// This NavStackUpdated msg is here to trigger a update-view loop
// in Fabulous in case we call NavStack.push/pop
| NavStackUpdated of NavigationStack
// Since we can have multiple times the same page in the nav stack,
// we have to include the index which triggered the msg
| HomePageMsg of index: int * model: HomePage.Model
| ListPageMsg of index: int * model: ListPage.Model
| DetailPageMsg of index: int * model: DetailPage.Model
let update msg model =
match msg with
| NavStackUpdated newStack ->
{ model with Stack = newStack }
// We can provide a helper function that will update a specific index
// in the nav stack by calling the function passed to it (here HomePage.update)
| HomePageMsg (index, msg) ->
{ model with
Stack = model.Stack |> NavigationStack.update HomePage.update msg index }
Child pages can directly interact with the NavigationStack by passing the stack to them when calling the update function.
Since NavigationStack
is not part of the UI tree, it can't dispatch messages for Fabulous. Instead NavigationView
will subscribe to the Pushed
/ Popped
event of its NavigationStack
and dispatch a NavStackUpdated
message to force Fabulous to trigger an update-view loop.
module ListPage =
type Model = { ... }
type Msg = GoBack | GoToDetail of id: int
let init () = { ... }
let update navStack msg model =
match msg with
| GoBack ->
navStack.pop()
model
| GoToDetail id ->
navStack.push(Pages.list, DetailPage.init id)
model
let view model = (...)
The good thing about this proposition is that it's also compatible with Xamarin.Forms NavigationPage
.
This is thanks to the fact at runtime we still use the Pages
collection attribute.
Since Xamarin.Forms is in maintenance mode only starting 5.0 and will go out of support in May 2024, we will do the same with Fabulous.XamarinForms.
We need to add a message at the top of the README file to make this clear to everyone.
https://dotnet.microsoft.com/en-us/platform/support/policy/xamarin
I'm attempting to use Media.Plugin with Fabulous. Unfortunately, using the Xamarin.Essentials Media Picker would not be ideal as it doesn't yet support everything I need to do. Right now I'm just trying to figure out what compiles and works, I'm not at all sure this is the best way to do it, or if what I'm trying to do is actually possible. Currently I'm trying to get Media.Plugin to open up the photo gallery for picking photos on iOS, via the CrossMedia.Current.PickPhotosAsync
method. Current problem is the photo gallery never appears.
In my page, I have a button that dispatches a SelectFromGallery
message. This message is matched in update
:
let update msg model =
match msg with
| SelectFromGallery -> { model with IsBusy = true },
Cmd.ofMsg (processSelectFromGallery model |> Async.StartImmediateAsTask).Result, ExternalMsg.NoOp
processSelectFromGallery
is called and looks like this:
let processSelectFromGallery model =
async {
try
match CrossMedia.Current.IsPickPhotoSupported with
| false -> return SelectFromGalleryError
| true ->
let mediaOptions = new PickMediaOptions (RotateImage = true)
let multiPickerOptions = new MultiPickerOptions (MaximumImagesCount = model.MaximumImagesCount)
let! currentPhotos =
CrossMedia.Current.PickPhotosAsync (mediaOptions, multiPickerOptions) |> Async.AwaitTask
return SelectFromGallerySuccess currentPhotos
with
| _ -> return SelectFromGalleryError
}
I have left out Async.SwitchToThreadPool()
as it seems things should be happening on the UI thread otherwise an exception is thrown out from Media.Plugin code. I gathered from this issue that using Async.RunSynchronously
silently "refuses" to run the code on the UI thread, hence why I've gone with Async.StartImmediateAsTask
, as I was hoping to return the collection of photos with the SelectFromGallerySuccess
message. I don't actually get to returning SelectFromGallerySuccess
.
CrossMedia.Current.PickPhotosAsync
is called and following the code execution inside Media.Plugin I can see Media.Plugin is constructing a UIViewController that looks like it is meant to show the photo gallery picker. But this UIViewController never displays. My hunch is that this is all happening orthogonal to the update loop and so it's not registering. CrossMedia.Current.PickPhotosAsync
is meant to return a System.Collections.Generic.List<MediaFile>
so the UIViewController construction and display all happens inside Media.Plugin code.
So my questions would be: is my hunch correct? Or am I going about this entirely wrong? Is using MediaPlugin or the Xamarin Essentials MediaPicker (which I assume works in a similar way to James Montemagno's MedaPlugin in so far as constructing its own view controller) with Fabulous actually possible? And if not, what would be the recommended alternate way forward for dealing with picking media from the photo gallery?
I'm trying to translate this C# code for use with Fabulous.XamarinForms.FFImageLoading:
var t = ImageService.Instance.LoadStream(async c => await image.OpenReadAsync()); // image is a Xamarin.Essentials.FileResult.
t.Transform(new RotateTransformation(90));
using var imageStream = await t.AsPNGStreamAsync();
I've gotten this far in F#:
let t = FFImageLoading.ImageService.Instance.LoadStream(fun _ -> image.OpenReadAsync())
t.Transform(FFImageLoading.Transformations.RotateTransformation(90.)) |> ignore
use! imageStream = t.AsPNGStreamAsync() |> Async.AwaitTask
But in my F# code the AsPNGStreamAsync
extension method cannot be found.
I also don't understand why open Fabulous.XamarinForms.FFImageLoading
or open FFImageLoading
both don't seem to work and I need to use use FFImageLoading.ImageService ...
and FFImageLoading.Transformations ...
instead. But I suspect this may have something to do with my problem.
Can anyone tell me what I'm doing wrong?
When a view update reorders a WebView control, sometimes the text set in its source.Html never appears
See the diff vs the standard counter app
The WebView should always show its HTML
Sometimes the WebView is created blank.
Adding a 'key' property to the WebView doesn't solve the problem
Version with issue:
Last known good version:
Platform Target Frameworks:
NuGet Packages:
Affected Devices:
Microsoft Visual Studio Community 2019
Version 16.9.4
VisualStudio.16.Release/16.9.4+31205.134
Microsoft .NET Framework
Version 4.8.04084
Installed Version: Community
Visual C++ 2019 00435-60000-00000-AA135
Microsoft Visual C++ 2019
ADL Tools Service Provider 1.0
This package contains services used by Data Lake tools
ASA Service Provider 1.0
ASP.NET and Web Tools 2019 16.9.693.2781
ASP.NET and Web Tools 2019
ASP.NET Core Razor Language Services 16.1.0.2112521+5741df381174d72f08e3632bb99f52e8635b6a1a
Provides languages services for ASP.NET Core Razor.
ASP.NET Web Frameworks and Tools 2019 16.9.693.2781
For additional information, visit https://www.asp.net/
Azure App Service Tools v3.0.0 16.9.693.2781
Azure App Service Tools v3.0.0
Azure Data Lake Node 1.0
This package contains the Data Lake integration nodes for Server Explorer.
Azure Data Lake Tools for Visual Studio 2.6.3000.0
Microsoft Azure Data Lake Tools for Visual Studio
Azure Functions and Web Jobs Tools 16.9.693.2781
Azure Functions and Web Jobs Tools
Azure Stream Analytics Tools for Visual Studio 2.6.3000.0
Microsoft Azure Stream Analytics Tools for Visual Studio
C# Tools 3.9.0-6.21160.10+59eedc33d35754759994155ea2f4e1012a9951e3
C# components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.
Code alignment 14.1.107.0
Code alignment helps you present your code beautifully, enhancing clarity and readability.
Common Azure Tools 1.10
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.
Extensibility Message Bus 1.2.6 (master@34d6af2)
Provides common messaging-based MEF services for loosely coupled Visual Studio extension components communication and integration.
F# Formatting 0.8
F# source code formatting using Fantomas.
Fabric.DiagnosticEvents 1.0
Fabric Diagnostic Events
IntelliCode Extension 1.0
IntelliCode Visual Studio Extension Detailed Info
Markdown Editor 1.12.253
A full featured Markdown editor with live preview and syntax highlighting. Supports GitHub flavored Markdown.
Microsoft Azure HDInsight Azure Node 2.6.3000.0
HDInsight Node under Azure Node
Microsoft Azure Hive Query Language Service 2.6.3000.0
Language service for Hive query
Microsoft Azure Service Fabric Tools for Visual Studio 16.0
Microsoft Azure Service Fabric Tools for Visual Studio
Microsoft Azure Stream Analytics Language Service 2.6.3000.0
Language service for Azure Stream Analytics
Microsoft Azure Stream Analytics Node 1.0
Azure Stream Analytics Node under Azure Node
Microsoft Azure Tools 2.9
Microsoft Azure Tools for Microsoft Visual Studio 2019 - v2.9.40331.1
Microsoft Continuous Delivery Tools for Visual Studio 0.4
Simplifying the configuration of Azure DevOps pipelines from within the Visual Studio IDE.
Microsoft JVM Debugger 1.0
Provides support for connecting the Visual Studio debugger to JDWP compatible Java Virtual Machines
Microsoft Library Manager 2.1.113+g422d40002e.RR
Install client-side libraries easily to any web project
Microsoft MI-Based Debugger 1.0
Provides support for connecting Visual Studio to MI compatible debuggers
Microsoft Visual C++ Wizards 1.0
Microsoft Visual C++ Wizards
Microsoft Visual Studio Tools for Containers 1.1
Develop, run, validate your ASP.NET Core applications in the target environment. F5 your application directly into a container with debugging, or CTRL + F5 to edit & refresh your app without having to rebuild the container.
Microsoft Visual Studio VC Package 1.0
Microsoft Visual Studio VC Package
Mono Debugging for Visual Studio 16.9.7 (df23ba6)
Support for debugging Mono processes with Visual Studio.
NCrunch
Continuous Testing Tool for .NET
Copyright � 2010-2021 Remco Software Ltd
Node.js Tools 1.5.21130.2 Commit Hash:dacc0e71a5e060cdcab466a301cacea359c1b6da
Adds support for developing and debugging Node.js apps in Visual Studio
NuGet Package Manager 5.9.0
NuGet Package Manager in Visual Studio. For more information about NuGet, visit https://docs.nuget.org/
ParallelBuildsMonitorWindow Extension 1.0
ParallelBuildsMonitorWindow Visual Studio Extension Detailed Info
Productivity Power Tools 2017/2019 16.0
Installs the individual extensions of Productivity Power Tools 2017/2019
ProjectServicesPackage Extension 1.0
ProjectServicesPackage Visual Studio Extension Detailed Info
Regex Editor 1.0
.Net Regular Expressions tools
SQL Server Data Tools 16.0.62103.10080
Microsoft SQL Server Data Tools
Test Adapter for Boost.Test 1.0
Enables Visual Studio's testing tools with unit tests written for Boost.Test. The use terms and Third Party Notices are available in the extension installation directory.
Test Adapter for Google Test 1.0
Enables Visual Studio's testing tools with unit tests written for Google Test. The use terms and Third Party Notices are available in the extension installation directory.
ToolWindowHostedEditor 1.0
Hosting json editor into a tool window
Tweaks 1.1.115
A collection of minor fixes and tweaks for Visual Studio to reduce the paper cuts and make you a happier developer
TypeScript Tools 16.0.30201.2001
TypeScript Tools for Microsoft Visual Studio
Viasfora 4.3.195
Add color to your Visual Studio editor!
Visual Basic Tools 3.9.0-6.21160.10+59eedc33d35754759994155ea2f4e1012a9951e3
Visual Basic components used in the IDE. Depending on your project type and settings, a different version of the compiler may be used.
Visual F# Tools 16.9.0-beta.21102.9+7ce7132f1459095e635194d09d6f73265352029a
Microsoft Visual F# Tools
Visual Studio Code Debug Adapter Host Package 1.0
Interop layer for hosting Visual Studio Code debug adapters in Visual Studio
Visual Studio Container Tools Extensions 1.0
View, manage, and diagnose containers within Visual Studio.
Visual Studio Tools for CMake 1.0
Visual Studio Tools for CMake
Visual Studio Tools for Containers 1.0
Visual Studio Tools for Containers
Visual Studio Tools for Kubernetes 1.0
Visual Studio Tools for Kubernetes
VisualStudio.DeviceLog 1.0
Information about my package
VisualStudio.Mac 1.0
Mac Extension for Visual Studio
Xamarin 16.9.000.273 (d16-9@1bba9e0)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.
Xamarin Designer 16.9.0.318 (remotes/origin/7b35adcdd1b204bbdcb279e0f029d151a20a4bf3@7b35adcdd)
Visual Studio extension to enable Xamarin Designer tools in Visual Studio.
Xamarin Templates 16.9.72 (426ebf6)
Templates for building iOS, Android, and Windows apps with Xamarin and Xamarin.Forms.
Xamarin.Android SDK 11.2.2.1 (d16-9/877f572)
Xamarin.Android Reference Assemblies and MSBuild support.
Mono: 5e9cb6d
Java.Interop: xamarin/java.interop/d16-9@54f8c24
ProGuard: Guardsquare/proguard/v7.0.1@912d149
SQLite: xamarin/sqlite/3.34.1@daff8f4
Xamarin.Android Tools: xamarin/xamarin-android-tools/d16-9@d210f11
Xamarin.iOS and Xamarin.Mac SDK 14.14.2.5 (3836759d4)
Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.
https://github.com/marklam/FabulousXamarinFormsWebViewProblem
Not found any
I'm currently trying to figure out how to get light/dark themes working with my full Elmish style Fabulous app (multi-page, somewhat following the composition model of the FabulousContacts example app). I've managed to get the themes sorted out, mainly by the F#-coded styling approach, plus some native styling that I needed to do in the Android project (via values and values-night, etc). The F# style code is simple, an excerpt example:
module Style =
let isDarkTheme = Application.Current.RequestedTheme = OSAppTheme.Dark
let TabBackgroundColor = if isDarkTheme then Color.FromHex("#2d2d30") else Color.FromHex("#f6f6f6")
let TabUnselectedColor = if isDarkTheme then Color.FromHex("#d0d0d0") else Color.FromHex("#949594")
These values are used within the various view functions to set colours on elements.
The themes are working, except that I can't apply them at runtime, e.g. if the theme changes automatically due to time of day or if the user manually changes the theme while the app is still running. The theme is only set when the app starts. I was hoping to use the Application.Current.RequestedThemeChanged
event to dispatch a message (in conjunction with the approach discussed under Triggering Commands from External Events) as I assumed that I would need to somehow trigger an update of the pages in the app for the F#-coded styling approach to work and reapply the different colours to the view elements. But as @TimLariviere mentions here, the Application.Current.RequestedThemeChanged
event does not seem to fire.
If anyone could give any info or examples on how they have managed dynamically applying light/dark themes at runtime for Fabulous, that would be much appreciated.
New to Fabulous. I'm using the XF Shell for a Fabulous XF app I'm writing, currently attempting to understand how one would use BackButtonBehaviour and OnBackButtonPressed in the Fabulous DSL.
I've gotten this far:
View.Shell(
shellBackButtonBehavior = // ???
)
Or perhaps this far:
View.ContentPage(
shellBackButtonBehavior = // ???
)
Similarly, I'm not sure how to override OnBackButtonPressed in the context of Fabulous. Can anyone provide some example code?
Is it possible to open multiple windows now? For example, let's say I want to open a new modal window from the main app/window where the modal window has its own separate update loop.
I propose we add support for AppLinkEntry :
This will enable scenarios like :
Application(...)
.onAppLinkReceived(NavigateDeepInAppMsg)
.appLinks {
AppLink(...)
AppLink(...)
}
We have out implementation of CollectionView that frequently uses UpdateIncremental
function. I find out that sometimes geastureRecognizers
are not updated. There is examle:
let i = ref 0
let view ... =
incr i
let a = !i
View.Label(
text = string a,
geastureRecognizers = [
View.TapGestureRecognizer (fun _ -> printfn "%i" a)
]
)
When I run this example I see different values in UI and stdout. This reproduced only on iOS.
I think would be good to add a wrapper to these libraries like we are doing to Maps
Glide: https://github.com/jonathanpeppers/glidex
Nuke: https://github.com/roubachof/Xamarin.Forms.Nuke
Blog Post: https://www.sharpnado.com/xamarin-nuke-a-xamarin-binding/
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.