obsidiansystems / obelisk

Functional reactive web and mobile applications, with batteries included.
https://reflex-frp.org
BSD 3-Clause "New" or "Revised" License
959 stars 107 forks source link

Error when building android app #1050

Open walseb opened 1 year ago

walseb commented 1 year ago

Hello!

When I try to build the example app using the steps detailed in the README, I get the following error: Unable to watch the file system for changes net.rubygrapefruit.platform.NativeException: Could not query file systems: could not open mount file (errno 2: No such file or directory)

The .apk is still produced, but some functionality appears to not be working after installing it. For instance the image doesn't render, and after restarting the app nothing appears to render.

Here's the relevant parts of the log:

building '/nix/store/q0jm4q2sqn9sd7ydxml72bgrvyw6h28r-android-app.drv'...
building '/nix/store/sbw9ncbcc5xxnnslxbin9y6si70pn3ks-systems.obsidian.obelisk.examples.minimal.drv'...
unpacking sources
unpacking source archive /nix/store/nm2a6raw2lm1x7kpq221xg1jsm77zi08-android-app
source root is android-app
patching sources
configuring
no configure script, doing nothing
building

Welcome to Gradle 7.0!

Here are the highlights of this release:
 - File system watching enabled by default
 - Support for running with and building Java 16 projects
 - Native support for Apple Silicon processors
 - Dependency catalog feature preview

For more details see https://docs.gradle.org/7.0/release-notes.html

To honour the JVM settings for this build a single-use Daemon process will be forked. See https://docs.gradle.org/7.0/userguide/gradle_daemon.html#sec:disabling_the_daemon.
Daemon will be stopped at the end of the build 

> Configure project :
WARNING:: The option setting 'android.enableBuildCache=false' is deprecated.
The current default is 'true'.
It will be removed in version 7.0 of the Android Gradle plugin.
It does not do anything and AGP is now using Gradle caching.
WARNING:: The option setting 'android.enableR8=false' is deprecated.
It will be removed in version 7.0 of the Android Gradle plugin.
You will no longer be able to disable R8
WARNING:: The option setting 'android.aapt2FromMavenOverride=local_sdk/android-sdk/build-tools/30.0.2/aapt2' is experimental.
WARNING:: DSL element 'useProguard' is obsolete.
It will be removed in version 7.0 of the Android Gradle plugin.
Use 'android.enableR8' in gradle.properties to switch between R8 and Proguard.
WARNING:: DSL element 'useProguard' is obsolete.
It will be removed in version 7.0 of the Android Gradle plugin.
Use 'android.enableR8' in gradle.properties to switch between R8 and Proguard.

> Task :preBuild UP-TO-DATE
> Task :preDebugBuild UP-TO-DATE
> Task :compileDebugAidl NO-SOURCE
> Task :compileDebugRenderscript NO-SOURCE
> Task :generateDebugBuildConfig
> Task :javaPreCompileDebug
> Task :checkDebugAarMetadata
> Task :generateDebugResValues
> Task :generateDebugResources
> Task :createDebugCompatibleScreenManifests
> Task :extractDeepLinksDebug
> Task :mergeDebugResources
> Task :processDebugMainManifest
> Task :processDebugManifest
> Task :mergeDebugNativeDebugMetadata NO-SOURCE
> Task :mergeDebugShaders
> Task :compileDebugShaders NO-SOURCE
> Task :generateDebugAssets UP-TO-DATE
> Task :mergeDebugAssets
> Task :processDebugJavaRes NO-SOURCE
> Task :compressDebugAssets
> Task :checkDebugDuplicateClasses
> Task :mergeDebugJavaResource
> Task :desugarDebugFileDependencies
> Task :mergeExtDexDebug
> Task :mergeDebugJniLibFolders
> Task :mergeDebugNativeLibs
> Task :validateSigningDebug

> Task :stripDebugDebugSymbols
Unable to strip the following libraries, packaging them as they are: libHaskellActivity.so, libffi.so.

> Task :writeDebugAppMetadata
> Task :writeDebugSigningConfigVersions
> Task :processDebugManifestForPackage
> Task :processDebugResources

> Task :compileDebugJavaWithJavac
Note: /build/android-app/src/main/java/org/reflexfrp/reflexdom/MainWidget.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.

> Task :compileDebugSources
> Task :dexBuilderDebug
> Task :mergeDexDebug
> Task :packageDebug
> Task :assembleDebug

