library(shiny)
library(shinyMobile)

Mobile preview

Since V0.2.0, shinyMobile has a function to preview your app in a large range of mobile devices: iphone X, iphone 8+, iphone8, iphone 5s, iphone 4s, ipad, Samsung galaxy S5, Samsung galaxy Note 8, … either locally on online:

preview_mobile(appPath = system.file("examples/gallery/app.R", package = "shinyMobile"), device = "iphoneX")
preview_mobile(url = "https://dgranjon.shinyapps.io/miniUI2DemoMd", device = "ipadMini")

The local preview is a 4 steps process:

  • run preview_mobile with appPath
  • Copy the returned code R -e "shiny::runApp('appPath', port = 3838)" in a terminal to launch the app
  • Press enter to run the wrapper app
  • Have fun!

preview_mobile has other options such as color and landscape (to preview in landscape mode).

Pull to Refresh

shinyMobile introduces the pull to refresh feature. It may be used to refresh the page content by pulling from top to bottom. This feature is disable by default but passing pullToRefresh = TRUE in f7Init() will activate it. On the server side, an input, namely input$ptr is TRUE when ptr is refreshed and becomes NULL at the end of the animation. This allows to trigger updates/computations on the server side, for instance:

library(shiny)
library(shinyMobile)

shiny::shinyApp(
  ui = f7Page(
    title = "My app",
    init = f7Init(pullToRefresh = TRUE, theme = "light"),
    f7SingleLayout(
      navbar = f7Navbar(
        title = "Single Layout",
        hairline = FALSE,
        shadow = TRUE
      ),
      toolbar = f7Toolbar(
        position = "bottom",
        f7Link(label = "Link 1", src = "https://www.google.com"),
        f7Link(label = "Link 2", src = "https://www.google.com", external = TRUE)
      ),
      # main content
      f7List(
        lapply(1:3, function(j) {
          f7ListItem(
            letters[j],
            media = f7Icon("alarm_fill"),
            right = "Right Text",
            header = "Header",
            footer = "Footer"
          )
        })
      )
    )
  ),
  server = function(input, output, session) {
    observe(print(input$ptr))

    observeEvent(input$ptr, {
      ptrStatus <- if (input$ptr) "on"
      f7Dialog(
        session = session,
        text = paste('ptr is', ptrStatus),
        type = "alert"
      )
    })
  }
)

Predefined input values

shinyMobile contains a set of useful functions to help you setting the layout as best as possible. It contains a predefined input, namely input$deviceInfo:

shiny::shinyApp(
  ui = f7Page(
    title = "My app",
    f7SingleLayout(
      navbar = f7Navbar(
        title = "Access device info",
        hairline = FALSE,
        shadow = TRUE
      ),
      # main content
      verbatimTextOutput("info")
    )
  ),
  server = function(input, output) {
    output$info <- renderPrint({
      input$deviceInfo
    })
  }
)

The following fields are returned:

  • input$deviceInfo$os, returns a string containing your OS
  • input$deviceInfo$desktop, TRUE or FALSE (if you are running the app on your laptop or desktop)
  • input$deviceInfo$standalone, TRUE or FALSE (standalone, namely whether you access the app like a native app)
  • input$deviceInfo$webview, TRUE or FALSE (webview)
  • input$deviceInfo$electron, TRUE or FALSE (electron)

There are other fields, with less inportance:

  • input$deviceInfo$ios, TRUE or FALSE (if you are running under iOS)
  • input$deviceInfo$android, TRUE or FALSE (if you are running under android)
  • input$deviceInfo$androidChrome, TRUE or FALSE (if you are running under android with Chrome)
  • input$deviceInfo$iphone, TRUE or FALSE (if you have an iphone)
  • input$deviceInfo$ipod, TRUE or FALSE (if you have an ipod)
  • input$deviceInfo$ipad, TRUE or FALSE (if you have an ipad)
  • input$deviceInfo$edge, TRUE or FALSE (if you are using edge)
  • input$deviceInfo$ie, TRUE or FALSE (if you are using Internet Explorer)
  • input$deviceInfo$firefox, TRUE or FALSE (if you are using Firefox)
  • input$deviceInfo$macos, TRUE or FALSE (if you have macOS)
  • input$deviceInfo$windows, TRUE or FALSE (if you have Windows)
  • input$deviceInfo$cordova, TRUE or FALSE (cordova)
  • input$deviceInfo$phonegap, TRUE or FALSE (phonegap)

Example

Below the example displays a card only when the app is on desktop.

shiny::shinyApp(
  ui = f7Page(
    title = "My app",
    f7SingleLayout(
      navbar = f7Navbar(
        title = "Access device info",
        hairline = FALSE,
        shadow = TRUE
      ),
      # main content
      uiOutput("card"),
      textOutput("userAgent"),
    )
  ),
  server = function(input, output) {
    
    output$userAgent <- renderText(input$deviceInfo$desktop)
    
    # generate a card inkly for desktop
    output$card <- renderUI({
      if (input$deviceInfo$desktop) {
        f7Card(
          "This is a simple card with plain text,
          but cards can also contain their own header,
          footer, list view, image, or any other element."
        )
      }
    })
  }
)