ImageLensRenderer.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <template>
  2. <div>
  3. <div
  4. class="
  5. bg-primary
  6. border-b border-dividerLight
  7. flex flex-1
  8. top-lowerSecondaryStickyFold
  9. pl-4
  10. z-10
  11. sticky
  12. items-center
  13. justify-between
  14. "
  15. >
  16. <label class="font-semibold text-secondaryLight">
  17. {{ $t("response.body") }}
  18. </label>
  19. <div class="flex">
  20. <ButtonSecondary
  21. v-if="response.body"
  22. ref="downloadResponse"
  23. v-tippy="{ theme: 'tooltip' }"
  24. :title="$t('action.download_file')"
  25. :svg="downloadIcon"
  26. @click.native="downloadResponse"
  27. />
  28. </div>
  29. </div>
  30. <img
  31. class="border-b border-dividerLight flex max-w-full flex-1"
  32. :src="imageSource"
  33. />
  34. </div>
  35. </template>
  36. <script>
  37. import { defineComponent } from "@nuxtjs/composition-api"
  38. export default defineComponent({
  39. props: {
  40. response: { type: Object, default: () => {} },
  41. },
  42. data() {
  43. return {
  44. imageSource: "",
  45. downloadIcon: "download",
  46. }
  47. },
  48. computed: {
  49. responseType() {
  50. return (
  51. this.response.headers.find(
  52. (h) => h.key.toLowerCase() === "content-type"
  53. ).value || ""
  54. )
  55. .split(";")[0]
  56. .toLowerCase()
  57. },
  58. },
  59. watch: {
  60. response: {
  61. immediate: true,
  62. handler() {
  63. this.imageSource = ""
  64. const buf = this.response.body
  65. const bytes = new Uint8Array(buf)
  66. const blob = new Blob([bytes.buffer])
  67. const reader = new FileReader()
  68. reader.onload = ({ target }) => {
  69. this.imageSource = target.result
  70. }
  71. reader.readAsDataURL(blob)
  72. },
  73. },
  74. },
  75. mounted() {
  76. this.imageSource = ""
  77. const buf = this.response.body
  78. const bytes = new Uint8Array(buf)
  79. const blob = new Blob([bytes.buffer])
  80. const reader = new FileReader()
  81. reader.onload = ({ target }) => {
  82. this.imageSource = target.result
  83. }
  84. reader.readAsDataURL(blob)
  85. },
  86. methods: {
  87. downloadResponse() {
  88. const dataToWrite = this.response.body
  89. const file = new Blob([dataToWrite], { type: this.responseType })
  90. const a = document.createElement("a")
  91. const url = URL.createObjectURL(file)
  92. a.href = url
  93. // TODO get uri from meta
  94. a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}`
  95. document.body.appendChild(a)
  96. a.click()
  97. this.downloadIcon = "check"
  98. this.$toast.success(this.$t("state.download_started"), {
  99. icon: "downloading",
  100. })
  101. setTimeout(() => {
  102. document.body.removeChild(a)
  103. URL.revokeObjectURL(url)
  104. this.downloadIcon = "download"
  105. }, 1000)
  106. },
  107. },
  108. })
  109. </script>