Correctly handle bookmark options for global.R and app.R

This commit is contained in:
Winston Chang
2016-08-05 16:08:49 -05:00
parent 99b5f92d7a
commit f78bd08440
7 changed files with 52 additions and 53 deletions

39
R/app.R
View File

@@ -76,9 +76,10 @@ shinyApp <- function(ui=NULL, server=NULL, onStart=NULL, options=list(),
server
}
# Add options from enableBookmarking and store appDir so that we can find out
# where we are from within the app.
appConfig <- c(consumeBookmarkOptions(), appDir = getwd())
# Store the appDir and bookmarking-related options, so that we can read them
# from within the app.
shinyOptions(appDir = getwd())
appOptions <- consumeAppOptions()
structure(
list(
@@ -86,7 +87,7 @@ shinyApp <- function(ui=NULL, server=NULL, onStart=NULL, options=list(),
serverFuncSource = serverFuncSource,
onStart = onStart,
options = options,
appConfig = appConfig
appOptions = appOptions
),
class = "shiny.appobj"
)
@@ -105,14 +106,10 @@ shinyAppDir <- function(appDir, options=list()) {
# affected by future changes to the path)
appDir <- normalizePath(appDir, mustWork = TRUE)
# Add options from enableBookmarking and store appDir so that we can find out
# where we are from within the app.
appConfig <- c(consumeBookmarkOptions(), appDir = appDir)
if (file.exists.ci(appDir, "server.R")) {
shinyAppDir_serverR(appDir, options = options, appConfig = appConfig)
shinyAppDir_serverR(appDir, options = options)
} else if (file.exists.ci(appDir, "app.R")) {
shinyAppDir_appR("app.R", appDir, options = options, appConfig = appConfig)
shinyAppDir_appR("app.R", appDir, options = options)
} else {
stop("App dir must contain either app.R or server.R.")
}
@@ -125,17 +122,12 @@ shinyAppFile <- function(appFile, options=list()) {
appFile <- normalizePath(appFile, mustWork = TRUE)
appDir <- dirname(appFile)
# Add options from enableBookmarking and store appDir so that we can find out
# where we are from within the app.
appConfig <- c(consumeBookmarkOptions(), appDir = appDir)
shinyAppDir_appR(basename(appFile), appDir, options = options,
appConfig = appConfig)
shinyAppDir_appR(basename(appFile), appDir, options = options)
}
# This reads in an app dir in the case that there's a server.R (and ui.R/www)
# present, and returns a shiny.appobj.
shinyAppDir_serverR <- function(appDir, options=list(), appConfig = list()) {
shinyAppDir_serverR <- function(appDir, options=list()) {
# Most of the complexity here comes from needing to hot-reload if the .R files
# change on disk, or are created, or are removed.
@@ -195,6 +187,8 @@ shinyAppDir_serverR <- function(appDir, options=list(), appConfig = list()) {
}
}
shinyOptions(appDir = appDir)
oldwd <- NULL
monitorHandle <- NULL
onStart <- function() {
@@ -216,8 +210,7 @@ shinyAppDir_serverR <- function(appDir, options=list(), appConfig = list()) {
serverFuncSource = serverFuncSource,
onStart = onStart,
onEnd = onEnd,
options = options,
appConfig = appConfig
options = options
),
class = "shiny.appobj"
)
@@ -271,8 +264,7 @@ initAutoReloadMonitor <- function(dir) {
# This reads in an app dir for a single-file application (e.g. app.R), and
# returns a shiny.appobj.
shinyAppDir_appR <- function(fileName, appDir, options=list(),
appConfig = list())
shinyAppDir_appR <- function(fileName, appDir, options=list())
{
fullpath <- file.path.ci(appDir, fileName)
@@ -286,6 +278,8 @@ shinyAppDir_appR <- function(fileName, appDir, options=list(),
if (!is.shiny.appobj(result))
stop("app.R did not return a shiny.appobj object.")
unconsumeAppOptions(result$appOptions)
return(result)
}
)
@@ -322,8 +316,7 @@ shinyAppDir_appR <- function(fileName, appDir, options=list(),
serverFuncSource = dynServerFuncSource,
onStart = onStart,
onEnd = onEnd,
options = options,
appConfig = appConfig
options = options
),
class = "shiny.appobj"
)

View File

@@ -10,7 +10,7 @@
saveInterfaceLocal <- function(id, callback) {
# Try to save in app directory
appDir <- getShinyOption("appConfig")$appDir
appDir <- getShinyOption("appDir", default = getwd())
stateDir <- file.path(appDir, "shiny_bookmarks", id)
if (!dirExists(stateDir))
@@ -21,7 +21,7 @@ saveInterfaceLocal <- function(id, callback) {
loadInterfaceLocal <- function(id, callback) {
# Try to load from app directory
appDir <- getShinyOption("appConfig")$appDir
appDir <- getShinyOption("appDir", default = getwd())
stateDir <- file.path(appDir, "shiny_bookmarks", id)
callback(stateDir)

View File

@@ -547,7 +547,7 @@ urlModal <- function(url, title = "Bookmarked application link", subtitle = NULL
#' @param url A URL to show in the modal dialog.
#' @export
showBookmarkUrlModal <- function(url) {
store <- getShinyOption("appConfig")$bookmarkStore
store <- getShinyOption("bookmarkStore", default = "")
if (store == "url") {
subtitle <- "This link stores the current state of this application."
} else if (store == "server") {
@@ -993,21 +993,3 @@ onRestore <- function(fun, session = getDefaultReactiveDomain()) {
onRestored <- function(fun, session = getDefaultReactiveDomain()) {
session$onRestored(fun)
}
# Get shiny options related to bookmarking and put them in a list, reset those
# shiny options, and then return the options list. This should be during the
# creation of a shiny app object, which happens before another option frame is
# added to the options stack (the new option frame is added when the app is
# run). This function "consumes" the options when the shinyApp object is
# created, so the options won't affect another app that is created later.
consumeBookmarkOptions <- function() {
# Get options from enableBookmarking
options <- list(
bookmarkStore = getShinyOption("bookmarkStore")
)
shinyOptions(bookmarkStore = NULL)
options
}

View File

@@ -237,7 +237,7 @@ createAppHandlers <- function(httpHandlers, serverFuncSource) {
# used by an input handler (like the one for "shiny.file"). This
# should only happen once, when the app starts.
if (is.null(shinysession$restoreContext)) {
bookmarkStore <- getShinyOption("appConfig")$bookmarkStore %OR% "disable"
bookmarkStore <- getShinyOption("bookmarkStore", default = "disable")
if (bookmarkStore == "disable") {
# If bookmarking is disabled, use empty context
shinysession$restoreContext <- RestoreContext$new()
@@ -704,10 +704,10 @@ runApp <- function(appDir=getwd(),
appParts <- as.shiny.appobj(appDir)
# Extract appConfig (which is a list) and store it as a shinyOption. (This is
# the only place we have to store settings that are accessible both the UI and
# server portion of the app.)
shinyOptions(appConfig = appParts$appConfig)
# Extract appOptions (which is a list) and store them as shinyOptions, for
# this app. (This is the only place we have to store settings that are
# accessible both the UI and server portion of the app.)
unconsumeAppOptions(appParts$appOptions)
# Set up the onEnd before we call onStart, so that it gets called even if an
# error happens in onStart.

View File

@@ -55,3 +55,29 @@ withLocalOptions <- function(expr) {
expr
}
# Get specific shiny options and put them in a list, reset those shiny options,
# and then return the options list. This should be during the creation of a
# shiny app object, which happens before another option frame is added to the
# options stack (the new option frame is added when the app is run). This
# function "consumes" the options when the shinyApp object is created, so the
# options won't affect another app that is created later.
consumeAppOptions <- function() {
options <- list(
appDir = getwd(),
bookmarkStore = getShinyOption("bookmarkStore")
)
shinyOptions(appDir = NULL, bookmarkStore = NULL)
options
}
# Do the inverse of consumeAppOptions. This should be called once the app is
# started.
unconsumeAppOptions <- function(options) {
if (!is.null(options)) {
do.call(shinyOptions, options)
}
}

View File

@@ -438,9 +438,7 @@ ShinySession <- R6Class(
# for bookmarking to work.
# Get bookmarking config
appConfig <- getShinyOption("appConfig")
store <- appConfig$bookmarkStore %OR% "disable"
store <- getShinyOption("bookmarkStore", default = "disable")
if (store == "disable")
return()

View File

@@ -93,7 +93,7 @@ uiHttpHandler <- function(ui, uiPattern = "^/$") {
}
# Create a restore context using query string
bookmarkStore <- getShinyOption("appConfig")$bookmarkStore %OR% "disable"
bookmarkStore <- getShinyOption("bookmarkStore", default = "disable")
if (bookmarkStore == "disable") {
# If bookmarking is disabled, use empty context
restoreContext <- RestoreContext$new()