@carbonorm/carbonreact 2.0.1 → 2.0.3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carbonorm/carbonreact",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "main": "dist/index.cjs.js",
5
5
  "module": "dist/index.esm.js",
6
6
  "types": "dist/index.d.ts",
@@ -13,6 +13,7 @@
13
13
  "axios": "^1.4.0",
14
14
  "bootstrap": "^5.3.1",
15
15
  "classnames": "^2.3.2",
16
+ "heic2any": "^0.0.4",
16
17
  "qs": "^6.11.1",
17
18
  "react": "^18.2.0",
18
19
  "react-dom": "^18.2.0",
@@ -13,7 +13,7 @@ import {initialRestfulObjectsState, iRestfulObjectArrayTypes} from "variables/C6
13
13
 
14
14
 
15
15
  // our central container, single page application is best with the DigApi
16
- export interface iCarbonORMState {
16
+ export interface iCarbonReactState {
17
17
  alertsWaiting: any[],
18
18
  websocketEvents: MessageEvent[],
19
19
  websocketData: any[],
@@ -21,21 +21,21 @@ export interface iCarbonORMState {
21
21
  backendThrowable: any[],
22
22
  }
23
23
 
24
- export const initialRequiredCarbonORMState: iCarbonORMState = {
24
+ export const initialRequiredCarbonORMState: iCarbonReactState = {
25
25
  alertsWaiting: [],
26
26
  backendThrowable: [],
27
27
  websocketData: [],
28
28
  websocketEvents: [],
29
29
  }
30
30
 
31
- export const initialCarbonORMState: iCarbonORMState = {
31
+ export const initialCarbonReactState: iCarbonReactState = {
32
32
  ...initialRequiredCarbonORMState,
33
33
  ...initialRestfulObjectsState,
34
34
  }
35
35
 
36
36
  export default class CarbonReact<P = {}, S = {}> extends React.Component<{
37
37
  children?: ReactNode | ReactNode[],
38
- } & P, ( iRestfulObjectArrayTypes |& S ) & iCarbonORMState> {
38
+ } & P, ( iRestfulObjectArrayTypes |& S ) & iCarbonReactState> {
39
39
 
40
40
  static instance: CarbonReact;
41
41
 
@@ -49,7 +49,7 @@ export default class CarbonReact<P = {}, S = {}> extends React.Component<{
49
49
 
50
50
  super(props);
51
51
 
52
- this.state = initialCarbonORMState as unknown as iCarbonORMState & S;
52
+ this.state = initialCarbonReactState as unknown as iCarbonReactState & S;
53
53
 
54
54
  CarbonReact.instance = this;
55
55
 
@@ -72,7 +72,7 @@ export default class CarbonReact<P = {}, S = {}> extends React.Component<{
72
72
 
73
73
  shouldComponentUpdate(
74
74
  nextProps: Readonly<any>,
75
- nextState: Readonly<iCarbonORMState>,
75
+ nextState: Readonly<iCarbonReactState>,
76
76
  _nextContext: any): boolean {
77
77
 
78
78
  changed(this.constructor.name + ' (DigApi)', 'props', this.props, nextProps);
@@ -82,7 +82,7 @@ export default class CarbonReact<P = {}, S = {}> extends React.Component<{
82
82
 
83
83
  }
84
84
 
85
- componentDidUpdate(_prevProps: Readonly<any>, _prevState: Readonly<iCarbonORMState>, _snapshot?: any) {
85
+ componentDidUpdate(_prevProps: Readonly<any>, _prevState: Readonly<iCarbonReactState>, _snapshot?: any) {
86
86
  if (CarbonReact.lastLocation !== location.pathname) {
87
87
  CarbonReact.lastLocation = location.pathname;
88
88
  const websocket = this.state.websocket;
@@ -1,10 +1,10 @@
1
- import CarbonReact, {iCarbonORMState} from "CarbonReact";
1
+ import CarbonReact, {iCarbonReactState} from "CarbonReact";
2
2
  import {iRestfulObjectArrayTypes, tRestfulObjectValues} from "variables/C6";
3
3
 
4
4
 
5
5
  //ObjectType, UniqueIdType extends keyof ObjectType
6
6
  export default function deleteRestfulObjectArrays<ObjectType = tRestfulObjectValues, ObjectArrayTypes = iRestfulObjectArrayTypes>
7
- (dataOrCallback: ((prev: Readonly<iCarbonORMState>) => ObjectType[]) | ObjectType[],
7
+ (dataOrCallback: ((prev: Readonly<iCarbonReactState>) => ObjectType[]) | ObjectType[],
8
8
  stateKey: keyof ObjectArrayTypes,
9
9
  uniqueObjectId: keyof ObjectType,
10
10
  callback?: () => void): void {
@@ -1,5 +1,5 @@
1
1
  import CarbonReact, {
2
- iCarbonORMState
2
+ iCarbonReactState
3
3
  } from "CarbonReact";
4
4
  import {iRestfulObjectArrayTypes, tRestfulObjectValues} from "variables/C6";
5
5
 
@@ -20,8 +20,8 @@ export enum eUpdateInsertMethod {
20
20
  * @param callback - if you want to do something with the updated state, you can pass a callback here. Run as the second
21
21
  * parameter of setState.
22
22
  */
23
- export default function updateRestfulObjectArray<ObjectType = tRestfulObjectValues, ObjectArrayTypes = iRestfulObjectArrayTypes>
24
- (dataOrCallback: ((prev: Readonly<iCarbonORMState>) => ObjectType[]) | ObjectType[],
23
+ export default function updateRestfulObjectArrays<ObjectType = tRestfulObjectValues, ObjectArrayTypes = iRestfulObjectArrayTypes>
24
+ (dataOrCallback: ((prev: Readonly<iCarbonReactState>) => ObjectType[]) | ObjectType[],
25
25
  stateKey: keyof ObjectArrayTypes,
26
26
  uniqueObjectId: keyof ObjectType,
27
27
  insertUpdateOrder: eUpdateInsertMethod = eUpdateInsertMethod.LAST,
@@ -1,6 +1,6 @@
1
1
  // @link https://stackoverflow.com/questions/6735414/php-data-uri-to-file
2
2
  // @link https://www.tutorialspoint.com/convert-image-to-data-uri-with-javascript
3
- import {ChangeEvent} from "react";
3
+ import {ChangeEvent, lazy} from "react";
4
4
  import {toast} from "react-toastify";
5
5
 
6
6
 
@@ -40,40 +40,69 @@ export async function toDataURL(src: string, fileType: string, callback: (dataUr
40
40
 
41
41
  }
42
42
 
43
- export function uploadImageChange(event: ChangeEvent<HTMLInputElement>,
44
- uploadCallback: ((imageDataUri: string) => void)) {
43
+ export async function uploadImageChange(event: ChangeEvent<HTMLInputElement>,
44
+ uploadCallback: (dataUriBase64: string) => void) {
45
45
 
46
- if (event.target.files !== null && event.target.files[0]) {
46
+ if (event.target.files === null || undefined === event.target?.files?.[0]) {
47
47
 
48
- Object.keys(event.target.files).forEach((index) => {
48
+ toast.error('Please upload a valid image file type (jpg, jpeg, png, gif, heic).');
49
49
 
50
- const file = event.target.files?.[index];
50
+ return;
51
+
52
+ }
53
+
54
+ Object.keys(event.target.files).forEach((index) => {
55
+
56
+ (async () => {
57
+ let file = event.target.files?.[index];
51
58
 
52
59
  // loop through all files and create data url then post to postPost
53
- if (file.type.match('image.*')) {
60
+ if (false === file.type.match('image.*')) {
54
61
 
55
- // get file extension
56
- const fileExtension = file.name.split('.').pop();
62
+ toast.error('Please upload a valid image file type (jpg, jpeg, png, gif, heic). (E_IMAGE_*<>' + file.type + ')');
57
63
 
58
- // check file extension is valid data uri
59
- if (fileExtension !== 'jpg' && fileExtension !== 'jpeg' && fileExtension !== 'png' && fileExtension !== 'gif') {
64
+ return;
60
65
 
61
- toast.error('Please upload a valid image file type (jpg, jpeg, png, gif).');
66
+ }
62
67
 
63
- return;
68
+ // get file extension
69
+ const fileExtension = file.name.split('.').pop();
64
70
 
65
- }
71
+ // check file extension is valid data uri
72
+ if (fileExtension !== 'jpg'
73
+ && fileExtension !== 'jpeg'
74
+ && fileExtension !== 'heic'
75
+ && fileExtension !== 'png'
76
+ && fileExtension !== 'gif') {
66
77
 
78
+ toast.error('Please upload a valid image file type (jpg, jpeg, png, gif, heic). (E_IMAGE_EXT)');
67
79
 
68
- // @link https://github.com/palantir/tslint/issues/4653
69
- // @link https://github.com/Microsoft/TypeScript/issues/13376#issuecomment-273289748
70
- void toDataURL(URL.createObjectURL(file), file.type, uploadCallback);
80
+ return;
71
81
 
72
82
  }
73
83
 
74
- });
84
+ const isHeic = fileExtension === 'heic';
85
+
86
+ if (isHeic) {
87
+
88
+ // todo - this should be code split and lazy loaded, but doesn't work
89
+ // look up code splitting, it could be an issue with rewired
90
+ file = (await lazy(() => require("heic2any")))({
91
+ blob: file,
92
+ toType: "image/webp",
93
+ quality: 1.0, // 0.5 cuts the quality and size by half
94
+ });
95
+
96
+ }
97
+
98
+ // @link https://github.com/palantir/tslint/issues/4653
99
+ // @link https://github.com/Microsoft/TypeScript/issues/13376#issuecomment-273289748
100
+ void toDataURL(URL.createObjectURL(file), 'image/webp', uploadCallback);
101
+
102
+ })();
103
+
104
+ });
75
105
 
76
- }
77
106
 
78
107
  }
79
108
 
@@ -81,12 +110,28 @@ uploadCallback: ((imageDataUri: string) => void)) {
81
110
  // dataUriEncoded is the base64 encoded string which is posted in column post_content
82
111
  export default function uploadImage(uploadCallback: (dataUriBase64: string) => void) {
83
112
  return () => {
113
+
84
114
  const input: HTMLInputElement = document.createElement('input')
115
+
85
116
  input.type = 'file'
86
- input.accept = 'image/*'
87
- input.onchange = (e: Event): any => {
88
- uploadImageChange(e as unknown as ChangeEvent<HTMLInputElement>, uploadCallback)
89
- }
117
+
118
+ input.accept = 'image/*, .heic'
119
+
120
+ input.style.display = 'none'
121
+
122
+ // the element must be appended to the document to work on safari
123
+ // @link https://stackoverflow.com/questions/47664777/javascript-file-input-onchange-not-working-ios-safari-only
124
+ document.body.appendChild(input);
125
+
126
+ // safari also requires addEventListener rather than .onChange
127
+ input.addEventListener('change', (e) => {
128
+
129
+ console.log('upload image event', e)
130
+
131
+ void uploadImageChange(e as unknown as ChangeEvent<HTMLInputElement>, uploadCallback)
132
+
133
+ })
134
+
90
135
  input.click()
91
136
  }
92
137
  }