When a user is thanking, check state to see if other user thanked first, if so switch new_state to THANKED_BY_BOTH. fixes #13
This commit is contained in:
parent
52663c83ef
commit
a83ce746b5
7 changed files with 35 additions and 42 deletions
|
|
@ -26,9 +26,9 @@ class CardDetailView(DetailView):
|
||||||
|
|
||||||
class TradeOfferHaveCardListView(ListView):
|
class TradeOfferHaveCardListView(ListView):
|
||||||
model = TradeOffer
|
model = TradeOffer
|
||||||
template_name = "cards/_trade_offer_list.html"
|
template_name = "trades/_trade_offer_list.html"
|
||||||
context_object_name = "trade_offers"
|
context_object_name = "offers"
|
||||||
paginate_by = 6
|
paginate_by = 2
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
card_id = self.kwargs.get("pk")
|
card_id = self.kwargs.get("pk")
|
||||||
|
|
@ -46,9 +46,9 @@ class TradeOfferHaveCardListView(ListView):
|
||||||
|
|
||||||
class TradeOfferWantCardListView(ListView):
|
class TradeOfferWantCardListView(ListView):
|
||||||
model = TradeOffer
|
model = TradeOffer
|
||||||
template_name = "cards/_trade_offer_list.html"
|
template_name = "trades/_trade_offer_list.html"
|
||||||
context_object_name = "trade_offers"
|
context_object_name = "offers"
|
||||||
paginate_by = 6
|
paginate_by = 2
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
card_id = self.kwargs.get("pk")
|
card_id = self.kwargs.get("pk")
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
{% load trade_offer_tags %}
|
|
||||||
{% if trade_offers %}
|
|
||||||
<div class="flex flex-row flex-wrap gap-1 justify-center items-start">
|
|
||||||
{% for offer in trade_offers %}
|
|
||||||
{% render_trade_offer offer %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<p class="text-gray-500">No trade offers found.</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{% load trade_offer_tags pagination_tags %}
|
{% load trade_offer_tags pagination_tags %}
|
||||||
|
|
||||||
<div class="flex flex-row gap-6 md:gap-2 lg:gap-6 flex-wrap justify-center py-6">
|
<div class="flex flex-row flex-wrap gap-6 md:gap-2 lg:gap-6 justify-center items-start py-6">
|
||||||
{% for offer in offers %}
|
{% for offer in offers %}
|
||||||
{% if offer.accepted_by %}
|
{% if offer.accepted_by %}
|
||||||
{# Render a trade acceptance using our new tag #}
|
{# Render a trade acceptance using our new tag #}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{% load gravatar card_badge cache %}
|
{% load gravatar card_badge cache %}
|
||||||
|
|
||||||
{% cache 60 trade_offer offer_pk %}
|
{% cache 60 trade_offer offer_pk %}
|
||||||
<div x-data="{ flipped: {{flipped|lower}}, offerExpanded: {{flipped|yesno:'false,true'}}, acceptanceExpanded: {{flipped|lower}} }" x-ref="tradeOffer" class="transition-all duration-500 trade-offer-card my-auto h-full w-auto justify-center">
|
<div x-data="{ flipped: {{flipped|lower}}, offerExpanded: {{flipped|yesno:'false,true'}}, acceptanceExpanded: {{flipped|lower}} }" x-ref="tradeOffer" class="transition-all duration-500 trade-offer-card">
|
||||||
<div class="flip-container">
|
<div class="flip-container">
|
||||||
<div{% if not on_detail_page %} @click="window.location.href = '{% url 'trade_offer_detail' pk=offer_pk %}'"{% endif %} class="flip-inner grid grid-cols-1 grid-rows-1 card bg-base-100 card-border shadow-lg w-90 transform transition-transform duration-500 ease-in-out{% if not on_detail_page %} cursor-pointer{% endif %}{%if flipped %} rotate-y-180{% endif %}"
|
<div{% if not on_detail_page %} @click="window.location.href = '{% url 'trade_offer_detail' pk=offer_pk %}'"{% endif %} class="flip-inner grid grid-cols-1 grid-rows-1 card bg-base-100 card-border shadow-lg w-90 transform transition-transform duration-500 ease-in-out{% if not on_detail_page %} cursor-pointer{% endif %}{%if flipped %} rotate-y-180{% endif %}"
|
||||||
:class="{'rotate-y-180': flipped}">
|
:class="{'rotate-y-180': flipped}">
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ class TradeAcceptance(models.Model):
|
||||||
REJECTED_BY_ACCEPTOR = 'REJECTED_BY_ACCEPTOR', 'Rejected by Acceptor'
|
REJECTED_BY_ACCEPTOR = 'REJECTED_BY_ACCEPTOR', 'Rejected by Acceptor'
|
||||||
|
|
||||||
# DRY improvement: define active states once as a class-level constant.
|
# DRY improvement: define active states once as a class-level constant.
|
||||||
ACTIVE_STATES = [
|
POSITIVE_STATES = [
|
||||||
AcceptanceState.ACCEPTED,
|
AcceptanceState.ACCEPTED,
|
||||||
AcceptanceState.SENT,
|
AcceptanceState.SENT,
|
||||||
AcceptanceState.RECEIVED,
|
AcceptanceState.RECEIVED,
|
||||||
|
|
@ -223,8 +223,8 @@ class TradeAcceptance(models.Model):
|
||||||
|
|
||||||
# A mapping for alternate action labels
|
# A mapping for alternate action labels
|
||||||
ALTERNATE_ACTION_LABELS = {
|
ALTERNATE_ACTION_LABELS = {
|
||||||
AcceptanceState.REJECTED_BY_INITIATOR: "Cancel This Trade",
|
AcceptanceState.REJECTED_BY_INITIATOR: "Reject This Trade",
|
||||||
AcceptanceState.REJECTED_BY_ACCEPTOR: "Cancel This Trade",
|
AcceptanceState.REJECTED_BY_ACCEPTOR: "Reject This Trade",
|
||||||
# Optionally add alternate labels for other states:
|
# Optionally add alternate labels for other states:
|
||||||
AcceptanceState.ACCEPTED: "Accept This Trade Offer",
|
AcceptanceState.ACCEPTED: "Accept This Trade Offer",
|
||||||
AcceptanceState.SENT: "Mark as Sent",
|
AcceptanceState.SENT: "Mark as Sent",
|
||||||
|
|
@ -321,6 +321,10 @@ class TradeAcceptance(models.Model):
|
||||||
if new_state not in [choice[0] for choice in self.AcceptanceState.choices]:
|
if new_state not in [choice[0] for choice in self.AcceptanceState.choices]:
|
||||||
raise ValueError(f"'{new_state}' is not a valid state.")
|
raise ValueError(f"'{new_state}' is not a valid state.")
|
||||||
|
|
||||||
|
if (new_state == self.AcceptanceState.THANKED_BY_ACCEPTOR and self.state == self.AcceptanceState.THANKED_BY_INITIATOR) or \
|
||||||
|
(new_state == self.AcceptanceState.THANKED_BY_INITIATOR and self.state == self.AcceptanceState.THANKED_BY_ACCEPTOR):
|
||||||
|
new_state = self.AcceptanceState.THANKED_BY_BOTH
|
||||||
|
|
||||||
if self.state in [
|
if self.state in [
|
||||||
self.AcceptanceState.THANKED_BY_BOTH,
|
self.AcceptanceState.THANKED_BY_BOTH,
|
||||||
self.AcceptanceState.REJECTED_BY_INITIATOR,
|
self.AcceptanceState.REJECTED_BY_INITIATOR,
|
||||||
|
|
@ -361,9 +365,7 @@ class TradeAcceptance(models.Model):
|
||||||
self.AcceptanceState.THANKED_BY_INITIATOR,
|
self.AcceptanceState.THANKED_BY_INITIATOR,
|
||||||
self.AcceptanceState.REJECTED_BY_INITIATOR,
|
self.AcceptanceState.REJECTED_BY_INITIATOR,
|
||||||
},
|
},
|
||||||
self.AcceptanceState.THANKED_BY_INITIATOR: {
|
self.AcceptanceState.THANKED_BY_INITIATOR: { },
|
||||||
self.AcceptanceState.REJECTED_BY_INITIATOR,
|
|
||||||
},
|
|
||||||
self.AcceptanceState.THANKED_BY_ACCEPTOR: {
|
self.AcceptanceState.THANKED_BY_ACCEPTOR: {
|
||||||
self.AcceptanceState.REJECTED_BY_INITIATOR,
|
self.AcceptanceState.REJECTED_BY_INITIATOR,
|
||||||
self.AcceptanceState.THANKED_BY_BOTH,
|
self.AcceptanceState.THANKED_BY_BOTH,
|
||||||
|
|
@ -379,14 +381,11 @@ class TradeAcceptance(models.Model):
|
||||||
self.AcceptanceState.REJECTED_BY_ACCEPTOR,
|
self.AcceptanceState.REJECTED_BY_ACCEPTOR,
|
||||||
},
|
},
|
||||||
self.AcceptanceState.RECEIVED: {
|
self.AcceptanceState.RECEIVED: {
|
||||||
self.AcceptanceState.THANKED_BY_ACCEPTOR,
|
self.AcceptanceState.THANKED_BY_ACCEPTOR, #allow early thanks (uses THANKED_BY_ACCEPTOR state)
|
||||||
self.AcceptanceState.REJECTED_BY_ACCEPTOR,
|
self.AcceptanceState.REJECTED_BY_ACCEPTOR
|
||||||
},
|
|
||||||
self.AcceptanceState.THANKED_BY_ACCEPTOR: {
|
|
||||||
self.AcceptanceState.REJECTED_BY_ACCEPTOR,
|
|
||||||
},
|
},
|
||||||
|
self.AcceptanceState.THANKED_BY_ACCEPTOR: { },
|
||||||
self.AcceptanceState.THANKED_BY_INITIATOR: {
|
self.AcceptanceState.THANKED_BY_INITIATOR: {
|
||||||
self.AcceptanceState.REJECTED_BY_ACCEPTOR,
|
|
||||||
self.AcceptanceState.THANKED_BY_BOTH,
|
self.AcceptanceState.THANKED_BY_BOTH,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ from django.conf import settings
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
|
|
||||||
ACTIVE_STATES = [
|
POSITIVE_STATES = [
|
||||||
TradeAcceptance.AcceptanceState.ACCEPTED,
|
TradeAcceptance.AcceptanceState.ACCEPTED,
|
||||||
TradeAcceptance.AcceptanceState.SENT,
|
TradeAcceptance.AcceptanceState.SENT,
|
||||||
TradeAcceptance.AcceptanceState.RECEIVED,
|
TradeAcceptance.AcceptanceState.RECEIVED,
|
||||||
|
|
@ -70,14 +70,14 @@ def trade_acceptance_pre_save(sender, instance, **kwargs):
|
||||||
def trade_acceptance_post_save(sender, instance, created, **kwargs):
|
def trade_acceptance_post_save(sender, instance, created, **kwargs):
|
||||||
delta = 0
|
delta = 0
|
||||||
if created:
|
if created:
|
||||||
if instance.state in ACTIVE_STATES:
|
if instance.state in POSITIVE_STATES:
|
||||||
delta = 1
|
delta = 1
|
||||||
else:
|
else:
|
||||||
old_state = getattr(instance, '_old_state', None)
|
old_state = getattr(instance, '_old_state', None)
|
||||||
if old_state is not None:
|
if old_state is not None:
|
||||||
if old_state in ACTIVE_STATES and instance.state not in ACTIVE_STATES:
|
if old_state in POSITIVE_STATES and instance.state not in POSITIVE_STATES:
|
||||||
delta = -1
|
delta = -1
|
||||||
elif old_state not in ACTIVE_STATES and instance.state in ACTIVE_STATES:
|
elif old_state not in POSITIVE_STATES and instance.state in POSITIVE_STATES:
|
||||||
delta = 1
|
delta = 1
|
||||||
|
|
||||||
if delta != 0:
|
if delta != 0:
|
||||||
|
|
@ -88,7 +88,7 @@ def trade_acceptance_post_save(sender, instance, created, **kwargs):
|
||||||
|
|
||||||
@receiver(post_delete, sender=TradeAcceptance)
|
@receiver(post_delete, sender=TradeAcceptance)
|
||||||
def trade_acceptance_post_delete(sender, instance, **kwargs):
|
def trade_acceptance_post_delete(sender, instance, **kwargs):
|
||||||
if instance.state in ACTIVE_STATES:
|
if instance.state in POSITIVE_STATES:
|
||||||
delta = -1
|
delta = -1
|
||||||
trade_offer = instance.trade_offer
|
trade_offer = instance.trade_offer
|
||||||
adjust_qty_for_trade_offer(trade_offer, instance.requested_card, side='have', delta=delta)
|
adjust_qty_for_trade_offer(trade_offer, instance.requested_card, side='have', delta=delta)
|
||||||
|
|
|
||||||
|
|
@ -498,9 +498,9 @@ class TradeOfferPNGView(View):
|
||||||
trade_offer = get_object_or_404(TradeOffer, pk=kwargs['pk'])
|
trade_offer = get_object_or_404(TradeOffer, pk=kwargs['pk'])
|
||||||
|
|
||||||
# If the image is already generated and stored, serve it directly.
|
# If the image is already generated and stored, serve it directly.
|
||||||
# if trade_offer.image:
|
if trade_offer.image and not request.GET.get("debug"):
|
||||||
# trade_offer.image.open()
|
trade_offer.image.open()
|
||||||
# return HttpResponse(trade_offer.image.read(), content_type="image/png")
|
return HttpResponse(trade_offer.image.read(), content_type="image/png")
|
||||||
|
|
||||||
# Acquire PostgreSQL advisory lock to prevent concurrent generation.
|
# Acquire PostgreSQL advisory lock to prevent concurrent generation.
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
|
|
@ -509,10 +509,10 @@ class TradeOfferPNGView(View):
|
||||||
cursor.execute("SELECT pg_advisory_lock(%s)", [lock_key])
|
cursor.execute("SELECT pg_advisory_lock(%s)", [lock_key])
|
||||||
try:
|
try:
|
||||||
# Double-check if the image was generated while waiting for the lock.
|
# Double-check if the image was generated while waiting for the lock.
|
||||||
# trade_offer.refresh_from_db()
|
trade_offer.refresh_from_db()
|
||||||
# if trade_offer.image:
|
if trade_offer.image and not request.GET.get("debug"):
|
||||||
# trade_offer.image.open()
|
trade_offer.image.open()
|
||||||
# return HttpResponse(trade_offer.image.read(), content_type="image/png")
|
return HttpResponse(trade_offer.image.read(), content_type="image/png")
|
||||||
|
|
||||||
tag_context = render_trade_offer_png(
|
tag_context = render_trade_offer_png(
|
||||||
{'request': request}, trade_offer, show_friend_code=True
|
{'request': request}, trade_offer, show_friend_code=True
|
||||||
|
|
@ -523,6 +523,10 @@ class TradeOfferPNGView(View):
|
||||||
raise ValueError("Could not determine image dimensions from tag_context")
|
raise ValueError("Could not determine image dimensions from tag_context")
|
||||||
html = render_to_string("templatetags/trade_offer_png.html", tag_context)
|
html = render_to_string("templatetags/trade_offer_png.html", tag_context)
|
||||||
|
|
||||||
|
# if query string has "debug=true", render the HTML instead of the PNG
|
||||||
|
if request.GET.get("debug") == "html":
|
||||||
|
return render(request, "trades/trade_offer_png_debug.html", {"html": html})
|
||||||
|
|
||||||
with sync_playwright() as p:
|
with sync_playwright() as p:
|
||||||
browser = p.chromium.launch(
|
browser = p.chromium.launch(
|
||||||
headless=True,
|
headless=True,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue