/* Copyright © XlXi 2022 */ import { Component, createElement, createRef } from 'react'; import axios from 'axios'; import classNames from 'classnames/bind'; import { buildGenericApiUrl } from '../util/HTTP.js'; import Loader from './Loader'; axios.defaults.withCredentials = true; const assetTypes = [ { assetTypeId: 1, name: 'Image', type: 'fileupload', extra:

PNG, JPG, JPEG, and other common image formats are supported.

, sellable: false }, { assetTypeId: 4, name: 'Mesh', type: 'fileupload', extra:

Your mesh can be obj or Roblox's mesh format.

, sellable: false }, { assetTypeId: 5, name: 'Lua', type: 'text', sellable: false }, { assetTypeId: 6, name: 'HTML', type: 'text', sellable: false }, { assetTypeId: 7, name: 'Text', type: 'text', sellable: false }, { assetTypeId: 8, name: 'Hat', type: 'fileupload', sellable: true }, { assetTypeId: 17, name: 'Head', type: 'fileupload', extra:

Heads are SpecialMeshes. Export it from studio, do not upload the mesh file here.

, sellable: true }, { assetTypeId: 18, name: 'Face', type: 'fileupload', extra:

Faces are image files. The XML will be automatically generated.

, sellable: true }, { assetTypeId: 19, name: 'Gear', type: 'fileupload', sellable: true }, { assetTypeId: 27, name: 'Torso', type: 'packagepart', extra:

Overlay ID displays atop clothing, base ID displays under clothing.

, sellable: false }, { assetTypeId: 28, name: 'Right Arm', type: 'packagepart', extra:

Overlay ID displays atop clothing, base ID displays under clothing.

, sellable: false }, { assetTypeId: 29, name: 'Left Arm', type: 'packagepart', extra:

Overlay ID displays atop clothing, base ID displays under clothing.

, sellable: false }, { assetTypeId: 30, name: 'Left Leg', type: 'packagepart', extra:

Overlay ID displays atop clothing, base ID displays under clothing.

, sellable: false }, { assetTypeId: 31, name: 'Right Leg', type: 'packagepart', extra:

Overlay ID displays atop clothing, base ID displays under clothing.

, sellable: false }, { assetTypeId: 32, name: 'Package', type: 'text', extra:

Asset IDs for package. Example: 1;2;3;4;5

, sellable: true }, { assetTypeId: 37, name: 'Code', type: 'text', sellable: false } ]; class ManualAssetUploadModel extends Component { constructor(props) { super(props); this.state = { forSale: false, requestInputs: { name: 'New Asset', description: this.props.TypeName + ' Asset', 'roblox-id': 0, 'on-sale': false, price: 0 } }; this.forSaleRef = createRef(); this.pushInput = this.pushInput.bind(this); this.updateContentInputFile = this.updateContentInputFile.bind(this); this.updateContentInputText = this.updateContentInputText.bind(this); this.updateInput = this.updateInput.bind(this); this.uploadAsset = this.uploadAsset.bind(this); } componentDidMount() { this.pushInput('asset-type-id', this.props.TypeId); if(this.props.UploadType == 'packagepart') { this.pushInput('mesh-id', 0); this.pushInput('overlay-id', 0); this.pushInput('base-id', 0); } } pushInput(name, value) { this.setState((state, props) => ({ requestInputs: { ...state.requestInputs, [name]: value } })); } updateContentInputFile(value) { this.pushInput('content', value); } updateContentInputText(value) { const file = (value != '' && new Blob([ value ], { type: 'text/plain' })); this.pushInput('content', file); } updateInput(e, prop='value') { this.pushInput(e.target.id, e.target[prop]); } uploadAsset() { let { requestInputs } = this.state; this.props.setLoad(true); if(!requestInputs.content && this.props.UploadType != 'packagepart') { this.props.flashError('Asset content cannot be blank!'); this.props.setLoad(false); return; } let bodyFormData = new FormData(); Object.keys(requestInputs).map(key => { let val = requestInputs[key]; if(typeof(val) == 'boolean') val = val ? 1 : 0; bodyFormData.append(key, val); }); axios.post(buildGenericApiUrl('api', 'admin/v1/manual-asset-upload'), bodyFormData) .then(res => { const data = res.data; this.props.flashSuccess(data.message, data.assetId); this.props.setLoad(false); }) .catch(err => { const data = err.response.data; this.props.flashError(data.errors ? data.errors[0].message : 'An unknown error occurred.'); this.props.setLoad(false); }); } render() { let { TypeName, UploadType, Extra, Sellable } = this.props; return ( <>

Create a { TypeName }

{ Extra } { UploadType == 'fileupload' ? <> this.updateContentInputFile(e.target.files[0]) } /> : UploadType == 'packagepart' ? <> : UploadType == 'text' && <> } { Sellable && <>

Sell this Item

this.updateInput(e, 'checked') } />
{ this.state.requestInputs['on-sale'] &&

 

} }
) } } class ManualAssetUpload extends Component { constructor(props) { super(props); this.state = { createModelLoaded: false, currentTabTypeId: 0, tabKey: 0, loading: false }; this.findAssetType = this.findAssetType.bind(this); this.setLoad = this.setLoad.bind(this); this.flashError = this.flashError.bind(this); this.flashSuccess = this.flashSuccess.bind(this); this.navigateAssetType = this.navigateAssetType.bind(this); } componentDidMount() { this.navigateAssetType(1); } findAssetType(typeId) { return assetTypes.find(obj => { return obj.assetTypeId === typeId }); } setLoad(loading) { this.setState({ loading: loading }); } flashError(message) { this.setState({ errorMessage: message }); setTimeout(function(){ this.setState({ errorMessage: null }); }.bind(this), 3000); } flashSuccess(message, assetId) { this.setState({ successMessage: message, successId: assetId }); setTimeout(function(){ this.setState({ successMessage: null, successId: null }); }.bind(this), 10000); } navigateAssetType(typeId) { if(this.state.loading) return; let data = this.findAssetType(typeId); this.activeModel = createElement( ManualAssetUploadModel, { TypeId: data.assetTypeId, TypeName: data.name, UploadType: data.type, Extra: data.extra, Sellable: data.sellable, setLoad: this.setLoad, flashError: this.flashError, flashSuccess: this.flashSuccess, key: this.state.tabKey } ); this.setState({ createModelLoaded: true, currentTabTypeId: data.assetTypeId, tabKey: this.state.tabKey+1 }); } render() { return ( <>
{ this.state.successMessage &&
{ this.state.successMessage } Click Here
} { this.state.errorMessage &&
{ this.state.errorMessage }
}
{ this.state.loading &&
} { !this.state.createModelLoaded ? : this.activeModel }
); } } export default ManualAssetUpload;