rshinymessageboxgmailr

Shiny feedback to user once e-mail is sent


I need some shiny wisdom, please. Below code works well in shiny server part; it sends an e-mail when user clicks actionButton("mailButton", "e-mail!") in ui part with a PDF report attached via gmailr. The only problem I have is that there is no feedback to the user whether e-mail has been sent. What I would ideally like to have is a message box mid-screen (maybe with overlay). When e-mail is sent it would tell so to the user who pressed the input$mailButton (and maybe the box would disappear with timeout of 15 seconds). This event approximately should correspond to the point of print("message sent") in the below code (this does get printed to the terminal). What would be a good way to do display user a confirmation that e-mail has indeed been sent and block inputs while sending is going on (which usually takes 4 seconds)?

    # email sender ------------------------------------------------------------
     observeEvent(input$mailButton,{
        isolate( {
            
            library(gmailr)
            
            params <- list(startDate = min(dashData()$mdate), 
                           endDate = max(dashData()$mdate), 
                           dfSurvey = dashData(), 
                           onePerson = input$checkOnePt, 
                           onePersonNumber = input$patientNumber, 
                           showAvg = input$checkAvgLine, 
                           alphaAvg = alphaAvg)            
            
            toAddress <- input$emailAddr
            
            if (input$checkOnePt) {
                mailSubject <- paste("Feedback graph for ", input$patientNumber)
                mailText <- paste("Hello, please see the attached report from us for ",input$patientNumber)
            } else {
                mailSubject <- paste("Feedback graph")
                mailText <- paste("Hello, please see the attached report from us.")
            }
            
                
            library(rmarkdown)
            out <- render('hwu-weekly.Rmd',
                              params = params,
                              pdf_document(),
                              envir = new.env(parent = globalenv())
                )

            
            gm_auth_configure(path  = "credentials.json")
            gm_auth(email = TRUE, cache = ".secret")
            
            email <- gm_mime() %>%
                gm_to(toAddress) %>%
                gm_from("user.us@gmail.com") %>%
                gm_subject(mailSubject) %>%
                gm_text_body( mailText ) %>% 
                gm_attach_file(filename = "hwu-weekly.pdf")
            
            gm_send_message(email)

            print("message sent")
        })
    
    })


Solution

  • This seems like a good use case of withProgress() and showNotification():

    library(shiny)
    
    ui <- fluidPage(
      actionButton('go', 'go')
    )
    
    server <- function(input, output, session) {
      observeEvent(input$go, {
        withProgress(message = "Please Wait", {
          Sys.sleep(1)
          setProgress(0.25, detail = "1 Sec")
          Sys.sleep(1)
          setProgress(0.5, detail = "2 Sec")
          Sys.sleep(1)
          setProgress(0.75, detail = "3 Sec")
          Sys.sleep(1)
          setProgress(1, detail = "4 Sec")
       })
        showNotification("Your message here", type = "message", duration = 15)
      })
    }
    
    shinyApp(ui, server)
    

    Links to shiny documents for notifications and progress indicators.

    You could also use a modal for something more obvious that the user would have to close before moving on:

    library(shiny)
    
    ui <- fluidPage(
      actionButton('go', 'go')
    )
    
    server <- function(input, output, session) {
      observeEvent(input$go, {
        withProgress(message = "Please Wait", {
          Sys.sleep(1)
          setProgress(0.25, detail = "1 Sec")
          Sys.sleep(1)
          setProgress(0.5, detail = "2 Sec")
          Sys.sleep(1)
          setProgress(0.75, detail = "3 Sec")
          Sys.sleep(1)
          setProgress(1, detail = "4 Sec")
       })
        showModal(modalDialog(title = 'Message', h2("Content Here")))
      })
    }
    
    shinyApp(ui, server)