---
title: "Cookbook"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Cookbook}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

```{r setup}
# Build a valid IPC message envelope
msg <- RDesk::rdesk_message("get_data", list(filter = "cyl == 6"))
str(msg)
```

Copy-paste recipes for the most common RDesk patterns.

## Load a CSV with a file dialog

```r
app$on_message("load_file", function(payload) {
  path <- app$dialog_open(
    title   = "Open CSV",
    filters = list("CSV files" = "*.csv")
  )
  if (is.null(path)) return(invisible(NULL))

  df <- utils::read.csv(path, stringsAsFactors = FALSE)
  app$send("file_loaded", list(
    rows     = nrow(df),
    cols     = names(df),
    filename = basename(path)
  ))
})
```

## Render a ggplot2 chart

![RDesk Explorer Boxplot](../man/figures/explorer_boxplot.png)
![RDesk Models Page](../man/figures/models.png)

```r
app$on_message("get_chart", async(function(payload) {
  p <- ggplot2::ggplot(mtcars,
         ggplot2::aes(wt, mpg, colour = factor(cyl))) +
       ggplot2::geom_point(size = 3) +
       ggplot2::theme_minimal()

  list(chart = rdesk_plot_to_base64(p))
}, app = app))
```

```javascript
rdesk.on("get_chart_result", function(data) {
  document.getElementById("chart").src =
    "data:image/png;base64," + data.chart;
});
```

## Show a toast notification

```r
app$toast("File saved successfully", type = "success")
app$toast("Could not connect",       type = "error")
app$toast("Update available",        type = "info")
```

## Save a file with a dialog

```r
app$on_message("export_csv", function(payload) {
  path <- app$dialog_save(
    title        = "Save CSV",
    filters      = list("CSV files" = "*.csv"),
    default_name = "export.csv"
  )
  if (is.null(path)) return(invisible(NULL))

  write.csv(mtcars, path, row.names = FALSE)
  app$toast(paste("Saved to", basename(path)), type = "success")
})
```

## Run a slow computation without freezing the UI

```r
app$on_message("run_analysis", async(function(payload) {
  result <- slow_function(payload$data)
  list(
    summary = as.list(summary(result)),
    n       = length(result)
  )
}, app = app, loading_message = "Analysing..."))
```

## Add a native menu

```r
app$on_ready(function() {
  app$set_menu(list(
    File = list(
      "Open..."   = function() app$send("load_file", list()),
      "Export..." = function() app$send("export_csv", list()),
      "---",
      "Exit"      = app$quit
    ),
    View = list(
      "Refresh"   = function() app$send("refresh", list()),
      "Dark mode" = function() app$send("toggle_theme", list())
    ),
    Help = list(
      "About"     = function() {
        app$toast("MyApp v1.0.0 -- built with RDesk", type = "info")
      }
    )
  ))
})
```

## Check for and install updates

```r
# In app.R, before app$run()
rdesk_auto_update(
  current_version = "1.0.0",
  version_url     = "https://yourserver.com/latest.txt",
  download_url    = "https://yourserver.com/MyApp-setup.exe",
  app             = app
)
```

Host a plain text file at `version_url` containing only the latest
version string, e.g. `1.1.0`. RDesk checks it silently on launch
and installs the update if a newer version is available.

## Send data when the app starts

```r
app$on_ready(function() {
  df <- load_initial_data()
  app$send("data_ready", list(
    rows = lapply(seq_len(nrow(df)), function(i) as.list(df[i,])),
    cols = names(df),
    n    = nrow(df)
  ))
})
```

## Handle errors gracefully

```r
app$on_message("risky_operation", async(function(payload) {
  tryCatch({
    result <- operation_that_might_fail(payload)
    list(success = TRUE, data = result)
  }, error = function(e) {
    list(success = FALSE, error = e$message)
  })
}, app = app))
```

```javascript
rdesk.on("risky_operation_result", function(data) {
  if (!data.success) {
    showError(data.error);
    return;
  }
  renderResult(data.data);
});
```

## Detect if running as a built app vs dev mode

```r
if (rdesk_is_bundle()) {
  # Running as distributed exe
  data_path <- file.path(getwd(), "data", "config.json")
} else {
  # Running in development via source("app.R")
  data_path <- file.path(app_dir, "data", "config.json")
}
```