BUILD SUCCESSFUL in 36s
28 actionable tasks: 28 executed
Unable to watch the file system for changes
net.rubygrapefruit.platform.NativeException: Could not query file systems: could not open mount file (errno 2: No such file or directory)
        at net.rubygrapefruit.platform.internal.PosixFileSystems.getFileSystems(PosixFileSystems.java:32)
        at org.gradle.internal.watch.vfs.impl.DefaultWatchableFileSystemDetector.detectUnsupportedFileSystems(DefaultWatchableFileSystemDetector.java:64)
        at org.gradle.internal.watch.registry.impl.WatchableHierarchies.removeUnwatchableFileSystems(WatchableHierarchies.java:113)
        at org.gradle.internal.watch.registry.impl.WatchableHierarchies.removeUnwatchableContent(WatchableHierarchies.java:82)
        at org.gradle.internal.watch.registry.impl.NonHierarchicalFileWatcherUpdater.buildFinished(NonHierarchicalFileWatcherUpdater.java:99)
        at org.gradle.internal.watch.registry.impl.DefaultFileWatcherRegistry.buildFinished(DefaultFileWatcherRegistry.java:146)
        at org.gradle.internal.watch.vfs.impl.WatchingVirtualFileSystem$2.lambda$call$0(WatchingVirtualFileSystem.java:199)
        at org.gradle.internal.watch.vfs.impl.WatchingVirtualFileSystem.withWatcherChangeErrorHandling(WatchingVirtualFileSystem.java:320)
        at org.gradle.internal.watch.vfs.impl.WatchingVirtualFileSystem.access$1000(WatchingVirtualFileSystem.java:53)
        at org.gradle.internal.watch.vfs.impl.WatchingVirtualFileSystem$2.call(WatchingVirtualFileSystem.java:199)
        at org.gradle.internal.watch.vfs.impl.WatchingVirtualFileSystem$2.call(WatchingVirtualFileSystem.java:179)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
        at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
        at org.gradle.internal.watch.vfs.impl.WatchingVirtualFileSystem.lambda$beforeBuildFinished$5(WatchingVirtualFileSystem.java:179)
        at org.gradle.internal.vfs.impl.VfsRootReference.update(VfsRootReference.java:40)
        at org.gradle.internal.watch.vfs.impl.WatchingVirtualFileSystem.beforeBuildFinished(WatchingVirtualFileSystem.java:179)
        at org.gradle.tooling.internal.provider.FileSystemWatchingBuildActionRunner.run(FileSystemWatchingBuildActionRunner.java:93)
        at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:41)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:49)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:44)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
        at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
        at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:44)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.lambda$execute$0(InProcessBuildActionExecuter.java:59)
        at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:86)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:58)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
        at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.lambda$execute$0(BuildTreeScopeLifecycleBuildActionExecuter.java:34)
        at org.gradle.internal.buildtree.BuildTreeState.run(BuildTreeState.java:53)
        at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.execute(BuildTreeScopeLifecycleBuildActionExecuter.java:33)
        at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.execute(BuildTreeScopeLifecycleBuildActionExecuter.java:28)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:104)
        at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:55)
        at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:64)
        at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:37)
        at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.lambda$execute$0(SessionScopeLifecycleBuildActionExecuter.java:54)
        at org.gradle.internal.session.BuildSessionState.run(BuildSessionState.java:67)
        at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.execute(SessionScopeLifecycleBuildActionExecuter.java:50)
        at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.execute(SessionScopeLifecycleBuildActionExecuter.java:36)
        at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
        at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
        at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:59)
        at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:31)
        at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:58)
        at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:42)
        at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:47)
        at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:31)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:65)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:50)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:84)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
        at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
        at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
        at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
        at java.lang.Thread.run(Thread.java:748)
installing
post-installation fixup
shrinking RPATHs of ELF executables and libraries in /nix/store/dcgpxaiipd14aq7drzn8mrp2fmvx1iij-systems.obsidian.obelisk.examples.minimal
strip is /nix/store/2cl8h183p6xsnq2vbqv2jlwg4mp1bhgg-binutils-2.35.2/bin/strip
patching script interpreter paths in /nix/store/dcgpxaiipd14aq7drzn8mrp2fmvx1iij-systems.obsidian.obelisk.examples.minimal
checking for references to /build/ in /nix/store/dcgpxaiipd14aq7drzn8mrp2fmvx1iij-systems.obsidian.obelisk.examples.minimal...
building '/nix/store/ip7laivjkkqd303sd6r7fsgzf8kikcwz-android-app.drv'...
/nix/store/zlld39w8r5p3vnszc9fysp93g72bx6rf-android-app
akegalj commented 1 year ago

I have the same problem.

For some reason if I remove prerender line https://github.com/obsidiansystems/obelisk/blob/master/skeleton/frontend/src/Frontend.hs#L42-L45:

      prerender_ blank $ liftJSM $ void
        $ jsg ("window" :: T.Text)
        ^. js ("skeleton_lib" :: T.Text)
        ^. js1 ("log" :: T.Text) ("Hello, World!" :: T.Text)

from my project then deployed application seems to work as expected (picture is rendered normally and aplication starts normally every time). I still see the same failing message as you have posted though.

