@umituz/react-native-image 1.1.0 → 1.1.2

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,393 +1,22 @@
1
1
  /**
2
- * Image Domain - useImage Hook
3
- *
4
- * React hook for image manipulation operations.
5
- * Provides image resizing, cropping, rotating, and format conversion.
2
+ * useImage Hook
3
+ *
4
+ * Aggregator hook that combines transformation and conversion capabilities.
5
+ * Kept simple and modular.
6
6
  */
7
7
 
8
- import { useState, useCallback } from 'react';
9
- import { ImageService } from '../../infrastructure/services/ImageService';
10
- import type {
11
- ImageManipulateAction,
12
- ImageSaveOptions,
13
- ImageManipulationResult,
14
- SaveFormat,
15
- } from '../../domain/entities/Image';
8
+ import { useImageTransform } from './useImageTransform';
9
+ import { useImageConversion } from './useImageConversion';
16
10
 
17
- /**
18
- * useImage hook for image manipulation
19
- *
20
- * USAGE:
21
- * ```typescript
22
- * const { resize, crop, rotate, compress, isProcessing } = useImage();
23
- *
24
- * // Resize image
25
- * const resized = await resize(imageUri, 800, 600);
26
- *
27
- * // Crop image
28
- * const cropped = await crop(imageUri, { originX: 0, originY: 0, width: 500, height: 500 });
29
- *
30
- * // Compress image
31
- * const compressed = await compress(imageUri, 0.7);
32
- * ```
33
- */
34
11
  export const useImage = () => {
35
- const [isProcessing, setIsProcessing] = useState(false);
36
- const [error, setError] = useState<string | null>(null);
37
-
38
- /**
39
- * Resize image
40
- */
41
- const resize = useCallback(
42
- async (
43
- uri: string,
44
- width?: number,
45
- height?: number,
46
- options?: ImageSaveOptions
47
- ): Promise<ImageManipulationResult | null> => {
48
- setIsProcessing(true);
49
- setError(null);
50
-
51
- try {
52
- const result = await ImageService.resize(uri, width, height, options);
53
-
54
- if (!result) {
55
- setError('Failed to resize image');
56
- }
57
-
58
- return result;
59
- } catch (err) {
60
- const errorMessage = err instanceof Error ? err.message : 'Failed to resize image';
61
- setError(errorMessage);
62
- return null;
63
- } finally {
64
- setIsProcessing(false);
65
- }
66
- },
67
- []
68
- );
69
-
70
- /**
71
- * Crop image
72
- */
73
- const crop = useCallback(
74
- async (
75
- uri: string,
76
- cropArea: { originX: number; originY: number; width: number; height: number },
77
- options?: ImageSaveOptions
78
- ): Promise<ImageManipulationResult | null> => {
79
- setIsProcessing(true);
80
- setError(null);
81
-
82
- try {
83
- const result = await ImageService.crop(uri, cropArea, options);
84
-
85
- if (!result) {
86
- setError('Failed to crop image');
87
- }
88
-
89
- return result;
90
- } catch (err) {
91
- const errorMessage = err instanceof Error ? err.message : 'Failed to crop image';
92
- setError(errorMessage);
93
- return null;
94
- } finally {
95
- setIsProcessing(false);
96
- }
97
- },
98
- []
99
- );
100
-
101
- /**
102
- * Rotate image
103
- */
104
- const rotate = useCallback(
105
- async (
106
- uri: string,
107
- degrees: number,
108
- options?: ImageSaveOptions
109
- ): Promise<ImageManipulationResult | null> => {
110
- setIsProcessing(true);
111
- setError(null);
112
-
113
- try {
114
- const result = await ImageService.rotate(uri, degrees, options);
115
-
116
- if (!result) {
117
- setError('Failed to rotate image');
118
- }
119
-
120
- return result;
121
- } catch (err) {
122
- const errorMessage = err instanceof Error ? err.message : 'Failed to rotate image';
123
- setError(errorMessage);
124
- return null;
125
- } finally {
126
- setIsProcessing(false);
127
- }
128
- },
129
- []
130
- );
131
-
132
- /**
133
- * Flip image
134
- */
135
- const flip = useCallback(
136
- async (
137
- uri: string,
138
- flipOptions: { horizontal?: boolean; vertical?: boolean },
139
- saveOptions?: ImageSaveOptions
140
- ): Promise<ImageManipulationResult | null> => {
141
- setIsProcessing(true);
142
- setError(null);
143
-
144
- try {
145
- const result = await ImageService.flip(uri, flipOptions, saveOptions);
146
-
147
- if (!result) {
148
- setError('Failed to flip image');
149
- }
150
-
151
- return result;
152
- } catch (err) {
153
- const errorMessage = err instanceof Error ? err.message : 'Failed to flip image';
154
- setError(errorMessage);
155
- return null;
156
- } finally {
157
- setIsProcessing(false);
158
- }
159
- },
160
- []
161
- );
162
-
163
- /**
164
- * Perform multiple manipulations
165
- */
166
- const manipulate = useCallback(
167
- async (
168
- uri: string,
169
- action: ImageManipulateAction,
170
- options?: ImageSaveOptions
171
- ): Promise<ImageManipulationResult | null> => {
172
- setIsProcessing(true);
173
- setError(null);
174
-
175
- try {
176
- const result = await ImageService.manipulate(uri, action, options);
177
-
178
- if (!result) {
179
- setError('Failed to manipulate image');
180
- }
181
-
182
- return result;
183
- } catch (err) {
184
- const errorMessage = err instanceof Error ? err.message : 'Failed to manipulate image';
185
- setError(errorMessage);
186
- return null;
187
- } finally {
188
- setIsProcessing(false);
189
- }
190
- },
191
- []
192
- );
193
-
194
- /**
195
- * Compress image
196
- */
197
- const compress = useCallback(
198
- async (uri: string, quality: number = 0.8): Promise<ImageManipulationResult | null> => {
199
- setIsProcessing(true);
200
- setError(null);
201
-
202
- try {
203
- const result = await ImageService.compress(uri, quality);
204
-
205
- if (!result) {
206
- setError('Failed to compress image');
207
- }
208
-
209
- return result;
210
- } catch (err) {
211
- const errorMessage = err instanceof Error ? err.message : 'Failed to compress image';
212
- setError(errorMessage);
213
- return null;
214
- } finally {
215
- setIsProcessing(false);
216
- }
217
- },
218
- []
219
- );
220
-
221
- /**
222
- * Resize to fit within max dimensions
223
- */
224
- const resizeToFit = useCallback(
225
- async (
226
- uri: string,
227
- maxWidth: number,
228
- maxHeight: number,
229
- options?: ImageSaveOptions
230
- ): Promise<ImageManipulationResult | null> => {
231
- setIsProcessing(true);
232
- setError(null);
233
-
234
- try {
235
- const result = await ImageService.resizeToFit(uri, maxWidth, maxHeight, options);
236
-
237
- if (!result) {
238
- setError('Failed to resize image to fit');
239
- }
240
-
241
- return result;
242
- } catch (err) {
243
- const errorMessage = err instanceof Error ? err.message : 'Failed to resize image to fit';
244
- setError(errorMessage);
245
- return null;
246
- } finally {
247
- setIsProcessing(false);
248
- }
249
- },
250
- []
251
- );
252
-
253
- /**
254
- * Create thumbnail
255
- */
256
- const createThumbnail = useCallback(
257
- async (
258
- uri: string,
259
- size: number = 200,
260
- options?: ImageSaveOptions
261
- ): Promise<ImageManipulationResult | null> => {
262
- setIsProcessing(true);
263
- setError(null);
264
-
265
- try {
266
- const result = await ImageService.createThumbnail(uri, size, options);
267
-
268
- if (!result) {
269
- setError('Failed to create thumbnail');
270
- }
271
-
272
- return result;
273
- } catch (err) {
274
- const errorMessage = err instanceof Error ? err.message : 'Failed to create thumbnail';
275
- setError(errorMessage);
276
- return null;
277
- } finally {
278
- setIsProcessing(false);
279
- }
280
- },
281
- []
282
- );
283
-
284
- /**
285
- * Crop to square
286
- */
287
- const cropToSquare = useCallback(
288
- async (
289
- uri: string,
290
- width: number,
291
- height: number,
292
- options?: ImageSaveOptions
293
- ): Promise<ImageManipulationResult | null> => {
294
- setIsProcessing(true);
295
- setError(null);
296
-
297
- try {
298
- const result = await ImageService.cropToSquare(uri, width, height, options);
299
-
300
- if (!result) {
301
- setError('Failed to crop to square');
302
- }
303
-
304
- return result;
305
- } catch (err) {
306
- const errorMessage = err instanceof Error ? err.message : 'Failed to crop to square';
307
- setError(errorMessage);
308
- return null;
309
- } finally {
310
- setIsProcessing(false);
311
- }
312
- },
313
- []
314
- );
315
-
316
- /**
317
- * Convert image format
318
- */
319
- const convertFormat = useCallback(
320
- async (
321
- uri: string,
322
- format: SaveFormat,
323
- quality?: number
324
- ): Promise<ImageManipulationResult | null> => {
325
- setIsProcessing(true);
326
- setError(null);
327
-
328
- try {
329
- const result = await ImageService.convertFormat(uri, format, quality);
330
-
331
- if (!result) {
332
- setError('Failed to convert image format');
333
- }
334
-
335
- return result;
336
- } catch (err) {
337
- const errorMessage = err instanceof Error ? err.message : 'Failed to convert image format';
338
- setError(errorMessage);
339
- return null;
340
- } finally {
341
- setIsProcessing(false);
342
- }
343
- },
344
- []
345
- );
346
-
347
- /**
348
- * Save image to device
349
- */
350
- const saveImage = useCallback(
351
- async (uri: string, filename?: string): Promise<string | null> => {
352
- setIsProcessing(true);
353
- setError(null);
354
-
355
- try {
356
- const savedUri = await ImageService.saveImage(uri, filename);
357
-
358
- if (!savedUri) {
359
- setError('Failed to save image');
360
- }
361
-
362
- return savedUri;
363
- } catch (err) {
364
- const errorMessage = err instanceof Error ? err.message : 'Failed to save image';
365
- setError(errorMessage);
366
- return null;
367
- } finally {
368
- setIsProcessing(false);
369
- }
370
- },
371
- []
372
- );
12
+ const transform = useImageTransform();
13
+ const conversion = useImageConversion();
373
14
 
374
15
  return {
375
- // Functions
376
- resize,
377
- crop,
378
- rotate,
379
- flip,
380
- manipulate,
381
- compress,
382
- resizeToFit,
383
- createThumbnail,
384
- cropToSquare,
385
- convertFormat,
386
- saveImage,
387
-
388
- // State
389
- isProcessing,
390
- error,
16
+ ...transform,
17
+ ...conversion,
18
+ // Combined state
19
+ isProcessing: transform.isTransforming || conversion.isConverting,
20
+ error: transform.transformError || conversion.conversionError,
391
21
  };
392
22
  };
