Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: inkbox changes #2

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41,441 changes: 25,208 additions & 16,233 deletions package-lock.json

Large diffs are not rendered by default.

28 changes: 15 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
"@contentful/forma-36-fcss": "^0.3.0",
"@contentful/forma-36-react-components": "^3.97.1",
"@contentful/forma-36-tokens": "^0.11.0",
"@imgix/contentful": "^1.4.1",
"buffer": "^6.0.3",
"contentful-ui-extensions-sdk": "^3.31.0",
"cross-env": "^7.0.3",
"imgix-management-js": "^1.3.0",
Expand All @@ -34,7 +36,7 @@
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-imgix": "^9.5.4",
"react-scripts": "4.0.3"
"react-scripts": "^5"
},
"scripts": {
"start": "cross-env BROWSER=none react-scripts start",
Expand Down Expand Up @@ -62,18 +64,18 @@
]
},
"devDependencies": {
"@testing-library/jest-dom": "6.5.0",
"@testing-library/react": "16.0.1",
"@testing-library/user-event": "14.5.2",
"@types/jest": "29.5.13",
"@types/lodash.debounce": "4.0.9",
"@types/node": "20.16.5",
"@types/react": "17.0.80",
"@types/react-dom": "17.0.25",
"@types/react-imgix": "9.5.3",
"cypress": "13.14.2",
"prettier": "3.2.5",
"typescript": "4.9.5"
"@testing-library/jest-dom": "^5.5.0",
"@testing-library/react": "^12.0.1",
"@testing-library/user-event": "^14.5.2",
"@types/jest": "^29.5.13",
"@types/lodash.debounce": "^4.0.9",
"@types/node": "^20.16.5",
"@types/react": "^16.0.80",
"@types/react-dom": "^16.0.25",
"@types/react-imgix": "^9.5.3",
"cypress": "^13.14.2",
"prettier": "^3.2.5",
"typescript": "^4.9.5"
},
"files": [
"dist",
Expand Down
85 changes: 64 additions & 21 deletions src/components/Dialog/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
noOriginAssetsWebFolderError,
noSearchAssetsError,
noSourcesError,
fileTooLargeError,
} from '../../helpers/errors';
import { AppInstallationParameters } from '../ConfigScreen/';
import { ImageGallery } from '../Gallery/';
Expand All @@ -31,6 +32,10 @@ import packageJson from '../../../package.json';
import { UploadButton } from '../UploadButton/UploadButton';
import './Dialog.css';
import { stringifyJsonFields } from '../../helpers/utils';
import { Buffer} from "buffer";

// @ts-ignore
window.Buffer = Buffer;

