Skip to content

Commit

Permalink
✨ Add UI logic for uploading modified epub files
Browse files Browse the repository at this point in the history
  • Loading branch information
williamchong committed Feb 19, 2024
1 parent 362f984 commit 118bf5f
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 40 deletions.
151 changes: 111 additions & 40 deletions components/IscnUploadForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<tbody class="w-full">
<tr
v-for="(
{ isFileImage, fileData, fileName, fileSize, exifInfo},
{ isFileImage, fileData, fileName, fileSize, exifInfo },
index
) of fileRecords"
:key="fileName"
Expand Down Expand Up @@ -104,6 +104,9 @@
</table>
</div>
</div>
<FormField v-if="showAddISCNPageOption">
<CheckBox v-model="isAddISCNPageToEpub">{{ $t('UploadForm.label.insertISCNPage') }}</CheckBox>
</FormField>
<!-- upload field__Submit -->
<div class="flex gap-[8px] justify-end text-medium-gray mt-[24px]">
<NuxtLink
Expand Down Expand Up @@ -242,6 +245,7 @@ import {
} from '~/utils/misc'
import { DEFAULT_TRANSFER_FEE, sendLIKE } from '~/utils/cosmos/sign';
import { getAccountBalance } from '~/utils/cosmos'
import { injectISCNQRCodePage } from '~/utils/epub/iscn'
const walletModule = namespace('wallet')
type UploadStatus = '' | 'loading' | 'signing' | 'uploading';
Expand Down Expand Up @@ -282,6 +286,7 @@ export default class IscnUploadForm extends Vue {
isOpenWarningSnackbar = false
isOpenKeplr = true
isSizeExceeded = false
isAddISCNPageToEpub = true
uploadSizeLimit: number = UPLOAD_FILESIZE_MAX
uploadStatus: UploadStatus = '';
Expand All @@ -300,6 +305,7 @@ export default class IscnUploadForm extends Vue {
balance = new BigNumber(0)
epubMetadataList: any[] = []
modifiedEpubMap: any = {}
get formClasses() {
return [
Expand Down Expand Up @@ -369,6 +375,23 @@ export default class IscnUploadForm extends Vue {
}
}
get showAddISCNPageOption() {
return this.mode === MODE.EDIT && this.fileRecords.some(file => file.fileType === 'application/epub+zip')
}
get modifiedFileRecords() {
if (!this.isAddISCNPageToEpub || this.mode !== MODE.EDIT) return this.fileRecords
return this.fileRecords.map((record) => {
if (record.fileType === 'application/epub+zip') {
const modifiedEpubRecord = this.modifiedEpubMap[record.ipfsHash]
if (modifiedEpubRecord) {
return modifiedEpubRecord
}
}
return record
})
}
@Watch('error')
showWarning(errormsg: any) {
if (errormsg) this.isOpenWarningSnackbar = true
Expand All @@ -385,6 +408,32 @@ export default class IscnUploadForm extends Vue {
}
}
// eslint-disable-next-line class-methods-use-this
async getFileInfo(file: Blob) {
const fileBytes = (await fileToArrayBuffer(
file,
)) as unknown as ArrayBuffer
if (fileBytes) {
const [
fileSHA256,
imageType,
ipfsHash,
// eslint-disable-next-line no-await-in-loop
] = await Promise.all([
digestFileSHA256(fileBytes),
readImageType(fileBytes),
Hash.of(Buffer.from(fileBytes)),
])
return {
fileBytes,
fileSHA256,
imageType,
ipfsHash,
}
}
return null
}
async onFileUpload(event: DragEvent) {
logTrackerEvent(this, 'ISCNCreate', 'SelectFile', '', 1)
this.isSizeExceeded = false
Expand Down Expand Up @@ -412,21 +461,14 @@ export default class IscnUploadForm extends Vue {
reader.readAsDataURL(file)
// eslint-disable-next-line no-await-in-loop
const fileBytes = (await fileToArrayBuffer(
file,
)) as unknown as ArrayBuffer
if (fileBytes) {
const [
const info = await this.getFileInfo(file)
if (info) {
const {
fileBytes,
fileSHA256,
imageType,
ipfsHash,
// eslint-disable-next-line no-await-in-loop
] = await Promise.all([
digestFileSHA256(fileBytes),
readImageType(fileBytes),
Hash.of(Buffer.from(fileBytes)),
])
} = info
fileRecord = {
...fileRecord,
fileName: file.name,
Expand All @@ -453,7 +495,7 @@ export default class IscnUploadForm extends Vue {
}
if (file.type === 'application/epub+zip') {
// eslint-disable-next-line no-await-in-loop
await this.processEPub({ buffer: fileBytes, file })
await this.processEPub({ ipfsHash, buffer: fileBytes, file })
}
}
} else {
Expand All @@ -464,10 +506,41 @@ export default class IscnUploadForm extends Vue {
}
}
async processEPub({ buffer, file }: { buffer: ArrayBuffer; file: File }) {
async processEPub({ ipfsHash, buffer, file }: { ipfsHash: string, buffer: ArrayBuffer; file: File }) {
try {
const book = ePub(buffer)
await book.ready
if (this.mode === MODE.EDIT) {
const modifiedEpub = await injectISCNQRCodePage(buffer, book, this.iscnId || '')
// eslint-disable-next-line no-await-in-loop
const info = await this.getFileInfo(modifiedEpub)
if (info) {
const {
fileSHA256: modifiedEpubSHA256,
ipfsHash: modifiedEpubIpfsHash,
} = info
const modifiedEpubRecord: any = {
fileName: file.name,
fileSize: modifiedEpub.size,
fileType: modifiedEpub.type,
fileBlob: modifiedEpub,
ipfsHash: modifiedEpubIpfsHash,
fileSHA256: modifiedEpubSHA256,
isFileImage: false,
}
const epubReader = new FileReader()
epubReader.onload = (e) => {
if (!e.target) return
modifiedEpubRecord.fileData = e.target.result as string
Vue.set(this.modifiedEpubMap, ipfsHash, modifiedEpubRecord)
}
epubReader.readAsDataURL(modifiedEpub)
}
}
const epubMetadata: any = {}
// Get metadata
Expand Down Expand Up @@ -510,24 +583,19 @@ export default class IscnUploadForm extends Vue {
type: 'image/jpeg',
},
)
const fileBytes = (await fileToArrayBuffer(
coverFile,
)) as unknown as ArrayBuffer
if (fileBytes) {
const [
// eslint-disable-next-line no-await-in-loop
const coverInfo = await this.getFileInfo(coverFile)
if (coverInfo) {
const {
fileSHA256,
imageType,
ipfsHash,
// eslint-disable-next-line no-await-in-loop
] = await Promise.all([
digestFileSHA256(fileBytes),
readImageType(fileBytes),
Hash.of(Buffer.from(fileBytes)),
])
ipfsHash: ipfsThumbnailHash,
} = coverInfo
epubMetadata.thumbnailIpfsHash = ipfsHash
epubMetadata.thumbnailIpfsHash = ipfsThumbnailHash
const fileRecord: any = {
const coverFileRecord: any = {
fileName: coverFile.name,
fileSize: coverFile.size,
fileType: coverFile.type,
Expand All @@ -536,13 +604,13 @@ export default class IscnUploadForm extends Vue {
fileSHA256,
isFileImage: !!imageType,
}
const reader = new FileReader()
reader.onload = (e) => {
const coverReader = new FileReader()
coverReader.onload = (e) => {
if (!e.target) return
fileRecord.fileData = e.target.result as string
this.fileRecords.push(fileRecord)
coverFileRecord.fileData = e.target.result as string
this.fileRecords.push(coverFileRecord)
}
reader.readAsDataURL(coverFile)
coverReader.readAsDataURL(coverFile)
}
}
}
Expand Down Expand Up @@ -589,6 +657,9 @@ export default class IscnUploadForm extends Vue {
handleDeleteFile(index: number) {
const deletedFile = this.fileRecords[index];
if (this.modifiedEpubMap[deletedFile.ipfsHash]) {
delete this.modifiedEpubMap[deletedFile.ipfsHash]
}
this.fileRecords.splice(index, 1);
const indexToDelete = this.epubMetadataList.findIndex(item => item.thumbnailIpfsHash === deletedFile.ipfsHashList);
Expand Down Expand Up @@ -616,7 +687,7 @@ export default class IscnUploadForm extends Vue {
async estimateArweaveFee(): Promise<void> {
try {
const results = await Promise.all(
this.fileRecords.map(async (record) => {
this.modifiedFileRecords.map(async (record) => {
const priceResult = await estimateBundlrFilePrice({
fileSize: record.fileBlob?.size || 0,
ipfsHash: record.ipfsHash,
Expand Down Expand Up @@ -753,7 +824,7 @@ export default class IscnUploadForm extends Vue {
this.uploadStatus = ''
return
}
if (!this.fileRecords.some(file => file.fileBlob)) {
if (!this.modifiedFileRecords.some(file => file.fileBlob)) {
this.error = 'NO_FILE_TO_UPLOAD'
this.isOpenWarningSnackbar = true
this.uploadStatus = ''
Expand All @@ -763,7 +834,7 @@ export default class IscnUploadForm extends Vue {
try {
this.uploadStatus = 'uploading';
// eslint-disable-next-line no-restricted-syntax
for (const record of this.fileRecords) {
for (const record of this.modifiedFileRecords) {
// eslint-disable-next-line no-await-in-loop
await this.submitToArweave(record);
}
Expand All @@ -779,17 +850,17 @@ export default class IscnUploadForm extends Vue {
}
const uploadArweaveIdList = Array.from(this.sentArweaveTransactionInfo.values()).map(entry => entry.arweaveId);
this.fileRecords.forEach((record: any, index:number) => {
this.modifiedFileRecords.forEach((record: any, index:number) => {
if (this.sentArweaveTransactionInfo.has(record.ipfsHash)) {
const arweaveId = this.sentArweaveTransactionInfo.get(
record.ipfsHash,
)?.arweaveId
if (arweaveId) {
this.fileRecords[index].arweaveId = arweaveId
this.modifiedFileRecords[index].arweaveId = arweaveId
}
}
})
this.$emit('submit', { fileRecords: this.fileRecords, arweaveIds: uploadArweaveIdList, epubMetadata: this.epubMetadataList[0] })
this.$emit('submit', { fileRecords: this.modifiedFileRecords, arweaveIds: uploadArweaveIdList, epubMetadata: this.epubMetadataList[0] })
}
handleSignDialogClose() {
Expand Down
1 change: 1 addition & 0 deletions locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@
"UploadForm.button.selectFile": "Select a file",
"UploadForm.button.skip": "Skip Upload",
"UploadForm.button": "Start Upload",
"UploadForm.label.insertISCNPage": "Add ISCN Page to Epub",
"UploadForm.guide.dropFile": "Drop your file here, or",
"UploadForm.guide.selectFile": "Select your file and publish to IPFS",
"UploadForm.title.registerISCN": "Register ISCN",
Expand Down

0 comments on commit 118bf5f

Please sign in to comment.