Skip to content

Commit

Permalink
Use result type to check for glyphs which are not supported
Browse files Browse the repository at this point in the history
  • Loading branch information
maxammann committed Jan 26, 2022
1 parent baab060 commit 3f38e7d
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 16 deletions.
34 changes: 24 additions & 10 deletions administration/src/components/generation/GenerationController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import downloadDataUri from "../../util/downloadDataUri";
import generateCards from "./generateCards";
import RegionSelector from "../RegionSelector";
import {RegionContext} from "../../RegionProvider";
import {PDFError} from "./PdfFactory";

enum Mode {
input,
Expand All @@ -30,17 +31,30 @@ const GenerationController = () => {
}

const confirm = async () => {
try {
setMode(Mode.loading)
const pdfDataUri = await generateCards(client, cardCreationModels, region)
downloadDataUri(pdfDataUri, "ehrenamtskarten.pdf")
setMode(Mode.finished)
} catch (e) {
console.error(e)
AppToaster.show({message: "Etwas ist schiefgegangen.", intent: "danger"})
setMode(Mode.input)
}
setMode(Mode.loading);
(await generateCards(client, cardCreationModels, region)).unwrap(
(blob: Blob) => {
downloadDataUri(blob, "ehrenamtskarten.pdf");
setMode(Mode.finished);
},
(error: PDFError) => {
console.error(error)
switch (error.type) {
case "pdf-generation":
AppToaster.show({message: "Etwas ist schiefgegangen.", intent: "danger"})
break;
case "unicode":
AppToaster.show({message: `Ein Zeichen konnte nicht in der PDF eingebunden werden: ${error.unsupportedChar}`, intent: "danger"})
break;

}

setMode(Mode.input)
}
);

}

if (mode === Mode.input)
return <GenerationForm cardCreationModels={cardCreationModels} setCardCreationModels={setCardCreationModels}
confirm={confirm}/>
Expand Down
46 changes: 42 additions & 4 deletions administration/src/components/generation/PdfFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,34 @@ import {CardActivateModel} from "../../generated/compiled";
import uint8ArrayToBase64 from "../../util/uint8ArrayToBase64";
import {format, fromUnixTime} from "date-fns";
import {getRegions_regions as Region} from "../../graphql/regions/__generated__/getRegions";
import {Err, Ok, Result} from "../../util/result";

export type PDFError = UnexpectedUnicodeError | PDFGenerationError

type PDFGenerationError = {
type: "pdf-generation"
}

type UnexpectedUnicodeError = {
type: "unicode"
unsupportedChar: string
}

function checkForeignText(doc: jsPDF, text: string): string | null {
let font = doc.getFont();

for (let i = 0; i < text.length; i++) {
if (font.metadata.characterToGlyph(text.charCodeAt(i)) == 0) {
return text.charAt(i)
}
}

return null
}

export function checkCardActivateModel(doc: jsPDF, model: CardActivateModel): string | null {
return checkForeignText(doc, model.fullName)
}

function addLetter(doc: jsPDF, model: CardActivateModel, region: Region) {
const pageSize = doc.internal.pageSize
Expand Down Expand Up @@ -59,8 +87,8 @@ Aussteller: ${region.prefix} ${region.name}`,
});
}

export function generatePdf(models: CardActivateModel[], region: Region) {
const doc = new jsPDF({
export async function generatePdf(models: CardActivateModel[], region: Region): Promise<Result<Blob, PDFError>> {
const doc: jsPDF = new jsPDF({
orientation: 'portrait',
unit: 'mm',
format: 'a4'
Expand All @@ -73,7 +101,16 @@ export function generatePdf(models: CardActivateModel[], region: Region) {
doc.setFont("NotoSans-Regular")

for (let k = 0; k < models.length; k++) {
addLetter(doc, models[k], region)
let model = models[k];
let unsupportedChar = checkCardActivateModel(doc, model);
if (unsupportedChar) {
return Err({
type: "unicode",
unsupportedChar
})
}

addLetter(doc, model, region)
if (k !== models.length - 1)
doc.addPage()
}
Expand All @@ -85,5 +122,6 @@ export function generatePdf(models: CardActivateModel[], region: Region) {
creator: "Bayern"
});

return new Blob([doc.output('blob')], {type: "application/pdf"})
let blob = doc.output('blob');
return Ok(new Blob([blob], {type: "application/pdf"}))
}
5 changes: 3 additions & 2 deletions administration/src/components/generation/generateCards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import generateHashFromCardDetails from "../../util/generateHashFromCardDetails"
import uint8ArrayToBase64 from "../../util/uint8ArrayToBase64";
import {addCard, addCardVariables} from "../../graphql/verification/__generated__/addCard";
import {ADD_CARD} from "../../graphql/verification/mutations";
import {generatePdf} from "./PdfFactory";
import {generatePdf, PDFError} from "./PdfFactory";
import {ApolloClient} from "@apollo/client";
import {getRegions_regions as Region} from "../../graphql/regions/__generated__/getRegions";
import {Result} from "../../util/result";

const generateCards = async (client: ApolloClient<object>, cardCreationModels: CardCreationModel[], region: Region) => {
const generateCards = async (client: ApolloClient<object>, cardCreationModels: CardCreationModel[], region: Region): Promise<Result<Blob, PDFError>> => {
const activateModels = cardCreationModels.map(model => {
const cardType = model.cardType === CardType.gold
? CardActivateModel.CardType.GOLD
Expand Down

0 comments on commit 3f38e7d

Please sign in to comment.