interface DialogProps {
sdk: DialogExtensionSDK;
Expand Down Expand Up @@ -356,7 +361,7 @@ export default class Dialog extends Component<DialogProps, DialogState> {
if (Object.keys(this.state.selectedSource).length) {
const defaultQuery = `?page[number]=${
currentIndex || this.state.page.currentIndex
}&page[size]=18`;
}&page[size]=18&filter[origin_path]=assets`; // INKBOX NOTE: Add assets filter to query

const assetObjects = query
? await this.getAssetObjects(query, noSearchAssetsError())
Expand Down Expand Up @@ -396,6 +401,10 @@ export default class Dialog extends Component<DialogProps, DialogState> {
}

let _destination, path;

// INKBOX NOTE: Force destination to be /assets/contentful
destination = '/assets/contentful';

if (destination) {
// strip the leading and trailing slash from destination
_destination = destination.replace(/^\//, '').replace(/\/$/, '');
Expand Down Expand Up @@ -458,20 +467,44 @@ export default class Dialog extends Component<DialogProps, DialogState> {
reader.addEventListener(
'load',
() => {
// convert image file to base64 string
const assetBase64String = reader.result as string;
const fileString = assetBase64String.replace(
/^data:image\/gif;base64,|^data:image\/png;base64,|^data:image\/jpeg;base64,|^data:image\/jpg;base64,|^data:image\/bmp;base64,|^data:image\/webp;base64,/,
'',
);
const buffer = Buffer.from(fileString, 'base64');
this.upload(buffer);
// Handle Image & Video Uploads
if (file?.type.includes('image')) {
this.handleImageUpload(reader, file);
} else if (file?.type.includes('video')) {
this.handleVideoUpload(reader, file);
} else {
// Error: Unsupported file type
console.error('imgix: unsupported file type');
}

},
false,
);
reader.readAsDataURL(file as File);
};

handleImageUpload = (reader: FileReader, file: File) => {
// convert image file to base64 string
const assetBase64String = reader.result as string;
const fileString = assetBase64String.replace(
/^data:image\/gif;base64,|^data:image\/png;base64,|^data:image\/jpeg;base64,|^data:image\/jpg;base64,|^data:image\/bmp;base64,|^data:image\/webp;base64,/,
'',
);
const buffer = Buffer.from(fileString, 'base64');
this.upload(buffer);
}

handleVideoUpload = (reader: FileReader, file: File) => {
// convert video file to base64 string
const assetBase64String = reader.result as string;
const fileString = assetBase64String.replace(
/^data:video\/mp4;base64,/,
'',
);
const buffer = Buffer.from(fileString, 'base64');
this.upload(buffer);
}

setIsUploading = (value: boolean) => {
this.setState({ isUploading: value });
};
Expand Down Expand Up @@ -506,6 +539,16 @@ export default class Dialog extends Component<DialogProps, DialogState> {
};

openFileForm = (file: File, previewSource: string, showUpload: boolean) => {

// INKBOX NOTE: Check video file size - we don't want anything larger than 30MB
if (file.type.includes('video') && file.size > 30 * 1024 * 1024) {
this.setState({
errors: [fileTooLargeError()],
});

return;
}

const uploadForm = {
...this.state.uploadForm,
file,
Expand Down Expand Up @@ -578,6 +621,15 @@ export default class Dialog extends Component<DialogProps, DialogState> {
</div>
)}
</div>
{/* { UI Error fallback } */}
{this.state.errors.length > 0 && (
<Note
error={this.state.errors[0]}
type={this.state.errors[0].type}
resetErrorBoundary={this.resetNErrors}
dismissable={this.state.errors[0].dismissable}
/>
)}
<ImageGallery
selectedSource={selectedSource}
sdk={sdk}
Expand All @@ -586,15 +638,7 @@ export default class Dialog extends Component<DialogProps, DialogState> {
assets={assets}
loading={this.state.loading}
/>
{/* { UI Error fallback } */}
{this.state.errors.length > 0 && (
<Note
error={this.state.errors[0]}
type={this.state.errors[0].type}
resetErrorBoundary={this.resetNErrors}
dismissable={this.state.errors[0].dismissable}
/>
)}

{this.state.showUpload && (
<div className="ix-upload-editor-container">
<div className="ix-upload-editor">
Expand Down Expand Up @@ -635,10 +679,9 @@ export default class Dialog extends Component<DialogProps, DialogState> {
className={
this.state.isUploading ? 'ix-input-readonly' : ''
}
value={this.state.uploadForm.destination || '/'}
value="/assets/contentful"
onChange={this.updateDestinationFilePath}
placeholder="/"
isReadOnly={this.state.isUploading}
isReadOnly={ true }
></TextInput>
</div>
</form>
Expand Down
31 changes: 29 additions & 2 deletions src/components/Field/Field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export default class Field extends Component<FieldProps, FieldState> {
return;
}

const url = new URL(this.state.selectedAsset.src || '');
const url = new URL(this.state.selectedAsset.src ||'');
const newParams = paramsReducer(url.searchParams, params, action);
const newURL = `${url.origin}${url.pathname}?${newParams.toString()}`;

Expand All @@ -98,7 +98,34 @@ export default class Field extends Component<FieldProps, FieldState> {

render() {
// Uncomment to test
// console.log({ ...this.state.selectedAsset });
//console.log({ ...this.state.selectedAsset });

// INKBOX NOTE: Undo all our shenanigans to get the selectedAsset back to the correct shape for the FieldImagePreview component

// undo the array wrapping
//@ts-ignore
this.state.selectedAsset = this.state.selectedAsset?.[0];

// ensure we have the correct src
if (this.state.selectedAsset && !this.state.selectedAsset.src) {
//@ts-ignore
this.state.selectedAsset.src = this.state.selectedAsset.original_url;

// get the correct content type by checking the file extension, check if image, video, or other
// we are assuming that the content type is image if it doesn't end with .mp4 - not the best way to do this, but it works for now
let contentType = "image";
if (this.state.selectedAsset.src.endsWith('.mp4')) {
contentType = "video";
}

// add the content type to the attributes back
this.state.selectedAsset.attributes = {
content_type: contentType,
}
}

// INKBOX NOTE: End of undoing shenanigans


const updateHeightHandler = this.props.sdk.window.updateHeight;
if (this.state.selectedAsset && this.state.selectedAsset.src) {
Expand Down
10 changes: 6 additions & 4 deletions src/components/Gallery/ImageGallery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,12 @@ export class Gallery extends Component<GalleryProps, GalleryState> {
]),
};

this.props.sdk.close({
...stringifiedAsset,
selectedSource: this.props.selectedSource,
});
// INKBOX NOTE: ignore the asset because we need it in our format
// [ { original_url: url } ]

this.props.sdk.close([
{original_url: selectedAsset.src,}
]);
};

handleClose = () => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/UploadButton/UploadButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export function UploadButton(props: {
style={{ display: 'none' }}
ref={inputRef}
type="file"
accept="image/*"
accept="image/*, video/*"
onChange={handleFileChange}
/>
</div>
Expand Down
12 changes: 11 additions & 1 deletion src/helpers/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ export type ErrorType =
| `NoSourcesError`
| `NoOriginAssetsError`
| `NoOriginAssetsWebFolderError`
| `noSearchAssetsError`;
| `noSearchAssetsError`
| `fileTooLargeError`;

const DASHBOARD_URL = 'https://dashboard.imgix.com';
const WEBFOLDER_DOCUMENTATION_URL = `https://docs.imgix.com/setup/serving-assets#web-folder`;
Expand Down Expand Up @@ -54,6 +55,12 @@ const ERROR_MESSAGES = {
name: 'No results found',
type: 'warning',
dismissable: true,
},
fileTooLargeError: {
message: `The file you are trying to upload is too large. Please try uploading a smaller file.`,
name: 'File too large',
type: 'negative',
dismissable: true,
}
} as const;

Expand Down Expand Up @@ -106,3 +113,6 @@ export const noOriginAssetsWebFolderError = (message?: string) =>

export const noSearchAssetsError = (message?: string) =>
new IxError('noSearchAssetsError', message);

export const fileTooLargeError = (message?: string) =>
new IxError('fileTooLargeError', message);
Loading