use <a> tags for card_badge and trade_offer clickable areas (except for main card_badge row on trade_offers, still uses @click for now because the a tag can't wrap that content for some reason). closes #14

This commit is contained in:
badblocks 2025-04-15 00:15:08 -07:00
parent 86b061c971
commit afaa392b2f
22 changed files with 247 additions and 227 deletions

View file

@ -55,15 +55,15 @@ class TradeAcceptanceCreateForm(forms.ModelForm):
elif default_friend_code and friend_codes.filter(pk=default_friend_code.pk).exists():
self.initial["accepted_by"] = default_friend_code.pk
# Update available requested_card choices from the TradeOffer's "have" side.
active_states = [
TradeAcceptance.AcceptanceState.ACCEPTED,
TradeAcceptance.AcceptanceState.SENT,
TradeAcceptance.AcceptanceState.RECEIVED,
]
self.fields["requested_card"].queryset = trade_offer.have_cards_available_qs
# Fix: Convert available 'have' cards (from through model) to Card objects.
self.fields["requested_card"].queryset = Card.objects.filter(
pk__in=trade_offer.have_cards_available_qs.values_list("card_id", flat=True)
)
self.fields["offered_card"].queryset = trade_offer.want_cards_available_qs
# Similarly for offered_card.
self.fields["offered_card"].queryset = Card.objects.filter(
pk__in=trade_offer.want_cards_available_qs.values_list("card_id", flat=True)
)
def clean(self):
"""

View file

@ -1,4 +1,4 @@
# Generated by Django 5.1.2 on 2025-04-14 04:07
# Generated by Django 5.1.2 on 2025-04-14 20:58
import django.db.models.deletion
from django.db import migrations, models

View file

@ -94,6 +94,8 @@ class TradeOffer(models.Model):
if len(rarity_levels) > 1:
raise ValidationError("All cards in a trade offer must have the same rarity.")
first_card = cards[0]
if first_card.rarity_level > 5:
raise ValidationError("Cannot trade cards above one-star rarity.")
if self.rarity_level != first_card.rarity_level or self.rarity_icon != first_card.rarity_icon:
self.rarity_level = first_card.rarity_level
self.rarity_icon = first_card.rarity_icon
@ -140,11 +142,11 @@ class TradeOfferHaveCard(models.Model):
return self.quantity - self.qty_accepted
def __str__(self):
return f"{self.card.name} x{self.quantity} (Accepted: {self.qty_accepted})"
return f"#{self.card.cardnum} {self.card.cardset} {self.card.rarity_icon} {self.card.name}"
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
self.trade_offer.update_rarity_fields()
super().save(*args, **kwargs)
def delete(self, *args, **kwargs):
trade_offer = self.trade_offer
@ -174,7 +176,7 @@ class TradeOfferWantCard(models.Model):
return self.quantity - self.qty_accepted
def __str__(self):
return f"{self.card.name} x{self.quantity} (Accepted: {self.qty_accepted})"
return f"#{self.card.cardnum} {self.card.cardset} {self.card.rarity_icon} {self.card.name}"
def save(self, *args, **kwargs):
super().save(*args, **kwargs)

View file

@ -40,7 +40,7 @@ def adjust_qty_for_trade_offer(trade_offer, card, side, delta):
def update_trade_offer_closed_status(trade_offer):
"""
Check if both sides of the trade offer meet the quantity requirement.
Mark the trade_offer as closed if all cards have qty_accepted
Mark the trade_offer as closed if all cards on one side have qty_accepted
greater than or equal to quantity; otherwise, mark it as open.
"""
have_complete = not TradeOfferHaveCard.objects.filter(
@ -107,6 +107,8 @@ def trade_acceptance_email_notification(sender, instance, created, **kwargs):
# return
acting_user = instance._actioning_user
del instance._actioning_user
state = instance.state
if state == TradeAcceptance.AcceptanceState.ACCEPTED:
@ -169,9 +171,6 @@ def trade_acceptance_email_notification(sender, instance, created, **kwargs):
[recipient_user.email],
)
# Clean up the temporary attribute.
del instance._actioning_user
@receiver(post_save, sender=TradeAcceptance)
def trade_acceptance_reputation_update(sender, instance, created, **kwargs):
"""

View file

@ -42,7 +42,7 @@ class TradeOfferCreateView(LoginRequiredMixin, CreateView):
context = super().get_context_data(**kwargs)
from cards.models import Card
# Ensure available_cards is a proper QuerySet
context["cards"] = Card.objects.all().order_by("name", "rarity_level")
context["cards"] = Card.objects.filter(rarity_level__lte=5).order_by("name", "rarity_level")
friend_codes = self.request.user.friend_codes.all()
if "initiated_by" in self.request.GET:
try:
@ -245,8 +245,8 @@ class TradeOfferSearchView(ListView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
from cards.models import Card
# Populate available_cards to re-populate the multiselects.
context["cards"] = Card.objects.all().order_by("name")
# Populate available_cards to re-populate the multiselects. Exclude cards with rarity level > 5.
context["cards"] = Card.objects.filter(rarity_level__lte=5).order_by("name", "rarity_level")
if self.request.method == "POST":
context["have_cards"] = self.request.POST.getlist("have_cards")
context["want_cards"] = self.request.POST.getlist("want_cards")
@ -515,7 +515,7 @@ class TradeOfferPNGView(View):
return HttpResponse(trade_offer.image.read(), content_type="image/png")
tag_context = render_trade_offer_png(
{'request': request}, trade_offer, show_friend_code=True
{'request': request}, trade_offer, show_friend_code=trade_offer.initiated_by.user.show_friend_code_on_link_previews
)
image_width = tag_context.get('image_width')
image_height = tag_context.get('image_height')
@ -547,7 +547,7 @@ class TradeOfferPNGView(View):
page.on("console", lambda msg: print(f"Console {msg.type}: {msg.text}"))
page.on("pageerror", lambda err: print(f"Page error: {err}"))
page.on("requestfailed", lambda req: print(f"Failed to load: {req.url} - {req.failure.error_text}"))
page.set_content(html, wait_until="domcontentloaded")
page.set_content(html, wait_until="networkidle")
element = page.wait_for_selector(".trade-offer-card-screenshot")
screenshot_bytes = element.screenshot(type="png", omit_background=True)
browser.close()