--- title: "shinyMobile Tools" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{shinyMobile Tools} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ## 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: ```{r, eval = FALSE} library(shiny) library(shinyMobile) 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 disabled by default but passing `pullToRefresh = TRUE` in `f7Page` options 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: ```{r, eval=FALSE} shinyApp( ui = f7Page( title = "My app", options = list(pullToRefresh = TRUE), f7SingleLayout( navbar = f7Navbar( title = "Single Layout", hairline = FALSE, shadow = TRUE ), toolbar = f7Toolbar( position = "bottom", f7Link(label = "Link 1", href = "https://www.google.com"), f7Link(label = "Link 2", href = "https://www.google.com") ), # 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( 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. ### Informations about your current device #### Description `{shinyMobile}` has a predefined input, namely **input$deviceInfo**: ```{r, eval = FALSE} 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) #### Usecase Below the example displays a card only when the app is on desktop. ```{r, eval = FALSE} 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 only 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." ) } }) } ) ``` ### Informations about Shiny inputs `{shinyMobile}` has `input$lastInputChanged` which returns the name, value and type of the last changed input, see below: ```{r, eval = FALSE} shinyApp( ui = f7Page( title = "My app", f7SingleLayout( navbar = f7Navbar( title = "Single Layout", hairline = FALSE, shadow = TRUE ), toolbar = f7Toolbar( position = "bottom", f7Link(label = "Link 1", href = "https://www.google.com"), f7Link(label = "Link 2", href = "https://www.google.com") ), # main content f7Card(verbatimTextOutput("infos")), f7Card( f7Text(inputId = "text", label = "Text"), f7Slider(inputId = "range1", label = "Range", min = 0, max = 2, value = 1, step = 0.1), f7Stepper(inputId = "stepper1", label = "Stepper", min = 0, max = 10, value = 5), verbatimTextOutput("lastChanged") ) ) ), server = function(input, output) { output$infos <- renderPrint(input$shinyInfo) output$lastChanged <- renderPrint(input$lastInputChanged) } ) ``` This is convenient since usually, there is no shortcut to get the last changed value and this needs to be done server side in shiny. Soon there will be a way to compare initial input values (frozen) to current input values and get a diff. ### Other information `input$shinyInfo` gives the current workerId (for shinyapps.io, shiny server pro, rstudio connect), the unique sessionId (equal to session$token on the server side).