🤷‍♂️ RStudio Addin to Search and Copy Emoji
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

167 行
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. #bad_emo_ji_name {
  56. white-space: nowrap;
  57. }
  58. '
  59. )
  60. )
  61. )
  62. }
  63. is_rstudio_dark <- function() {
  64. if (rstudioapi::hasFun("getThemeInfo")) {
  65. rstudioapi::getThemeInfo()$dark
  66. } else {
  67. FALSE
  68. }
  69. }
  70. rstudio_style <- function() {
  71. if (!rstudioapi::hasFun("getThemeInfo")) {
  72. return(NULL)
  73. }
  74. theme <- rstudioapi::getThemeInfo()
  75. shiny::tags$style(shiny::HTML(paste0(
  76. ".emoji-picker {\n",
  77. if (theme$dark) " --dark-background-color: " else " --background-color: ", theme$background, ";\n",
  78. if (theme$dark) " --dark-text-color: " else " --text-color: ", theme$foreground, ";\n",
  79. "}\n",
  80. "body { background-color: ", theme$background, "; color: ", theme$foreground, ";}\n",
  81. "#picker_type {\n",
  82. " display: flex;\n",
  83. " justify-content: space-between;\n",
  84. " width: 100%;\n",
  85. "}"
  86. )))
  87. }
  88. set_picker_type <- function(style = c("unicode", "html", "emo_ji")) {
  89. if (!rstudioapi::hasFun("setPersistentValue")) {
  90. return()
  91. }
  92. style <- match.arg(style)
  93. rstudioapi::setPersistentValue("ermoji.picker_type", style)
  94. invisible(style)
  95. }
  96. get_picker_type <- function() {
  97. if (!rstudioapi::hasFun("setPersistentValue")) {
  98. return("unicode")
  99. }
  100. style <- rstudioapi::getPersistentValue("ermoji.picker_type")
  101. if (is.null(style)) {
  102. return("unicode")
  103. }
  104. if (!style %in% c("unicode", "html", "emo_ji")) {
  105. return("unicode")
  106. }
  107. style
  108. }
  109. emoji_picker_server <- function(quick_add = TRUE, context = NULL) {
  110. if (is.null(context)) {
  111. context <- rstudioapi::getActiveDocumentContext()
  112. }
  113. function(input, output, session) {
  114. shiny::observeEvent(input$close, {
  115. shiny::stopApp(invisible(input$emoji))
  116. })
  117. shiny::observe({
  118. session$sendCustomMessage('update_picker_type', get_picker_type())
  119. })
  120. shiny::observeEvent(input$picker_type, {
  121. set_picker_type(input$picker_type)
  122. })
  123. shiny::observeEvent(input$emoji, {
  124. emoji <- switch(
  125. input$picker_type,
  126. "unicode" = input$emoji$emoji,
  127. "html" = input$emoji$html,
  128. "emo_ji" = {
  129. tryCatch({
  130. emo::ji(input$emoji$name)
  131. paste0('emo::ji("', input$emoji$name, '")')
  132. },
  133. error = function(e) {
  134. session$sendCustomMessage("bad_emo_ji", input$emoji$name)
  135. message("{emo} doesn't know the emoji ", shQuote(input$emoji$name))
  136. NULL
  137. }
  138. )
  139. }
  140. )
  141. if (!is.null(emoji)) {
  142. rstudioapi::insertText(
  143. location = Map(function(x) x$range, context$selection),
  144. text = emoji,
  145. id = context$id
  146. )
  147. if (isTRUE(quick_add)) {
  148. shiny::stopApp(invisible(input$emoji))
  149. }
  150. }
  151. })
  152. }
  153. }