Skip to content

Commit 72e852c

Browse files
Supported inputs: "non_sticky_message", "sticky_message", and "message"
The latter is an alias for the former two [#109]
1 parent be35fd3 commit 72e852c

File tree

6 files changed

+94
-52
lines changed

6 files changed

+94
-52
lines changed

NEWS

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: progressr
22
==================
33

4-
Version: 0.7.0-9001 [2021-05-16]
4+
Version: 0.7.0-9001 [2021-05-20]
55

66
SIGNIFICANT CHANGES:
77

@@ -16,13 +16,19 @@ SIGNIFICANT CHANGES:
1616
them when the package is loaded, it decrease the overhead in functions,
1717
and it clarifies that options can be changed at runtime whereas environment
1818
variables should only be set at startup.
19+
20+
* When using withProgressShiny(), progression messages now updates the
21+
'detail' component of the Shiny progress panel. Previously, it updated
22+
the 'message' component. This can be configured via new 'inputs' argument.
1923

2024
NEW FEATURES:
2125

22-
* withProgressShiny() gained argument 'map', which can be used to control
23-
whether the progression message should update the Shiny 'message' or the
24-
Shiny 'detail' component in the Shiny progress panel, e.g.
25-
map = c(message = "message") or map = c(message = "detail").
26+
* withProgressShiny() gained argument 'inputs', which can be used to control
27+
whether or not Shiny progress components 'message' and 'detail' should be
28+
updated based on the progression message, e.g.
29+
inputs = list(message = "sticky_message", detail = "message") will cause
30+
progression messages to update the 'detail' component and sticky ones
31+
to update both.
2632

2733
* Now supporting zero-length progressors, e.g. p <- progressor(along = x)
2834
where length(x) == 0.
@@ -35,7 +41,7 @@ BETA FEATURES:
3541
* As an alternative to specifying the relative amount of progress, say,
3642
p(amount = 2), it is now possible to also specify the absolute amount of
3743
progress made this far, e.g. p(step = 42). Argument 'amount' has not
38-
effect when argument 'step' is specfied. WARNING: Argument 'step' should
44+
effect when argument 'step' is specified. WARNING: Argument 'step' should
3945
only be used when in full control of the order when this progression
4046
condition is signaled. For example, it must not be signaled as one of many
4147
parallel progress updates signaled concurrently, because we cannot guarantee

R/handler_shiny.R

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
#'
55
#' @inheritParams make_progression_handler
66
#'
7-
#' @param map Specifies whether the progression message should be mapped
8-
#' to the 'message' and 'detail' element in the Shiny progress panel.
9-
#' This argument should be a named character string with value `"message"`
10-
#' or `"detail"` and where the name should be `message`, e.g.
11-
#' `map = c(message = "message")` or `map = c(message = "detail")`.
7+
#' @param inputs (named list) Specifies from what sources the Shiny progress
8+
#' elements 'message' and 'detail' should be updated. Valid sources are
9+
#' `"message"`, `"sticky_message"` and `"non_sticky_message"`, where
10+
#' `"message"` is short for `c("non_sticky_message", "sticky_message")`. For
11+
#' example, `inputs = list(message = "sticky-message", detail = "message")`
12+
#' will update the Shiny 'message' component from sticky messages only,
13+
#' whereas the 'detail' component is updated using any message.
1214
#'
1315
#' @param \ldots Additional arguments passed to [make_progression_handler()].
1416
#'
@@ -27,36 +29,46 @@
2729
#'
2830
#' @keywords internal
2931
#' @export
30-
handler_shiny <- function(intrusiveness = getOption("progressr.intrusiveness.gui", 1), target = "gui", map = c(message = "message"), ...) {
32+
handler_shiny <- function(intrusiveness = getOption("progressr.intrusiveness.gui", 1), target = "gui", inputs = list(message = NULL, detail = "message"), ...) {
3133
stop_if_not(
32-
is.character(map), all(map %in% c("message", "detail")),
33-
!is.null(names(map)), all(names(map) %in% c("message"))
34+
is.list(inputs),
35+
!is.null(names(inputs)),
36+
all(names(inputs) %in% c("message", "detail")),
37+
all(vapply(inputs, FUN = function(x) {
38+
if (is.null(x)) return(TRUE)
39+
if (!is.character(x)) return(FALSE)
40+
x %in% c("message", "non_sticky_message", "sticky_message")
41+
}, FUN.VALUE = FALSE))
3442
)
3543

44+
## Expand 'message' => c("non_sticky_message", "sticky_message")
45+
for (name in names(inputs)) {
46+
input <- inputs[[name]]
47+
if ("message" %in% input) {
48+
input <- setdiff(input, "message")
49+
input <- c(input, "non_sticky_message", "sticky_message")
50+
}
51+
inputs[[name]] <- unique(input)
52+
}
53+
3654
## Default: The progression message updates Shiny 'message'
3755
map_args <- function(state, progression) {
38-
message <- state$message
56+
message <- progression$message
3957
if (is.null(message)) return(list())
40-
if (inherits(progression, "sticky")) {
41-
list(detail = message)
42-
} else {
43-
list(message = message)
44-
}
45-
}
4658

47-
## Should progress message update another Shiny field?
48-
if ("message" %in% names(map)) {
49-
if (map["message"] == "detail") {
50-
map_args <- function(state, progression) {
51-
message <- state$message
52-
if (is.null(message)) return(list())
53-
if (inherits(progression, "sticky")) {
54-
list(message = message)
55-
} else {
56-
list(detail = message)
57-
}
58-
}
59+
## Update Shiny 'message' and 'detail'?
60+
args <- list()
61+
for (target in c("message", "detail")) {
62+
if (inherits(progression, "sticky")) {
63+
if ("sticky_message" %in% inputs[[target]])
64+
args[[target]] <- message
65+
} else {
66+
if ("non_sticky_message" %in% inputs[[target]])
67+
args[[target]] <- message
68+
}
5969
}
70+
71+
args
6072
}
6173

6274
reporter <- local({

R/withProgressShiny.R

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,47 @@
1717
#' [handler_shiny()] **progressr** handler internally to report on updates.
1818
#'
1919
#' @export
20-
withProgressShiny <- function(expr, ..., message = NULL, detail = NULL, map = c(message = "message"), env = parent.frame(), quoted = FALSE, handlers = c(shiny = handler_shiny, progressr::handlers(default = NULL))) {
20+
withProgressShiny <- function(expr, ..., message = NULL, detail = NULL, inputs = list(message = NULL, detail = "message"), env = parent.frame(), quoted = FALSE, handlers = c(shiny = handler_shiny, progressr::handlers(default = NULL))) {
2121
if (!quoted) expr <- substitute(expr)
2222

23+
stop_if_not(is.list(inputs), all(names(inputs) %in% c("message", "detail")))
24+
2325
stop_if_not("shiny" %in% names(handlers))
2426
if (sum(names(handlers) == "shiny") > 1) {
2527
warning("Detected a 'shiny' handler set via progressr::handlers()")
2628
}
2729

30+
## Optional, configure 'inputs' from attribute 'input' of arguments
31+
## 'message' and 'detail', if and only if that attribute is available.
32+
args <- list(message = message, detail = detail)
33+
for (name in names(args)) {
34+
input <- unique(attr(args[[name]], "input"))
35+
if (is.null(input)) next
36+
unknown <- setdiff(input, c("message", "sticky_message", "non_sticky_message"))
37+
if (length(unknown) > 0) {
38+
stop(sprintf("Unknown value of attribute %s on argument %s: %s",
39+
sQuote("input"), sQuote(name), commaq(unknown)))
40+
}
41+
inputs[[name]] <- input
42+
}
43+
2844
stop_if_not(
29-
is.character(map), all(map %in% c("message", "detail")),
30-
!is.null(names(map)), all(names(map) %in% c("message"))
45+
is.list(inputs),
46+
!is.null(names(inputs)),
47+
all(names(inputs) %in% c("message", "detail")),
48+
all(vapply(inputs, FUN = function(x) {
49+
if (is.null(x)) return(TRUE)
50+
if (!is.character(x)) return(FALSE)
51+
x %in% c("message", "non_sticky_message", "sticky_message")
52+
}, FUN.VALUE = FALSE))
3153
)
3254

3355
## Customize the shiny 'message' target?
3456
if (is.function(handlers$shiny) &&
3557
!inherits(handlers$shiny, "progression_handler")) {
3658
tweaked_handler_shiny <- handlers$shiny
37-
if (!identical(map, formals(tweaked_handler_shiny)$map)) {
38-
formals(tweaked_handler_shiny)$map <- map
59+
if (!identical(inputs, formals(tweaked_handler_shiny)$inputs)) {
60+
formals(tweaked_handler_shiny)$inputs <- inputs
3961
handlers$shiny <- tweaked_handler_shiny
4062
}
4163
}

incl/withProgressShiny.R

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ app <- shinyApp(
1111
X <- 1:15
1212
withProgressShiny(message = "Calculation in progress",
1313
detail = "Starting ...",
14-
map = c(message = "detail"),
1514
value = 0, {
1615
p <- progressor(along = X)
1716
y <- lapply(X, FUN=function(x) {

man/handler_shiny.Rd

Lines changed: 8 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/withProgressShiny.Rd

Lines changed: 8 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)