@dative-gpi/foundation-shared-components 1.0.13 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,228 +1,49 @@
1
1
  <template>
2
- <v-img
3
- class="fs-image"
4
- ref="imageRef"
5
- :height="computedHeight"
6
- :width="computedWidth"
7
- :cover="$props.cover"
8
- :src="realSource"
9
- :style="style"
2
+ <FSImageUI
3
+ :blurhash="image"
4
+ :source="source"
10
5
  @error="onError"
11
6
  v-bind="$attrs"
12
- >
13
- <template
14
- #placeholder
15
- >
16
- <FSLoader
17
- v-if="$props.imageId"
18
- class="fs-image-load"
19
- height="100%"
20
- width="100%"
21
- :borderRadius="$props.borderRadius"
22
- />
23
- </template>
24
- <template
25
- #error
26
- >
27
- <FSLoader
28
- v-if="!blurHash"
29
- class="fs-image-load"
30
- height="100%"
31
- width="100%"
32
- :borderRadius="$props.borderRadius"
33
- />
34
- <canvas
35
- ref="canvasRef"
36
- />
37
- </template>
38
- </v-img>
7
+ />
39
8
  </template>
40
9
 
41
10
  <script lang="ts">
42
- import { computed, defineComponent, type PropType, ref, type StyleValue, watch } from "vue";
43
- import { decode, isBlurhashValid } from "blurhash";
11
+ import { computed, defineComponent, type PropType } from "vue";
44
12
 
45
- import { IMAGE_RAW_EXTENSION_URL, IMAGE_RAW_URL } from "@dative-gpi/foundation-shared-services/config/urls";
46
- import { useExtensionJwt, useImageBlurHash } from "@dative-gpi/foundation-shared-services/composables";
47
- import { sizeToVar, varToSize } from "@dative-gpi/foundation-shared-components/utils";
13
+ import { IMAGE_RAW_URL } from "@dative-gpi/foundation-shared-services/config/urls";
48
14
 
49
- import FSLoader from "./FSLoader.vue";
15
+ import { useImage } from "@dative-gpi/foundation-shared-services/composables";
16
+
17
+ import FSImageUI from "./FSImageUI.vue";
50
18
 
51
19
  export default defineComponent({
52
20
  name: "FSImage",
53
21
  components: {
54
- FSLoader
22
+ FSImageUI
55
23
  },
56
24
  props: {
57
- height: {
58
- type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
59
- required: false,
60
- default: null
61
- },
62
- width: {
63
- type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
64
- required: false,
65
- default: null
66
- },
67
25
  imageId: {
68
26
  type: String as PropType<string | null>,
69
27
  required: false,
70
28
  default: null
71
- },
72
- imageB64: {
73
- type: String as PropType<string | null>,
74
- required: false,
75
- default: null
76
- },
77
- source: {
78
- type: String as PropType<string | null>,
79
- required: false,
80
- default: null
81
- },
82
- aspectRatio: {
83
- type: String as PropType<string | null>,
84
- required: false,
85
- default: null
86
- },
87
- borderRadius: {
88
- type: [String, Number],
89
- required: false,
90
- default: "4px"
91
- },
92
- cover: {
93
- type: Boolean,
94
- required: false,
95
- default: true
96
29
  }
97
30
  },
98
31
  setup(props) {
99
- const { fetch: fetchBlurHash, entity: blurHash } = useImageBlurHash();
100
- const { jwt } = useExtensionJwt();
32
+ const { get: getImage, entity: image } = useImage();
101
33
 
102
- const imageRef = ref<HTMLFormElement | null>(null);
103
- const canvasRef = ref<HTMLCanvasElement | null>(null);
104
-
105
- const signatures = ref<{ [key: string]: string }>({
106
- JVBERi0 : "application/pdf",
107
- R0lGODdh : "image/gif",
108
- R0lGODlh : "image/gif",
109
- iVBORw0KGgo: "image/png",
110
- "/9j/" : "image/jpg",
111
- });
112
-
113
- const style = computed((): StyleValue => ({
114
- "--fs-image-border-radius" : sizeToVar(props.borderRadius),
115
- "--fs-image-blurhash-opacity": blurHash.value ? "1" : "0"
116
- }));
117
-
118
- const computedHeight = computed((): string | undefined => {
119
- if (props.height) {
120
- return sizeToVar(props.height);
121
- }
122
- if (props.width) {
123
- if (typeof (props.width) === "string") {
124
- return undefined;
125
- }
126
- if (props.aspectRatio) {
127
- const split = props.aspectRatio.split('/');
128
- if (split.length === 2 && !isNaN(parseFloat(split[0])) && !isNaN(parseFloat(split[1]))) {
129
- return sizeToVar(varToSize(props.width) * (parseFloat(split[1]) / parseFloat(split[0])));
130
- }
131
- }
132
- return sizeToVar(props.width);
133
- }
134
- return undefined;
135
- });
136
-
137
- const computedWidth = computed((): string | undefined => {
138
- if (props.width) {
139
- return sizeToVar(props.width);
140
- }
141
- if (props.height) {
142
- if (typeof (props.height) === "string") {
143
- return undefined;
144
- }
145
- if (props.aspectRatio) {
146
- const split = props.aspectRatio.split('/');
147
- if (split.length === 2 && !isNaN(parseFloat(split[0])) && !isNaN(parseFloat(split[1]))) {
148
- return sizeToVar(varToSize(props.height) * (parseFloat(split[0]) / parseFloat(split[1])));
149
- }
150
- }
151
- return sizeToVar(props.height);
152
- }
153
- return undefined;
154
- });
155
-
156
- const realSource = computed((): string | undefined => {
157
- if (props.imageB64) {
158
- if (imageType.value && imageData.value) {
159
- return `${imageType.value},${imageData.value}`;
160
- }
161
- }
162
- else if (props.imageId) {
163
- if (jwt.value) {
164
- return IMAGE_RAW_EXTENSION_URL(props.imageId, jwt.value);
165
- }
166
- return IMAGE_RAW_URL(props.imageId);
167
- }
168
- else if (props.source) {
169
- return props.source;
170
- }
171
- });
172
-
173
- const imageData = computed((): string | null => {
174
- if (props.imageB64 && props.imageB64.includes(",")) {
175
- return props.imageB64.split(",")[1];
176
- }
177
- return props.imageB64;
178
- });
179
-
180
- const imageType = computed((): string | null => {
181
- if (props.imageB64 && props.imageB64.includes(",")) {
182
- return props.imageB64.split(",")[0];
183
- }
184
- if (props.imageB64) {
185
- for (const s in signatures.value) {
186
- if (props.imageB64.startsWith(s)) {
187
- return `data:${signatures.value[s]};base64`;
188
- }
189
- }
190
- }
191
- return null;
34
+ const source = computed(() => {
35
+ return props.imageId ? IMAGE_RAW_URL(props.imageId) : null;
192
36
  });
193
37
 
194
38
  const onError = (): void => {
195
39
  if (props.imageId) {
196
- fetchBlurHash(props.imageId);
40
+ getImage(props.imageId);
197
41
  }
198
42
  };
199
43
 
200
- watch(() => blurHash.value, () => {
201
- if (canvasRef.value && imageRef.value) {
202
- if (blurHash.value && isBlurhashValid(blurHash.value.blurHash).result) {
203
- const ctx = canvasRef.value.getContext("2d");
204
- if (ctx) {
205
- const width = (imageRef.value as any).$el.clientWidth;
206
- const height = (imageRef.value as any).$el.clientHeight;
207
- const pixels = decode(blurHash.value.blurHash, width, height);
208
- const imageData = ctx.createImageData(width, height);
209
- canvasRef.value.width = width;
210
- canvasRef.value.height = height;
211
- imageData.data.set(pixels);
212
- ctx.putImageData(imageData, 0, 0);
213
- }
214
- }
215
- }
216
- });
217
-
218
44
  return {
219
- computedHeight,
220
- computedWidth,
221
- realSource,
222
- canvasRef,
223
- imageRef,
224
- blurHash,
225
- style,
45
+ source,
46
+ image,
226
47
  onError
227
48
  };
228
49
  }
@@ -0,0 +1,219 @@
1
+ <template>
2
+ <v-img
3
+ class="fs-image"
4
+ ref="imageRef"
5
+ :height="computedHeight"
6
+ :width="computedWidth"
7
+ :cover="$props.cover"
8
+ :src="realSource"
9
+ :style="style"
10
+ @error="$emit('error')"
11
+ v-bind="$attrs"
12
+ >
13
+ <template
14
+ #placeholder
15
+ >
16
+ <FSLoader
17
+ v-if="$props.loading"
18
+ class="fs-image-load"
19
+ height="100%"
20
+ width="100%"
21
+ :borderRadius="$props.borderRadius"
22
+ />
23
+ </template>
24
+ <template
25
+ #error
26
+ >
27
+ <FSLoader
28
+ v-if="!$props.blurHash"
29
+ class="fs-image-load"
30
+ height="100%"
31
+ width="100%"
32
+ :borderRadius="$props.borderRadius"
33
+ />
34
+ <canvas
35
+ ref="canvasRef"
36
+ />
37
+ </template>
38
+ </v-img>
39
+ </template>
40
+
41
+ <script lang="ts">
42
+ import { computed, defineComponent, type PropType, ref, type StyleValue, watch } from "vue";
43
+ import { decode, isBlurhashValid } from "blurhash";
44
+
45
+ import type { ImageDetails } from "@dative-gpi/foundation-shared-domain/models";
46
+
47
+ import { sizeToVar, varToSize } from "@dative-gpi/foundation-shared-components/utils";
48
+
49
+ import FSLoader from "./FSLoader.vue";
50
+
51
+ export default defineComponent({
52
+ name: "FSImageUI",
53
+ components: {
54
+ FSLoader
55
+ },
56
+ props: {
57
+ height: {
58
+ type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
59
+ required: false,
60
+ default: null
61
+ },
62
+ width: {
63
+ type: [Array, String, Number] as PropType<string[] | number[] | string | number | null>,
64
+ required: false,
65
+ default: null
66
+ },
67
+ imageB64: {
68
+ type: String as PropType<string | null>,
69
+ required: false,
70
+ default: null
71
+ },
72
+ source: {
73
+ type: String as PropType<string | null>,
74
+ required: false,
75
+ default: null
76
+ },
77
+ blurHash: {
78
+ type: Object as PropType<ImageDetails | null>,
79
+ required: false,
80
+ default: null
81
+ },
82
+ aspectRatio: {
83
+ type: String as PropType<string | null>,
84
+ required: false,
85
+ default: null
86
+ },
87
+ borderRadius: {
88
+ type: [String, Number],
89
+ required: false,
90
+ default: "4px"
91
+ },
92
+ cover: {
93
+ type: Boolean,
94
+ required: false,
95
+ default: true
96
+ },
97
+ loading: {
98
+ type: Boolean,
99
+ required: false,
100
+ default: false
101
+ }
102
+ },
103
+ setup(props) {
104
+
105
+ const imageRef = ref<HTMLFormElement | null>(null);
106
+ const canvasRef = ref<HTMLCanvasElement | null>(null);
107
+
108
+ const signatures = ref<{ [key: string]: string }>({
109
+ JVBERi0 : "application/pdf",
110
+ R0lGODdh : "image/gif",
111
+ R0lGODlh : "image/gif",
112
+ iVBORw0KGgo: "image/png",
113
+ "/9j/" : "image/jpg",
114
+ });
115
+
116
+ const style = computed((): StyleValue => ({
117
+ "--fs-image-border-radius" : sizeToVar(props.borderRadius),
118
+ "--fs-image-blurhash-opacity": props.blurHash ? "1" : "0"
119
+ }));
120
+
121
+ const computedHeight = computed((): string | undefined => {
122
+ if (props.height) {
123
+ return sizeToVar(props.height);
124
+ }
125
+ if (props.width) {
126
+ if (typeof (props.width) === "string") {
127
+ return undefined;
128
+ }
129
+ if (props.aspectRatio) {
130
+ const split = props.aspectRatio.split('/');
131
+ if (split.length === 2 && !isNaN(parseFloat(split[0])) && !isNaN(parseFloat(split[1]))) {
132
+ return sizeToVar(varToSize(props.width) * (parseFloat(split[1]) / parseFloat(split[0])));
133
+ }
134
+ }
135
+ return sizeToVar(props.width);
136
+ }
137
+ return undefined;
138
+ });
139
+
140
+ const computedWidth = computed((): string | undefined => {
141
+ if (props.width) {
142
+ return sizeToVar(props.width);
143
+ }
144
+ if (props.height) {
145
+ if (typeof (props.height) === "string") {
146
+ return undefined;
147
+ }
148
+ if (props.aspectRatio) {
149
+ const split = props.aspectRatio.split('/');
150
+ if (split.length === 2 && !isNaN(parseFloat(split[0])) && !isNaN(parseFloat(split[1]))) {
151
+ return sizeToVar(varToSize(props.height) * (parseFloat(split[0]) / parseFloat(split[1])));
152
+ }
153
+ }
154
+ return sizeToVar(props.height);
155
+ }
156
+ return undefined;
157
+ });
158
+
159
+ const realSource = computed((): string | undefined => {
160
+ if (props.imageB64) {
161
+ if (imageType.value && imageData.value) {
162
+ return `${imageType.value},${imageData.value}`;
163
+ }
164
+ }
165
+ else if (props.source) {
166
+ return props.source;
167
+ }
168
+ });
169
+
170
+ const imageData = computed((): string | null => {
171
+ if (props.imageB64 && props.imageB64.includes(",")) {
172
+ return props.imageB64.split(",")[1];
173
+ }
174
+ return props.imageB64;
175
+ });
176
+
177
+ const imageType = computed((): string | null => {
178
+ if (props.imageB64 && props.imageB64.includes(",")) {
179
+ return props.imageB64.split(",")[0];
180
+ }
181
+ if (props.imageB64) {
182
+ for (const s in signatures.value) {
183
+ if (props.imageB64.startsWith(s)) {
184
+ return `data:${signatures.value[s]};base64`;
185
+ }
186
+ }
187
+ }
188
+ return null;
189
+ });
190
+
191
+ watch(() => props.blurHash, () => {
192
+ if (canvasRef.value && imageRef.value) {
193
+ if (props.blurHash && isBlurhashValid(props.blurHash.blurHash).result) {
194
+ const ctx = canvasRef.value.getContext("2d");
195
+ if (ctx) {
196
+ const width = (imageRef.value as any).$el.clientWidth;
197
+ const height = (imageRef.value as any).$el.clientHeight;
198
+ const pixels = decode(props.blurHash.blurHash, width, height);
199
+ const imageData = ctx.createImageData(width, height);
200
+ canvasRef.value.width = width;
201
+ canvasRef.value.height = height;
202
+ imageData.data.set(pixels);
203
+ ctx.putImageData(imageData, 0, 0);
204
+ }
205
+ }
206
+ }
207
+ });
208
+
209
+ return {
210
+ computedHeight,
211
+ computedWidth,
212
+ realSource,
213
+ canvasRef,
214
+ imageRef,
215
+ style
216
+ };
217
+ }
218
+ });
219
+ </script>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dative-gpi/foundation-shared-components",
3
3
  "sideEffects": false,
4
- "version": "1.0.13",
4
+ "version": "1.0.14",
5
5
  "description": "",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -10,8 +10,8 @@
10
10
  "author": "",
11
11
  "license": "ISC",
12
12
  "dependencies": {
13
- "@dative-gpi/foundation-shared-domain": "1.0.13",
14
- "@dative-gpi/foundation-shared-services": "1.0.13"
13
+ "@dative-gpi/foundation-shared-domain": "1.0.14",
14
+ "@dative-gpi/foundation-shared-services": "1.0.14"
15
15
  },
16
16
  "peerDependencies": {
17
17
  "@dative-gpi/bones-ui": "^0.0.75",
@@ -35,5 +35,5 @@
35
35
  "sass": "1.71.1",
36
36
  "sass-loader": "13.3.2"
37
37
  },
38
- "gitHead": "b77b0e0975cd193eae758a4af0effa38e5182a9f"
38
+ "gitHead": "e073c5a79111956c451fe05f19c7829246d4784e"
39
39
  }