From cd4da853da7fa681cf8cb1dcc6b4265ea2165236 Mon Sep 17 00:00:00 2001 From: Kara Engelhardt Date: Tue, 20 Oct 2026 17:49:21 +0200 Subject: [PATCH] apple: show fg color as white when background is set --- .../wallet/components/input/file-input.vue | 2 - .../components/platform-preview/apple.vue | 1 + .../static/pretixplugins/wallet/index.d.ts | 2 +- .../pretixplugins/wallet/walletStore.ts | 48 +++++++-------- src/pretix/plugins/wallet/styles/apple.py | 61 ++++++++++--------- 5 files changed, 57 insertions(+), 57 deletions(-) diff --git a/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/input/file-input.vue b/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/input/file-input.vue index ce3e6ec810..fce5a5eaed 100644 --- a/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/input/file-input.vue +++ b/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/input/file-input.vue @@ -9,8 +9,6 @@ const props = defineProps<{ label?: LocalizableString; errors?: string[]; help_text?: string; - filename?: string; - current_url?: string; default?: string; }>(); const id = useId(); diff --git a/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/platform-preview/apple.vue b/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/platform-preview/apple.vue index d23386c25a..5447eb0491 100644 --- a/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/platform-preview/apple.vue +++ b/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/platform-preview/apple.vue @@ -16,6 +16,7 @@ const theme = computed(() => { if (bg_image?.url) { theme.bg_image = `url(${encodeURI(store.getSettingValue("background").url)})`; theme.bg_color = "#000"; + theme.fg_color = '#fff' } return theme; }); diff --git a/src/pretix/plugins/wallet/static/pretixplugins/wallet/index.d.ts b/src/pretix/plugins/wallet/static/pretixplugins/wallet/index.d.ts index 9b2ed487c5..97e646313b 100644 --- a/src/pretix/plugins/wallet/static/pretixplugins/wallet/index.d.ts +++ b/src/pretix/plugins/wallet/static/pretixplugins/wallet/index.d.ts @@ -105,5 +105,5 @@ type PlatformLayout = { file_settings: Record; }; type ServerSideFile = { url: string; name: string }; -type ClientSideFile = { file: File | null; identifier?: string }; +type ClientSideFile = { file: File | null; identifier?: string; url: string }; type WalletFile = ServerSideFile | ClientSideFile; diff --git a/src/pretix/plugins/wallet/static/pretixplugins/wallet/walletStore.ts b/src/pretix/plugins/wallet/static/pretixplugins/wallet/walletStore.ts index 3bf72e9453..8bcd500a01 100644 --- a/src/pretix/plugins/wallet/static/pretixplugins/wallet/walletStore.ts +++ b/src/pretix/plugins/wallet/static/pretixplugins/wallet/walletStore.ts @@ -92,12 +92,7 @@ export function createWalletStore(config: { this.layout.settings[setting.identifier]; } else if (setting.type == "image") { const val = this.layout.file_settings[setting.identifier]; - if (val && "file" in val && val.file) { - settings[setting.identifier] = { - name: val.file.name, - url: URL.createObjectURL(val.file), - }; - } else if (val && "url" in val && val.url) { + if (val) { settings[setting.identifier] = val; } else { settings[setting.identifier] = null; @@ -172,9 +167,7 @@ export function createWalletStore(config: { }, load() { // TODO: error handling / proper api client - fetch( - `${this.baseUrl}${this.layoutId}/`, - ) + fetch(`${this.baseUrl}${this.layoutId}/`) .then((x) => x.json()) .then((x) => { this.parseServerLayout(x); @@ -232,7 +225,7 @@ export function createWalletStore(config: { } } }, - getSettingValue(identifier: string): Setting { + getSettingValue(identifier: string): Setting | { url: string } { const setting = this.getSetting(identifier); if (!setting) return; @@ -245,12 +238,7 @@ export function createWalletStore(config: { return this.layout.settings[setting.identifier] || setting.default; } else if (setting.type == "image") { const val = this.layout.file_settings[setting.identifier]; - if (val && "file" in val && val.file) { - return { - name: val.file.name, - url: URL.createObjectURL(val.file), - }; - } else if (val && "url" in val && val.url) { + if (val && "url" in val && val.url) { return val; } else if (setting.default) { return { url: setting.default }; @@ -261,13 +249,23 @@ export function createWalletStore(config: { const setting = this.getSetting(identifier); if (!setting) return; - if ( - setting.type === "image" && - (value instanceof File || value === null) - ) { - this.layout.file_settings[setting.identifier] = { - file: value as File | null, - }; + if (setting.type === "image") { + if (this.layout.file_settings[setting.identifier]?.url) { + URL.revokeObjectURL( + this.layout.file_settings[setting.identifier].url, + ); + } + if (value instanceof File) { + this.layout.file_settings[setting.identifier] = { + file: value, + url: value === null ? null : URL.createObjectURL(value), + name: value.name, + }; + } else if (value === null) { + this.layout.file_settings[setting.identifier] = { + file: null, + }; + } } else if ( (setting.type == "text" || setting.type == "color") && typeof value == "string" @@ -303,9 +301,7 @@ export function createWalletStore(config: { ( await Promise.all( Object.entries(layout.file_settings).map(async ([k, v]) => { - if ("url" in v) { - return; - } else if ("identifier" in v) { + if ("identifier" in v) { return [k, v.identifier]; } else if ("file" in v && v.file instanceof File) { return [k, await this.uploadFile(v)]; diff --git a/src/pretix/plugins/wallet/styles/apple.py b/src/pretix/plugins/wallet/styles/apple.py index 18895cf372..7fd1daf7f7 100644 --- a/src/pretix/plugins/wallet/styles/apple.py +++ b/src/pretix/plugins/wallet/styles/apple.py @@ -19,12 +19,20 @@ from django.utils.translation import gettext as _ from pretix.base.models import OrderPosition from pretix.plugins.wallet.i18n import ( - FormattingLocalizableString, GettextLocalizableString, Localizable, + FormattingLocalizableString, + GettextLocalizableString, + Localizable, MaybeTranslatedString, ) from pretix.plugins.wallet.styles.base import ( - ColorSettingsField, FieldGroup, FieldGroupDisplay, FloatSettingsField, - ImageSettingsField, PassStyle, PlaceholderFieldEntry, TextFieldGroup, + ColorSettingsField, + FieldGroup, + FieldGroupDisplay, + FloatSettingsField, + ImageSettingsField, + PassStyle, + PlaceholderFieldEntry, + TextFieldGroup, WalletPlatform, ) @@ -162,18 +170,24 @@ class AppleWalletStyle(PassStyle): ImageSettingsField( identifier="logo", label=_("Logo"), - help_text="Will be displayed on the top left corner of the pass", + help_text=_("Will be displayed on the top left corner of the pass"), default="pretixplugins/wallet/logo.png", ), ImageSettingsField( identifier="icon", label=_("Icon"), - help_text="Will be displayed as the file icon", + help_text=_("Will be displayed as the file icon"), default="pretixplugins/wallet/icon.png", ), ImageSettingsField(identifier="background", label=_("Background Image")), ColorSettingsField(identifier="bg_color", label=_("Background Color")), - ColorSettingsField(identifier="fg_color", label=_("Foreground Color")), + ColorSettingsField( + identifier="fg_color", + label=_("Foreground Color"), + help_text=_( + "This color is ignored if a background image is set. Instead, the text will be displayed in white." + ), + ), ColorSettingsField(identifier="label_color", label=_("Label Color")), FloatSettingsField(identifier="lat", label=_("Latitude"), min=-90, max=90), FloatSettingsField( @@ -223,7 +237,12 @@ class AppleWalletStyle(PassStyle): # TODO: Apples specs says this should be "specified as a CSS-style RGB triple, such as rgb(100, 10, 110).", but hex codes work as well if bg_color := self.layout["settings"].get("bg_color"): pass_json["backgroundColor"] = bg_color - if fg_color := self.layout["settings"].get("fg_color"): + if self.file_settings.get("background"): + # iOS ignores the set foregroundColor if a background is set and uses white instead. + # Explicitly set white in this case so the pass looks the same on all platforms + # https://developer.apple.com/forums/thread/809417 + pass_json["foregroundColor"] = "#ffffff" + elif fg_color := self.layout["settings"].get("fg_color"): pass_json["foregroundColor"] = fg_color if label_color := self.layout["settings"].get("label_color"): pass_json["labelColor"] = label_color @@ -342,9 +361,7 @@ class AppleWalletEventTicket(AppleWalletStyle): default_entries=[ PlaceholderFieldEntry( content="admission_or_date_from", - label=GettextLocalizableString.gettext( - "Admission" - ), + label=GettextLocalizableString.gettext("Admission"), ), ], ), @@ -370,9 +387,7 @@ class AppleWalletEventTicket(AppleWalletStyle): default_entries=[ PlaceholderFieldEntry( content="item_with_variation", - label=GettextLocalizableString.gettext( - "Product" - ), + label=GettextLocalizableString.gettext("Product"), ) ], ), @@ -386,24 +401,18 @@ class AppleWalletEventTicket(AppleWalletStyle): default_entries=[ PlaceholderFieldEntry( content="seat", - label=GettextLocalizableString.gettext( - "Seat" - ), + label=GettextLocalizableString.gettext("Seat"), ), PlaceholderFieldEntry( content="attendee_name", ), PlaceholderFieldEntry( content="program_start", - label=GettextLocalizableString.gettext( - "From" - ), + label=GettextLocalizableString.gettext("From"), ), PlaceholderFieldEntry( content="program_end", - label=GettextLocalizableString.gettext( - "To" - ), + label=GettextLocalizableString.gettext("To"), ), ], ), @@ -432,9 +441,7 @@ class AppleWalletEventTicket(AppleWalletStyle): ), PlaceholderFieldEntry( content="order_email", - label=GettextLocalizableString.gettext( - "Ordered by" - ), + label=GettextLocalizableString.gettext("Ordered by"), ), PlaceholderFieldEntry( content="organizer", @@ -471,9 +478,7 @@ class AppleWalletEventTicket(AppleWalletStyle): strings.add_entry(f"{prefix}-{i}-label", converted_field["label"]) converted_field["label"] = f"{prefix}-{i}-label" - if isinstance( - converted_field["value"], Localizable - ): + if isinstance(converted_field["value"], Localizable): strings.add_entry(f"{prefix}-{i}-value", converted_field["value"]) converted_field["value"] = f"{prefix}-{i}-value" converted.append(converted_field)