ImageLensRenderer.vue 2.6 KB

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