This commit is contained in:
2026-06-13 01:34:45 +02:00
parent 408b29896c
commit 3cb2e466d8
21 changed files with 1285 additions and 130 deletions
@@ -11,14 +11,11 @@ import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Checkbox } from '@/components/ui/checkbox';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import {
QSLPickPhotos, QSLGenerateProposals, QSLListTemplates, QSLGetTemplate,
QSLSaveTemplate, QSLSetDefaultTemplate, QSLDeleteTemplate, QSLSavePreview,
QSLPreviewDataURL, QSLResolvePreview, QSLStylePresets,
QSLGetEmailTemplates, QSLSaveEmailTemplates,
} from '../../../wailsjs/go/main/App';
import { main } from '../../../wailsjs/go/models';
import type {
CardTemplate, CardElement, QSOBox, RenderModel, QSLTemplateInfo, QSLPresetInfo,
} from './qslTypes';
@@ -66,9 +63,6 @@ export function QslDesignerModal({ open, onClose }: Props) {
const [presets, setPresets] = useState<QSLPresetInfo[]>([]);
const [fontFamilies, setFontFamilies] = useState<string[]>([]);
const [deleteArm, setDeleteArm] = useState(0);
const [mailSubject, setMailSubject] = useState('');
const [mailBody, setMailBody] = useState('');
const [mailSaved, setMailSaved] = useState(false);
const svgEl = useRef<SVGSVGElement | null>(null);
useEffect(() => {
@@ -80,7 +74,6 @@ export function QslDesignerModal({ open, onClose }: Props) {
setEditing(null);
void refreshSaved();
void QSLStylePresets().then((p) => setPresets(p as QSLPresetInfo[]));
void QSLGetEmailTemplates().then((t) => { setMailSubject(t.subject); setMailBody(t.body); setMailSaved(false); });
void loadFonts().then(({ fonts }) =>
setFontFamilies([...fonts.map((f) => f.family), 'system-bold-sans']));
}, [open]);
@@ -103,7 +96,7 @@ export function QslDesignerModal({ open, onClose }: Props) {
async function choosePhotos() {
try {
const paths = ((await QSLPickPhotos()) ?? []) as string[];
if (paths.length) setPhotoPaths(paths.slice(0, 6));
if (paths.length) setPhotoPaths(paths.slice(0, 3));
} catch (e) {
setError(String(e));
}
@@ -237,7 +230,7 @@ export function QslDesignerModal({ open, onClose }: Props) {
return (
<Dialog open={open} onOpenChange={(v) => !v && onClose()}>
<DialogContent className="max-w-[1180px]">
<DialogContent className="max-w-[1260px]">
<DialogHeader>
<DialogTitle className="flex items-center gap-2">
<Sparkles className="size-5 text-amber-500" />
@@ -261,7 +254,7 @@ export function QslDesignerModal({ open, onClose }: Props) {
<section className="space-y-2">
<h3 className="text-sm font-semibold">New design</h3>
<p className="text-xs text-muted-foreground">
Pick 16 photos OpsLog analyzes them and proposes three card designs
Pick 13 photos OpsLog analyzes them and proposes three card designs
with your callsign, name, zones and country placed automatically.
</p>
<div className="flex items-center gap-2">
@@ -317,25 +310,9 @@ export function QslDesignerModal({ open, onClose }: Props) {
</div>
</section>
<section className="space-y-2">
<h3 className="text-sm font-semibold">eQSL e-mail message</h3>
<p className="text-xs text-muted-foreground">
{'{CALL}'} {'{DATE}'} {'{BAND}'} {'{MODE}'} {'{MYCALL}'} fill in per QSO.
</p>
<Input className="h-8" value={mailSubject} placeholder="Subject"
onChange={(e) => { setMailSubject(e.target.value); setMailSaved(false); }} />
<Textarea rows={3} value={mailBody} placeholder="Body"
onChange={(e) => { setMailBody(e.target.value); setMailSaved(false); }} />
<Button variant="outline" size="sm" disabled={mailSaved}
onClick={async () => {
try {
await QSLSaveEmailTemplates(new main.QSLEmailTemplates({ subject: mailSubject, body: mailBody }));
setMailSaved(true);
} catch (e) { setError(String(e)); }
}}>
{mailSaved ? 'Saved' : 'Save message'}
</Button>
</section>
<p className="text-xs text-muted-foreground">
The eQSL e-mail message and the auto-send option are in Settings E-mail (SMTP).
</p>
</div>
)}
@@ -392,6 +369,7 @@ export function QslDesignerModal({ open, onClose }: Props) {
onPatchElement={patchElement}
onPatchBox={patchBox}
onScrim={onScrim}
onSelect={setSel}
/>
</div>
)}