Skip to content

Commit

Permalink
Fix call on main thread
Browse files Browse the repository at this point in the history
  • Loading branch information
TimLariviere committed Jun 1, 2022
1 parent 7012760 commit 56b3f7b
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ module AboutPage =
type Msg = OpenBrowser of string

let openBrowserCmd url =
Device.InvokeOnMainThreadAsync(
funcTask = fun () -> task { do! Browser.OpenAsync(Uri url, BrowserLaunchMode.SystemPreferred) }
)
|> Async.AwaitTask
async {
do!
Browser.OpenAsync(Uri url, BrowserLaunchMode.SystemPreferred)
|> Async.AwaitTask
}
|> Helpers.executeOnMainThread

let init () = ()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ module DetailPage =
)
| _ -> do! displayAlert(Strings.DetailPage_DialNumberFailed, Strings.Common_Error, Strings.Common_OK)
}
|> executeOnMainThread

let tryComposeSmsAsync (phoneNumber: string) =
async {
Expand All @@ -61,6 +62,7 @@ module DetailPage =
)
| _ -> do! displayAlert(Strings.DetailPage_ComposeSmsFailed, Strings.Common_Error, Strings.Common_OK)
}
|> executeOnMainThread

let tryComposeEmailAsync emailAddress =
async {
Expand All @@ -77,6 +79,7 @@ module DetailPage =
)
| _ -> do! displayAlert(Strings.DetailPage_ComposeEmailFailed, Strings.Common_Error, Strings.Common_OK)
}
|> executeOnMainThread

// Lifecycle
let init (contact: Contact) = { Contact = contact }, Cmd.none
Expand Down
101 changes: 44 additions & 57 deletions samples/Xamarin.Forms/FabulousContacts/FabulousContacts/EditPage.fs
Original file line number Diff line number Diff line change
Expand Up @@ -91,61 +91,51 @@ module EditPage =
}

let tryUpdatePictureAsync (previousValue: _ option) =
Device.InvokeOnMainThreadAsync(
funcTask =
fun () ->
task {
let canTakePicture =
CrossMedia.Current.IsCameraAvailable
&& CrossMedia.Current.IsTakePhotoSupported

let canPickPicture = CrossMedia.Current.IsPickPhotoSupported

let hasPreviousPicture = previousValue.IsSome

let! action =
displayActionSheet(
None,
Some Strings.Common_Cancel,
(if hasPreviousPicture then
Some Strings.EditPage_PictureContextMenu_Remove
else
None),
Some [| if canTakePicture then
yield Strings.EditPage_PictureContextMenu_TakePicture
if canPickPicture then
yield Strings.EditPage_PictureContextMenu_ChooseFromGallery |]
)

let setPicture value = Some(SetPicture value)

match action with
| s when s = Strings.EditPage_PictureContextMenu_Remove -> return setPicture None
| s when s = Strings.EditPage_PictureContextMenu_TakePicture ->
let! bytes = doAsync<CameraPermission> takePictureAsync
return setPicture bytes
| s when s = Strings.EditPage_PictureContextMenu_ChooseFromGallery ->
let! bytes = doAsync<PhotosPermission> pickPictureAsync
return setPicture bytes
| _ -> return None
}
)
|> Async.AwaitTask
async {
let canTakePicture =
CrossMedia.Current.IsCameraAvailable
&& CrossMedia.Current.IsTakePhotoSupported

let canPickPicture = CrossMedia.Current.IsPickPhotoSupported

let hasPreviousPicture = previousValue.IsSome

let! action =
displayActionSheet(
None,
Some Strings.Common_Cancel,
(if hasPreviousPicture then
Some Strings.EditPage_PictureContextMenu_Remove
else
None),
Some [| if canTakePicture then
yield Strings.EditPage_PictureContextMenu_TakePicture
if canPickPicture then
yield Strings.EditPage_PictureContextMenu_ChooseFromGallery |]
)

let setPicture value = Some(SetPicture value)

match action with
| s when s = Strings.EditPage_PictureContextMenu_Remove -> return setPicture None
| s when s = Strings.EditPage_PictureContextMenu_TakePicture ->
let! bytes = doAsync<CameraPermission> takePictureAsync
return setPicture bytes
| s when s = Strings.EditPage_PictureContextMenu_ChooseFromGallery ->
let! bytes = doAsync<PhotosPermission> pickPictureAsync
return setPicture bytes
| _ -> return None
}