393
-
@@ -0,0 +1,26 @@
1
+ import { useCallback } from 'react';
2
+ import { useImageOperation } from './useImageOperation';
3
+ import { ImageConversionService } from '../../infrastructure/services/ImageConversionService';
4
+ import { ImageStorageService } from '../../infrastructure/services/ImageStorageService';
5
+ import type { ImageSaveOptions, SaveFormat } from '../../domain/entities/ImageTypes';
6
+
7
+ export const useImageConversion = () => {
8
+ const { isProcessing, error, execute } = useImageOperation();
9
+
10
+ const compress = useCallback((uri: string, quality: number = 0.8) =>
11
+ execute(() => ImageConversionService.compress(uri, quality), 'Failed to compress'), [execute]);
12
+
13
+ const convertFormat = useCallback((uri: string, format: SaveFormat, quality?: number) =>
14
+ execute(() => ImageConversionService.convertFormat(uri, format, quality), 'Failed to convert'), [execute]);
15
+
16
+ const createThumbnail = useCallback((uri: string, size?: number, options?: ImageSaveOptions) =>
17
+ execute(() => ImageConversionService.createThumbnail(uri, size, options), 'Failed to create thumbnail'), [execute]);
18
+
19
+ const saveImage = useCallback((uri: string, filename?: string) =>
20
+ execute(() => ImageStorageService.saveImage(uri, filename), 'Failed to save'), [execute]);
21
+
22
+ return {
23
+ compress, convertFormat, createThumbnail, saveImage,
24
+ isConverting: isProcessing, conversionError: error,
25
+ };
26
+ };
@@ -10,7 +10,7 @@ import { ImageViewerService } from '../../infrastructure/services/ImageViewerSer
10
10
  import type {
11
11
  ImageViewerItem,
12
12
  ImageGalleryOptions,
13
- } from '../../domain/entities/Image';
13
+ } from '../../domain/entities/ImageTypes';
14
14
 