walseb commented 1 year ago

Thank you so much! I will try that.

As a side note, how well-developed is Android and IOS development using Reflex/Obelisk in your experience?

I have searched, but haven't found much information about it besides the mention in the readme.

I'm slightly concerned by this as I'm thinking of developing applications of medium complexity, things like basic progress tracking apps. It needs features such as storing basic data in local storage.

Thanks!

akegalj commented 1 year ago

As a side note, how well-developed is Android and IOS development using Reflex/Obelisk in your experience?

This is what I am also interested in. My experience with reflex/obelix was toying around last few years and it worked as expected in web. Unfortunatelly I was not successfull with mobile dev until few days ago (and I have never deployed anything on android/ios before so don't know much about developing for this platform). Before that I would try to follow instructions and if it didn't work out from first try I would give up (as I don't know much about mobile dev). Now I actually successfully deployed working scafolding app following their instructions (minus commented out the line above https://github.com/akegalj/obelisk-template/blob/ad01b658efe5d4e968bac1eefc00380c07d6bc86/frontend/src/Frontend.hs#L40 ) and that gives signal to dive deeper.

I have searched, but haven't found much information about it besides the mention in the readme.

Yes, I also couldnt find resources about mobile dev with reflex

I'm slightly concerned by this as I'm thinking of developing applications of medium complexity, things like basic progress tracking apps. It needs features such as storing basic data in local storage.

I think this should be doable but as I am in the process of figurint thigs out I can't say much about is interfacing with js working as expected. I know reflex-dom is using jsaddle as a layer for interfacing with js (and alternitively running code natively in haskell). For example i am trying to implement some game in obelix/reflex so I wanted to listen to requestAnimationFrame from js (https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame). My attempt was https://github.com/akegalj/obelisk-template/commit/ffbf815a847d12f6b1db3764a45a95b57d207a34#diff-0b45c1ec1fb8fa7eab3b4b2209e06c10a3182b0ebc49c6c8fd796ce73fa1b4d6R46-R54 which fires an event every time browser is ready to render a page. How many times event has fired is counted and displayed on page https://github.com/akegalj/obelisk-template/commit/ffbf815a847d12f6b1db3764a45a95b57d207a34#diff-0b45c1ec1fb8fa7eab3b4b2209e06c10a3182b0ebc49c6c8fd796ce73fa1b4d6R35 .

If prerender_ line is active, then everything is working when app is run with ob run (this is using jsaddle to talk to haskell interpreter). It even works ok if I try to compile to js and run locally as explained here https://github.com/obsidiansystems/obelisk#locally . But when I build it and deploy on android using https://github.com/obsidiansystems/obelisk#android it either shows white screen, or partially starts (no image, counter not increasing). I am still trying to figure out what's the reason but it seems prerender_ is the reason and this is the part where I am interfacing with js. (you will probably have to interface with js for localstorage)

Hopefully this will be usefull to someone

walseb commented 1 year ago

Thank you so much for the information!

I tried it just now and after removing the line relating to prerender, the skeleton app works perfectly, although I do eventually need to use prerender.

akegalj commented 1 year ago

Note that I just tried prerender:

prerender_ blank $ el "h1" $ text "this is prerendered"

and it works as expected on android.

As previously tried:

   prerender_ blank $ liftJSM $ void
        $ jsg ("window" :: T.Text)
        ^. js ("skeleton_lib" :: T.Text)
        ^. js1 ("log" :: T.Text) ("Hello, World!" :: T.Text)

this didn't work on android. So it seems something is wront with liftJSM part where I interface with js. I'll try next directly FFI with js instead of using jsaddle as above.

akegalj commented 1 year ago

I managed to get it working on android as well with:

        dpb <- getPostBuild >>= delay 0.1
        prerender_ blank $ performEvent_ $ ffor dpb $ \_ -> liftJSM $ void
          $ jsg ("window" :: T.Text)
            ^. js ("skeleton_lib" :: T.Text)
            ^. js1 ("log" :: T.Text) ("Hello, World!" :: T.Text)

I accidentally found similar answer somewhere on the web so tried it and it works on androd as well now. If signal is not delayed a bit it won't trigger (for unknown reason) - but now this works on both web and android

EDIT: I saw a hint to the answer here https://www.reddit.com/r/reflexfrp/comments/x928ci/comment/inocsqm/?embed_host_url=https%3A%2F%2Fpublish.reddit.com%2Fembed%3Futm_source%3Dembedv2&embed_host_url=https%3A%2F%2Fpublish.reddit.com%2Fembed

EDIT2: This is an example of a working app for web and for android https://github.com/akegalj/obelisk-template/tree/a5836362873b223d555f1ed60e776b5380cef0fe @walseb . Everything works on my side and I think obelix should be good for your use case.You can easily interface with js side (as shown in this example) and everythin seems to be working (including prerenderer)

walseb commented 1 year ago

That's excellent! Thank you so much for finding the solution!

walseb commented 1 year ago

As an update on the original issue, I noticed that I get the following message now before I get the net.rubygrapefruit.platform.NativeException error posted above:

...
/nix/store/cxxsqdgm33r5yjqzw2996yr501djzdqb-ndk-toolchain-binutils/bin/aarch64-unknown-linux-android-ar: libz.so.1: cannot open shared object file: No such file or directory

/nix/store/cxxsqdgm33r5yjqzw2996yr501djzdqb-ndk-toolchain-binutils/bin/aarch64-unknown-linux-android-ranlib: libz.so.1: cannot open shared object file: No such file or directory

/nix/store/cxxsqdgm33r5yjqzw2996yr501djzdqb-ndk-toolchain-binutils/bin/aarch64-unknown-linux-android-ranlib: libz.so.1: cannot open shared object file: No such file or directory

/nix/store/cxxsqdgm33r5yjqzw2996yr501djzdqb-ndk-toolchain-binutils/bin/aarch64-unknown-linux-android-ranlib: libz.so.1: cannot open shared object file: No such file or directory

... (last message repeated hundereds of times)

Preprocessing executable 'libfrontend.so' for frontend-0.1..
Building executable 'libfrontend.so' for frontend-0.1..
[1 of 1] Compiling Main             ( src-bin/main.hs, dist/build/libfrontend.so/libfrontend.so-tmp/Main.o )
....

The app is going along nicely after the fix @akegalj suggested, although I'm surprised by how strange the WebView renderer is. The CSS styling is applied entirely differently from Chromium, Firefox, or a WebKit browser like Surf, even though my CSS passes the W3C validation test. I also had some issues with inline JavaScript.

Has anyone had similar experiences?

akegalj commented 1 year ago

I see the same error on my side as well. I thought it was missing zlib somewhere so I have tried to pull that dependency in with nix-shell -p zlib ... but that didn't help. I didn't invest much time into figuring that one out as it seems it works even when that error is reported. It might be the case that this should be labeled as warning.

About webview... I am still playing around with logic in reflex and some light interfacing with js, so didn't add much css to notice that but here are some relevant discussions:

walseb commented 1 year ago

Thank you for the links!

I spent a few hours fixing the many issues I had with WebView the other day through trial and error.

It seems like it doesn't support inline SVGs, can't display iFrames of local pages by setting the source as a reflex route URL (via askRouteToUrl. When I try it, it works fine in the browser but on android it just says that the resource is not available), and seem to have some built in CSS, unless it's my JavaScript apps that has some custom code for running on android somehow.

Perhaps it would be possible to display an iFrame of a local page on android if inserted the HTML manually, that would mean I need a function that could turn generated DOM into a string (DomBuilder t m => m () -> m (Text)), but I haven't found a function like that.

Other than that I'm happy with Reflex, especially the typed routing that Obelisk provides. But I hope I don't run into similar problems when I finally compile to IOS.

Ante Kegalj @.***> writes:

I see the same error on my side as well. I thought it was missing zlib somewhere so I have tried to pull that dependency in with nix-shell -p zlib ... but that didn't help. I didn't invest much time into figuring that one out as it seems it works even when that error is reported. It might be the case that this should be labeled as warning.

About webview... I am still playing around with logic in reflex and some light interfacing with js, so didn't add much css to notice that but here are some relevant discussions:

-- Reply to this email directly or view it on GitHub: https://github.com/obsidiansystems/obelisk/issues/1050#issuecomment-1756861365 You are receiving this because you were mentioned.

Message ID: @.***>

ali-abrar commented 11 months ago

It seems like it doesn't support inline SVGs, can't display iFrames of local pages by setting the source as a reflex route URL (via askRouteToUrl. When I try it, it works fine in the browser but on android it just says that the resource is not available), and seem to have some built in CSS, unless it's my JavaScript apps that has some custom code for running on android somehow.

SVGs ought to work. Are they working in the browser but not in the webview? Are you setting the namespace properly? It might be worth using a helper library like reflex-dom-svg.

Perhaps it would be possible to display an iFrame of a local page on android if inserted the HTML manually, that would mean I need a function that could turn generated DOM into a string (DomBuilder t m => m () -> m (Text)), but I haven't found a function like that.

You may be looking for renderStatic

walseb commented 11 months ago

Thank you for replying!

SVGs ought to work. Are they working in the browser but not in the webview? Are you setting the namespace properly? It might be worth using a helper library like reflex-dom-svg.

I see, I just entered the SVG manually into the HTML, I will try that package in the future.

You may be looking for renderStatic

Thank you! That might work, I will try it in the future.