🤷‍♂️ RStudio Addin to Search and Copy Emoji
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

163 行
4.5KB

  1. #' Emoji Picker
  2. #'
  3. #' An emoji picker gadget that lets you search and find emoji and insert either
  4. #' the unicode, HTML, or `emo::ji()` versions of the emoji. Built using the
  5. #' [Emoji Button](https://emoji-button.js.org/) JavaScript library.
  6. #'
  7. #' @return A list with the `emoji`, the emoji `name` and the `html` entity.
  8. #'
  9. #' @param gadget If `TRUE` the app is run as a gadget, otherwise it's run as a
  10. #' standalone app.
  11. #'
  12. #' @export
  13. emoji_picker <- function(gadget = TRUE) {
  14. shiny::addResourcePath("eb", system.file("picker", package = "ermoji"))
  15. if (gadget) {
  16. shiny::runGadget(
  17. emoji_picker_ui(),
  18. emoji_picker_server(quick_add = TRUE),
  19. viewer = shiny::dialogViewer("ermoji", width = 375, height = 463)
  20. )
  21. } else {
  22. shiny::shinyApp(emoji_picker_ui(), emoji_picker_server(quick_add = FALSE))
  23. }
  24. }
  25. emoji_picker_ui <- function() {
  26. shiny::fluidPage(
  27. id = "picker-gadget",
  28. class = paste(
  29. if (is_rstudio_dark()) "dark-theme",
  30. get_picker_type()
  31. ),
  32. shiny::div(id = "emoji-picker", style = "width: 100%; min-height: 425; position: relative;"),
  33. shiny::HTML('<div id="alert_bad_emo_ji" class="alert alert-danger" role="alert"><strong style="font-family: monospace">emo</strong> doesn\'t know the emoji <strong id="bad_emo_ji_name"></strong></div>'),
  34. rstudio_style(),
  35. shiny::tags$script(src = "eb/emoji-picker.js", type = "module"),
  36. shiny::tags$head(
  37. shiny::tags$script(src = 'eb/he.js'),
  38. shiny::tags$style('
  39. .emoji-picker__plugin-container { justify-content: space-between; }
  40. .emoji-picker { border-radius: 0 !important; }
  41. #alert_bad_emo_ji {
  42. position: fixed;
  43. top: 0;
  44. left: 0;
  45. right: 0;
  46. z-index: 9999;
  47. border-radius: 0;
  48. transform: translateY(-100px);
  49. transition: transform 0.5s ease-in;
  50. text-align: center;
  51. }
  52. #alert_bad_emo_ji.show-bad-emo-ji {
  53. transform: translateY(0);
  54. }
  55. '
  56. )
  57. )
  58. )
  59. }
  60. is_rstudio_dark <- function() {
  61. if (rstudioapi::hasFun("getThemeInfo")) {
  62. rstudioapi::getThemeInfo()$dark
  63. } else {
  64. FALSE
  65. }
  66. }
  67. rstudio_style <- function() {
  68. if (!rstudioapi::hasFun("getThemeInfo")) {
  69. return(NULL)
  70. }
  71. theme <- rstudioapi::getThemeInfo()
  72. shiny::tags$style(shiny::HTML(paste0(
  73. ".emoji-picker {\n",
  74. if (theme$dark) " --dark-background-color: " else " --background-color: ", theme$background, ";\n",
  75. if (theme$dark) " --dark-text-color: " else " --text-color: ", theme$foreground, ";\n",
  76. "}\n",
  77. "body { background-color: ", theme$background, "; color: ", theme$foreground, ";}\n",
  78. "#picker_type {\n",
  79. " display: flex;\n",
  80. " justify-content: space-between;\n",
  81. " width: 100%;\n",
  82. "}"
  83. )))
  84. }
  85. set_picker_type <- function(style = c("unicode", "html", "emo_ji")) {
  86. if (!rstudioapi::hasFun("setPersistentValue")) {
  87. return()
  88. }
  89. style <- match.arg(style)
  90. rstudioapi::setPersistentValue("ermoji.picker_type", style)
  91. invisible(style)
  92. }
  93. get_picker_type <- function() {
  94. if (!rstudioapi::hasFun("setPersistentValue")) {
  95. return("unicode")
  96. }
  97. style <- rstudioapi::getPersistentValue("ermoji.picker_type")
  98. if (is.null(style)) {
  99. return("unicode")
  100. }
  101. if (!style %in% c("unicode", "html", "emo_ji")) {
  102. return("unicode")
  103. }
  104. style
  105. }
  106. emoji_picker_server <- function(quick_add = TRUE, context = NULL) {
  107. if (is.null(context)) {
  108. context <- rstudioapi::getActiveDocumentContext()
  109. }
  110. function(input, output, session) {
  111. shiny::observeEvent(input$close, {
  112. shiny::stopApp(invisible(input$emoji))
  113. })
  114. shiny::observe({
  115. session$sendCustomMessage('update_picker_type', get_picker_type())
  116. })
  117. shiny::observeEvent(input$picker_type, {
  118. set_picker_type(input$picker_type)
  119. })
  120. shiny::observeEvent(input$emoji, {
  121. emoji <- switch(
  122. input$picker_type,
  123. "unicode" = input$emoji$emoji,
  124. "html" = input$emoji$html,
  125. "emo_ji" = {
  126. tryCatch({
  127. emo::ji(input$emoji$name)
  128. paste0('emo::ji("', input$emoji$name, '")')
  129. },
  130. error = function(e) {
  131. session$sendCustomMessage("bad_emo_ji", input$emoji$name)
  132. message("{emo} doesn't know the emoji ", shQuote(input$emoji$name))
  133. NULL
  134. }
  135. )
  136. }
  137. )
  138. if (!is.null(emoji)) {
  139. rstudioapi::insertText(
  140. location = Map(function(x) x$range, context$selection),
  141. text = emoji,
  142. id = context$id
  143. )
  144. if (isTRUE(quick_add)) {
  145. shiny::stopApp(invisible(input$emoji))
  146. }
  147. }
  148. })
  149. }
  150. }