15
15
  /**
16
16
  * useImageGallery hook return type
@@ -0,0 +1,33 @@
1
+ import { useState, useCallback } from 'react';
2
+
3
+ /**
4
+ * Generic hook to handle image operation states (loading, error)
5
+ * adhering to DRY principles.
6
+ */
7
+ export const useImageOperation = () => {
8
+ const [isProcessing, setIsProcessing] = useState(false);
9
+ const [error, setError] = useState<string | null>(null);
10
+
11
+ const execute = useCallback(async <T>(
12
+ operation: () => Promise<T | null>,
13
+ errorMessage: string
14
+ ): Promise<T | null> => {
15
+ setIsProcessing(true);
16
+ setError(null);
17
+ try {
18
+ const result = await operation();
19
+ if (!result) {
20
+ setError(errorMessage);
21
+ return null;
22
+ }
23
+ return result;
24
+ } catch (err) {
25
+ setError(err instanceof Error ? err.message : errorMessage);
26
+ return null;
27
+ } finally {
28
+ setIsProcessing(false);
29
+ }
30
+ }, []);
31
+
32
+ return { isProcessing, error, execute };
33
+ };
@@ -0,0 +1,37 @@
1
+ import { useCallback } from 'react';
2
+ import { useImageOperation } from './useImageOperation';
3
+ import { ImageTransformService } from '../../infrastructure/services/ImageTransformService';
4
+ import type {
5
+ ImageManipulateAction,
6
+ ImageSaveOptions,
7
+ } from '../../domain/entities/ImageTypes';
8
+
9
+ export const useImageTransform = () => {
10
+ const { isProcessing, error, execute } = useImageOperation();
11
+
12
+ const resize = useCallback((uri: string, width?: number, height?: number, options?: ImageSaveOptions) =>
13
+ execute(() => ImageTransformService.resize(uri, width, height, options), 'Failed to resize'), [execute]);
14
+
15
+ const crop = useCallback((uri: string, cropArea: any, options?: ImageSaveOptions) =>
16
+ execute(() => ImageTransformService.crop(uri, cropArea, options), 'Failed to crop'), [execute]);
17
+
18
+ const rotate = useCallback((uri: string, degrees: number, options?: ImageSaveOptions) =>
19
+ execute(() => ImageTransformService.rotate(uri, degrees, options), 'Failed to rotate'), [execute]);
20
+
21
+ const flip = useCallback((uri: string, flipParams: any, options?: ImageSaveOptions) =>
22
+ execute(() => ImageTransformService.flip(uri, flipParams, options), 'Failed to flip'), [execute]);
23
+
24
+ const manipulate = useCallback((uri: string, action: ImageManipulateAction, options?: ImageSaveOptions) =>
25
+ execute(() => ImageTransformService.manipulate(uri, action, options), 'Failed to manipulate'), [execute]);
26
+
27
+ const resizeToFit = useCallback((uri: string, w: number, h: number, opts?: ImageSaveOptions) =>
28
+ execute(() => ImageTransformService.resizeToFit(uri, w, h, opts), 'Failed to resize to fit'), [execute]);
29
+
30
+ const cropToSquare = useCallback((uri: string, w: number, h: number, opts?: ImageSaveOptions) =>
31
+ execute(() => ImageTransformService.cropToSquare(uri, w, h, opts), 'Failed to crop square'), [execute]);
32
+
33
+ return {
34
+ resize, crop, rotate, flip, manipulate, resizeToFit, cropToSquare,
35
+ isTransforming: isProcessing, transformError: error,
36
+ };
37
+ };