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 5c8a249d3f..868d0d460b 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 @@ -13,6 +13,7 @@ const props = defineProps<{ help_text?: string; filename?: string; current_url?: string; + default?: string; }>(); const id = useId(); @@ -57,7 +58,12 @@ const clearFile = () => { input(:id="id" @change="onChange" v-bind="$attrs" :required="$attrs.required && !current_url" type="file" style="display: inline" ref="inputRef") | {{ " " }} button.btn.btn-sm(v-if="selectedFile" @click.prevent="clearFile") {{ gettext("Clear") }} - .help-block(v-if="!!help_text") {{ help_text }} + .help-block(v-if="!!help_text || !!props.default") + template(v-if="!!help_text") {{ help_text }} + br(v-if="!!help_text && !!props.default") + template(v-if="!!props.default") + a(:href="props.default" data-lightbox="input") {{ gettext("Show default") }} + .help-block(v-if="!!errors" v-for="error in errors") {{ error }} diff --git a/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/preview/setting-preview.vue b/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/preview/setting-preview.vue index 9116bdbc07..e91ca0cb22 100644 --- a/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/preview/setting-preview.vue +++ b/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/preview/setting-preview.vue @@ -7,23 +7,26 @@ import PredefinedFieldgroupPreview from "./predefined-fieldgroup-preview.vue"; const store = inject(StoreKey)!; const { config } = defineProps<{ - config: SettingPreview; + config: SettingPreview; }>(); const settingDef = computed(() => { - return Object.fromEntries( - store.styles[store.layout.style].settings.map( - (x) => [x.identifier, x], - ), - )[config.setting]; + return Object.fromEntries( + store.styles[store.layout.style].settings.map((x) => [x.identifier, x]), + )[config.setting]; }); const settingValue = computed(() => { - const val = store.settings[config.setting]; - if (settingDef.value.type == "image" && val && 'file' in val && val.file) { - return URL.createObjectURL(val.file); - } else { - return val; - } + const val = store.settings[config.setting]; + if (settingDef.value.type == "image" && val && "file" in val && val.file) { + return URL.createObjectURL(val.file); + } else if ( + settingDef.value.type == "image" && + settingDef.value.attrs.default + ) { + return settingDef.value.attrs.default; + } else { + return val; + } }); diff --git a/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/settings-field.vue b/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/settings-field.vue index e404fa09e0..ecc526a263 100644 --- a/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/settings-field.vue +++ b/src/pretix/plugins/wallet/static/pretixplugins/wallet/components/settings-field.vue @@ -18,5 +18,5 @@ const store = inject(StoreKey)!; :inline="true" v-bind="field.attrs") FileInput(v-if='field.type == "image"' :label="field.label" :required="field.required" :help_text="field.help_text" @change="(v) => store.setSetting(field.identifier, v)" - :filename="store.settings[field.identifier]?.name" :current_url="store.settings[field.identifier]?.url") + :filename="store.settings[field.identifier]?.name" :current_url="store.settings[field.identifier]?.url" v-bind="field.attrs") diff --git a/src/pretix/plugins/wallet/styles/apple.py b/src/pretix/plugins/wallet/styles/apple.py index a4684e5a04..cbb25ef8a2 100644 --- a/src/pretix/plugins/wallet/styles/apple.py +++ b/src/pretix/plugins/wallet/styles/apple.py @@ -1,14 +1,15 @@ from typing import Any - +from django.templatetags.static import static from pretix.plugins.wallet.styles.base import ( + ColorSettingsField, FieldGroup, FieldGroupDisplay, FloatSettingsField, + ImageSettingsField, TextFieldGroup, WalletPlatform, PassStyle, PlaceholderFieldEntry, - SettingsField, ) from django.utils.translation import gettext as _, override from i18nfield.strings import LazyI18nString @@ -175,54 +176,26 @@ class AppleWalletStyle(PassStyle): @property def settings(self): return [ - SettingsField( + ImageSettingsField( identifier="logo", label=_("Logo"), - type="image", - required=False, help_text="Will be displayed on the top left corner of the pass", + default=static("pretixplugins/wallet/logo.png") ), - SettingsField( + ImageSettingsField( identifier="icon", label=_("Icon"), - type="image", - required=False, help_text="Will be displayed as the file icon", + default=static("pretixplugins/wallet/icon.png") ), - SettingsField( - identifier="background", - label=_("Background"), - type="image", - required=False, - ), + ImageSettingsField(identifier="background", label=_("Background")), + FloatSettingsField(identifier="lat", label=_("Latitude"), min=-90, max=90), FloatSettingsField( - identifier="lat", label=_("Latitude"), required=False, min=-90, max=90 - ), - FloatSettingsField( - identifier="long", - label=_("Longitude"), - required=False, - min=-180, - max=180, - ), - SettingsField( - identifier="bg_color", - label=_("Background Color"), - type="color", - required=False, - ), - SettingsField( - identifier="fg_color", - label=_("Foreground Color"), - type="color", - required=False, - ), - SettingsField( - identifier="label_color", - label=_("Label Color"), - type="color", - required=False, + identifier="long", label=_("Longitude"), min=-180, max=180 ), + ColorSettingsField(identifier="bg_color", label=_("Background Color")), + ColorSettingsField(identifier="fg_color", label=_("Foreground Color")), + ColorSettingsField(identifier="label_color", label=_("Label Color")), ] def pass_content(self, fields, strings): diff --git a/src/pretix/plugins/wallet/styles/base.py b/src/pretix/plugins/wallet/styles/base.py index 5db6ccee4e..962abb92ef 100644 --- a/src/pretix/plugins/wallet/styles/base.py +++ b/src/pretix/plugins/wallet/styles/base.py @@ -276,25 +276,6 @@ class SettingsField: help_text: str | None required: bool - def __init__( - self, - identifier: str, - label: str, - type: Literal["image", "text"] = "text", - help_text=None, - required: bool = False, - ): - self.identifier = identifier - self.label = label - self.type = type - self.help_text = help_text - self.required = required - - if type == "image" and required: - raise NotImplementedError( - "required image settings are currently unsupported" - ) - def asdict(self): return { "identifier": self.identifier, @@ -310,18 +291,71 @@ class SettingsField: return {} def layout_schema(self) -> dict[str, Any] | None: - if self.type == "string": - schema = {"type": "string"} - elif self.type == "float": - schema = {"type": "number"} - elif self.type == "color": - schema = {"type": ["string"]} - else: - assert self.type == "image" - return + raise NotImplementedError() + + +class TextSettingsField(SettingsField): + def __init__( + self, + identifier: str, + label: str, + help_text: str | None = None, + required: bool = False, + ): + self.identifier = identifier + self.label = label + self.type = "text" + self.help_text = help_text + self.required = required + + def layout_schema(self) -> dict[str, Any] | None: + schema = {"type": "string"} if not self.required: schema = {"oneOf": [schema, {"type": "null"}]} + return schema + +class ColorSettingsField(SettingsField): + def __init__( + self, + identifier: str, + label: str, + help_text: str | None = None, + required: bool = False, + ): + self.identifier = identifier + self.label = label + self.type = "color" + self.help_text = help_text + self.required = required + + def layout_schema(self) -> dict[str, Any] | None: + schema = {"type": "string"} + if not self.required: + schema = {"oneOf": [schema, {"type": "null"}]} + return schema + + +class ImageSettingsField(SettingsField): + def __init__( + self, + identifier: str, + label: str, + help_text: str | None = None, + default: str | None = None + ): + self.identifier = identifier + self.label = label + self.type = "image" + self.help_text = help_text + self.required = False + self.default = default + + @property + def attrs(self): + return {"default": self.default} + + def layout_schema(self): return