diff --git a/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/app.vue b/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/app.vue index 8e089965c4..bd8771281f 100644 --- a/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/app.vue +++ b/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/app.vue @@ -3,6 +3,7 @@ import { computed, inject, ref, watchEffect } from "vue"; import StyleSettings from "./style-settings.vue"; import Select from "./input/select.vue"; import Input from "./input/input.vue"; +import PassPreview from "./pass-preview.vue"; import { StoreKey } from "../walletStore"; const gettext = (window as any).gettext; @@ -64,14 +65,9 @@ function openPreview(e: SubmitEvent) { .panel-heading Preview .panel-body span.text-muted The preview below is only a rough representation of what the pass might look like. Please check the generated pass. - div(style="margin-top: 1em; width: 10cm; height: 15cm; position: relative; border: solid 1px gray; border-radius: 1em;") - div(style="position: absolute; background-color: red; top: 0.5cm; left: 0cm; height: 1cm; width: 2cm;") Logo - div(style="position: absolute; background-color: red; top: 0.5cm; left: 2.25cm; height: 1cm; width: 5.5cm;") Logo Text - div(style="position: absolute; background-color: red; top: 0.5cm; left: 8cm; height: 1cm; width: 2cm;") Header - div(style="position: absolute; background-color: red; top: 2.5cm; left: 0cm; height: 2cm; width: 10cm;") Primary - div(style="position: absolute; background-color: red; top: 4.75cm; left: 0cm; height: 1cm; width: 10cm;") Secondary - div(style="position: absolute; background-color: red; top: 7cm; left: 0cm; height: 1cm; width: 10cm;") Auxiliary - div(style="position: absolute; background-color: red; top: 10cm; left: 3cm; height: 4cm; width: 4cm;") Barcode + PassPreview + div(style="margin-top: 1em; width: calc(10cm); height: 15cm; position: relative; outline: solid 1px gray; border-radius: 1em;") + div(style="position: absolute; background-color: red; top: 0.5cm; left: 0.5cm; right: 0.5cm; height: 14cm;") Back // TODO: Preview pre code {{ store.currentPlatformLayout }} diff --git a/src/pretix/plugins/wallet/styles/apple.py b/src/pretix/plugins/wallet/styles/apple.py index 895266c074..4d42b268ce 100644 --- a/src/pretix/plugins/wallet/styles/apple.py +++ b/src/pretix/plugins/wallet/styles/apple.py @@ -22,6 +22,7 @@ from django.contrib.staticfiles import finders from pretix.base.models import OrderPosition from django.utils.encoding import force_bytes + class ApplePlatform(WalletPlatform): identifier = "apple" name = _("Apple") @@ -100,11 +101,19 @@ class StringResource: class SignedZipFile: """Generates a zip-file with manifest and signature as apple expects a pkpass file to be""" - def __init__(self, ca_certificate: str | bytes, certificate: str | bytes, key: str | bytes, password): + def __init__( + self, + ca_certificate: str | bytes, + certificate: str | bytes, + key: str | bytes, + password, + ): self.ca_certificate = cryptography.x509.load_pem_x509_certificate( force_bytes(ca_certificate) ) - self.certificate = cryptography.x509.load_pem_x509_certificate(force_bytes(certificate)) + self.certificate = cryptography.x509.load_pem_x509_certificate( + force_bytes(certificate) + ) self.key = cryptography.hazmat.primitives.serialization.load_pem_private_key( force_bytes(key), force_bytes(password) if password else None ) @@ -236,6 +245,13 @@ class AppleWalletEventTicket(AppleWalletStyle): ) ], ), + TextFieldGroup( + identifier="logo_text", + name=_("Logo text"), + max_entries=1, + labels=False, + default_entries=[], + ), TextFieldGroup( identifier="primary", name=_("Primary"), @@ -252,12 +268,20 @@ class AppleWalletEventTicket(AppleWalletStyle): TextFieldGroup( identifier="secondary", name=_("Secondary"), max_entries=4 ), # TODO: validation of max field count if combined "Coupons, store cards, and generic passes with a square barcode can have a total of up to four secondary and auxiliary fields, combined." - TextFieldGroup( - identifier="headers", name=_("Header"), max_entries=3 - ), + TextFieldGroup(identifier="header", name=_("Header"), max_entries=3), TextFieldGroup(identifier="auxiliary", name=_("Auxiliary"), max_entries=4), TextFieldGroup(identifier="back", name=_("Back")), - TextFieldGroup(identifier="code", name=_("QR-Code"), max_entries=1), + TextFieldGroup( + identifier="code", + name=_("QR-Code"), + max_entries=1, + labels=False, + default_entries=[ + PlaceholderFieldEntry( + content="secret", + ) + ], + ), ] # preview_image = "apple/event_ticket.svg" @@ -278,7 +302,7 @@ class AppleWalletEventTicket(AppleWalletStyle): return converted def pass_content(self, fields, strings): - return { + content = { "eventTicket": { "primaryFields": self.convert_fields( strings, fields["primary"], "primary" @@ -290,6 +314,11 @@ class AppleWalletEventTicket(AppleWalletStyle): strings, fields["auxiliary"], "auxiliary" ), "backFields": self.convert_fields(strings, fields["back"], "back"), - } + "headerFields": self.convert_fields(strings, fields["header"], "header"), + }, } - + if fields["logo_text"]: + content["logoText"] = self.convert_fields( + strings, fields["logo_text"], "logo_text" + )[0]["value"] + return content