let sayContactNotValidAsync () =
Device.InvokeOnMainThreadAsync(
funcTask =
fun () ->
task {
do!
displayAlert(
Strings.EditPage_InvalidContactTitle,
Strings.EditPage_InvalidContactDescription,
Strings.Common_OK
)
}
)
|> Async.AwaitTask
async {
do!
displayAlert(
Strings.EditPage_InvalidContactTitle,
Strings.EditPage_InvalidContactDescription,
Strings.Common_OK
)
}

let createOrUpdateAsync dbPath contact =
async {
Expand All @@ -162,10 +152,7 @@ module EditPage =
async {
if not model.IsFirstNameValid
|| not model.IsLastNameValid then
do!
Device.InvokeOnMainThreadAsync(funcTask = fun () -> task { do! sayContactNotValidAsync() })
|> Async.AwaitTask

do! sayContactNotValidAsync()
return None
else
let id =
Expand Down
10 changes: 10 additions & 0 deletions samples/Xamarin.Forms/FabulousContacts/FabulousContacts/Helpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@ open Fabulous.XamarinForms
open type Fabulous.XamarinForms.View

module Helpers =
let executeOnMainThread (action: Async<'T>) : Async<'T> =
Device.InvokeOnMainThreadAsync(funcTask = fun () -> task { return! action })
|> Async.AwaitTask

let displayAlert (title, message, cancel) =
Application.Current.MainPage.DisplayAlert(title, message, cancel)
|> Async.AwaitTask
|> executeOnMainThread

let displayAlertWithConfirm (title, message, accept, cancel) =
Application.Current.MainPage.DisplayAlert(title = title, message = message, accept = accept, cancel = cancel)
|> Async.AwaitTask
|> executeOnMainThread

let displayActionSheet (title, cancel, destruction, buttons) =
let title = Option.toObj title
Expand All @@ -28,6 +34,7 @@ module Helpers =

Application.Current.MainPage.DisplayActionSheet(title, cancel, destruction, buttons)
|> Async.AwaitTask
|> executeOnMainThread

let requestPermissionAsync<'a when 'a: (new: unit -> 'a) and 'a :> BasePermission> () =
async {
Expand All @@ -42,6 +49,7 @@ module Helpers =
with
| _ -> return false
}
|> executeOnMainThread

let askPermissionAsync<'a when 'a: (new: unit -> 'a) and 'a :> BasePermission> () =
async {
Expand Down Expand Up @@ -69,6 +77,7 @@ module Helpers =

return picture |> Option.ofObj
}
|> executeOnMainThread

let pickPictureAsync () =
async {
Expand All @@ -81,6 +90,7 @@ module Helpers =

return picture |> Option.ofObj
}
|> executeOnMainThread

let readBytesAsync (file: MediaFile) =
async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,12 @@ module Repository =
database.Table<ContactObject>().ToListAsync()
|> Async.AwaitTask

return objs |> Seq.toList |> List.map convertToModel
let results =
objs |> Seq.toList |> List.map convertToModel

do! database.CloseAsync() |> Async.AwaitTask

return results
}

let insertContact dbPath contact =
Expand All @@ -77,6 +82,9 @@ module Repository =
|> Async.AwaitTask

let rowId = rowIdObj |> int

do! database.CloseAsync() |> Async.AwaitTask

return { contact with Id = rowId }
}

Expand All @@ -90,6 +98,8 @@ module Repository =
|> Async.AwaitTask
|> Async.Ignore

do! database.CloseAsync() |> Async.AwaitTask

return contact
}

Expand All @@ -102,4 +112,6 @@ module Repository =
database.DeleteAsync(obj)
|> Async.AwaitTask
|> Async.Ignore

do! database.CloseAsync() |> Async.AwaitTask
}

0 comments on commit 56b3f7b

Please sign in to comment.