combined buy button for awards and hats

pull/143/head
Aevann 2023-04-24 17:08:40 +02:00
parent 938b9b66a8
commit a37fca393d
19 changed files with 50 additions and 76 deletions

View File

@ -100,17 +100,16 @@ function pick(kind, price, coins, marseybux) {
coins = parseInt(coins)
marseybux = parseInt(marseybux)
const buy1 = document.getElementById('buy1')
if (marseybux >= price && kind != "grass")
buy1.disabled=false;
else
buy1.disabled=true;
const buy = document.getElementById('buy')
const buy2 = document.getElementById('buy2')
if (coins >= price && kind != "benefactor")
buy2.disabled=false;
if (kind == "grass" && coins < price)
buy.disabled = true;
else if (kind == "benefactor" && marseybux < price)
buy.disabled = true;
else if (coins+marseybux < price)
buy.disabled = true;
else
buy2.disabled=true;
buy.disabled = false;
let ownednum = Number(document.getElementById(`${kind}-owned`).textContent);
document.getElementById('giveaward').disabled = (ownednum == 0);
@ -144,10 +143,9 @@ function pick(kind, price, coins, marseybux) {
document.getElementById('award_price').textContent = price;
}
function buy(mb) {
function buy() {
const kind = document.getElementById('kind').value;
url = `/buy/${kind}`
if (mb) url += "?mb=true"
const xhr = createXhrWithFormKey(url);
xhr[0].onload = function() {
let data
@ -163,9 +161,6 @@ function buy(mb) {
let ownednum = Number(owned.textContent) + 1;
owned.textContent = ownednum
}
const currency = mb ? "bux" : "coins";
document.getElementById(`user-${currency}-amount`).innerText = parseInt(document.getElementById(`user-${currency}-amount`).innerText) - global_price;
}
};

View File

@ -104,7 +104,7 @@ for (const element of btns_to_disable) {
function disable_btn(t) {
if (!t.classList.contains('disabled')) {
const isShopConfirm = t.id.startsWith('buy1-') || t.id.startsWith('buy2-') || t.id.startsWith('giveaward')
const isShopConfirm = t.id.startsWith('buy-') || t.id.startsWith('giveaward')
if (!isShopConfirm) {
t.classList.add('disabled');

View File

@ -33,7 +33,7 @@ function createXhrWithFormKey(url, method="POST", form=new FormData()) {
}
function postToast(t, url, data, extraActionsOnSuccess, method="POST") {
const isShopConfirm = t.id.startsWith('buy1-') || t.id.startsWith('buy2-') || t.id.startsWith('giveaward')
const isShopConfirm = t.id.startsWith('buy-') || t.id.startsWith('giveaward')
if (!isShopConfirm)
{

View File

@ -205,6 +205,7 @@ class User(Base):
def charge_account(self, currency, amount, **kwargs):
in_db = g.db.query(User).filter(User.id == self.id).with_for_update().one()
succeeded = False
charged_coins = 0
should_check_balance = kwargs.get('should_check_balance', True)
@ -214,6 +215,7 @@ class User(Base):
if not should_check_balance or account_balance >= amount:
g.db.query(User).filter(User.id == self.id).update({ User.coins: User.coins - amount })
succeeded = True
charged_coins = amount
elif currency == 'marseybux':
account_balance = in_db.marseybux
@ -228,19 +230,20 @@ class User(Base):
subtracted_mbux = in_db.marseybux
subtracted_coins = amount - subtracted_mbux
if subtracted_coins > in_db.coins:
return False
return (False, 0)
g.db.query(User).filter(User.id == self.id).update({
User.marseybux: User.marseybux - subtracted_mbux,
User.coins: User.coins - subtracted_coins,
})
succeeded = True
charged_coins = subtracted_coins
if succeeded:
g.db.add(self)
g.db.flush()
return succeeded
return (succeeded, charged_coins)
@property
@lazy

View File

@ -112,7 +112,7 @@ def purchase_lottery_tickets(v, quantity=1):
if (most_recent_lottery is None):
return False, "There is no active lottery!"
if not v.charge_account('coins', LOTTERY_TICKET_COST * quantity):
if not v.charge_account('coins', LOTTERY_TICKET_COST * quantity)[0]:
return False, "You don't have enough coins"
v.currently_held_lottery_tickets += quantity
v.total_held_lottery_tickets += quantity

View File

@ -85,7 +85,7 @@ def get_active_roulette_games():
def charge_gambler(gambler, amount, currency):
charged = gambler.charge_account(currency, amount)
charged = gambler.charge_account(currency, amount)[0]
if not charged:
raise Exception("Gambler cannot afford charge.")

View File

@ -24,7 +24,7 @@ payout_to_symbols = {
def casino_slot_pull(gambler, wager_value, currency):
over_min = wager_value >= minimum_bet
under_max = wager_value <= maximum_bet
charged = gambler.charge_account(currency, wager_value)
charged = gambler.charge_account(currency, wager_value)[0]
if (over_min and under_max and charged):
payout = determine_payout()

View File

@ -82,7 +82,7 @@ def get_active_twentyone_game_state(gambler):
def charge_gambler(gambler, amount, currency):
charged = gambler.charge_account(currency, amount)
charged = gambler.charge_account(currency, amount)[0]
if not charged:
raise Exception("Gambler cannot afford charge.")

View File

@ -59,9 +59,6 @@ def shop(v:User):
@limiter.limit("100/minute;200/hour;1000/day", key_func=get_ID)
@auth_required
def buy(v:User, award):
if award == 'benefactor' and not request.values.get("mb"):
abort(403, "You can only buy the Benefactor award with marseybux!")
if award == 'ghost' and v.admin_level < PERMS['BUY_GHOST_AWARD']:
abort(403, "Only admins can buy this award")
@ -76,19 +73,19 @@ def buy(v:User, award):
award_title = AWARDS[award]['title']
price = int(og_price * v.discount)
if request.values.get("mb"):
if award == "grass":
abort(403, "You can't buy the grass award with marseybux!")
charged = v.charge_account('marseybux', price)
if not charged:
abort(400, "Not enough marseybux!")
if award == "grass":
currency = 'coins'
elif award == "benefactor":
currency = 'marseybux'
else:
charged = v.charge_account('coins', price)
if not charged:
abort(400, "Not enough coins!")
currency = 'combined'
v.coins_spent += price
charged = v.charge_account(currency, price)[0]
if not charged:
abort(400, "Not enough coins/marseybux!")
v.coins_spent += charged[1]
if v.coins_spent >= 1000000:
badge_grant(badge_id=73, user=v)
elif v.coins_spent >= 500000:

View File

@ -35,7 +35,7 @@ def create_group(v):
if name == 'everyone' or g.db.get(Group, name):
return redirect(f"/ping_groups?error=This group already exists!")
if not v.charge_account('combined', GROUP_COST):
if not v.charge_account('combined', GROUP_COST)[0]:
return redirect(f"/ping_groups?error=You don't have enough coins or marseybux!")
g.db.add(v)

View File

@ -47,19 +47,11 @@ def buy_hat(v:User, hat_id):
if not hat.is_purchasable:
abort(403, "This hat is not for sale!")
if request.values.get("mb"):
charged = v.charge_account('marseybux', hat.price)
if not charged: abort(400, "Not enough marseybux!")
charged = v.charge_account('combined', hat.price)[0]
if not charged: abort(400, "Not enough coins/marseybux!")
hat.author.pay_account('marseybux', hat.price * 0.1)
currency = "marseybux"
else:
charged = v.charge_account('coins', hat.price)
if not charged: abort(400, "Not enough coins!")
v.coins_spent_on_hats += hat.price
hat.author.pay_account('coins', hat.price * 0.1)
currency = "coins"
v.coins_spent_on_hats += charged[1]
hat.author.pay_account('coins', hat.price * 0.1)
new_hat = Hat(user_id=v.id, hat_id=hat.id)
g.db.add(new_hat)
@ -69,7 +61,7 @@ def buy_hat(v:User, hat_id):
send_repeatable_notification(
hat.author.id,
f":marseycapitalistmanlet: @{v.username} has just bought `{hat.name}`, you have received your 10% cut ({int(hat.price * 0.1)} {currency}) :!marseycapitalistmanlet:"
f":marseycapitalistmanlet: @{v.username} has just bought `{hat.name}`, you have received your 10% cut ({int(hat.price * 0.1)} coins) :!marseycapitalistmanlet:"
)
if v.num_of_owned_hats >= 250:

View File

@ -26,7 +26,7 @@ def vote_option(option_id, v):
if option.exclusive == 2:
if option.parent.total_bet_voted(v):
abort(403, "You can't participate in a closed bet!")
if not v.charge_account('combined', POLL_BET_COINS):
if not v.charge_account('combined', POLL_BET_COINS)[0]:
abort(400, f"You don't have {POLL_BET_COINS} coins or marseybux!")
g.db.add(v)
autojanny = get_account(AUTOJANNY_ID)
@ -76,7 +76,7 @@ def vote_option_comment(option_id, v):
if option.exclusive == 2:
if option.parent.total_bet_voted(v):
abort(403, "You can't participate in a closed bet!")
if not v.charge_account('combined', POLL_BET_COINS):
if not v.charge_account('combined', POLL_BET_COINS)[0]:
abort(400, f"You don't have {POLL_BET_COINS} coins or marseybux!")
g.db.add(v)
autojanny = get_account(AUTOJANNY_ID)

View File

@ -360,7 +360,7 @@ def settings_personal_post(v):
else:
cost = HOUSE_JOIN_COST
success = v.charge_account('combined', cost)
success = v.charge_account('combined', cost)[0]
if not success: abort(403)
if house == "None": house = ''

View File

@ -375,7 +375,7 @@ def create_sub2(v):
if not valid_sub_regex.fullmatch(name):
return redirect(f"/create_hole?error=Name does not match the required format!")
if not v.charge_account('combined', HOLE_COST):
if not v.charge_account('combined', HOLE_COST)[0]:
return redirect(f"/create_hole?error=You don't have enough coins or marseybux!")
sub = get_sub_by_name(name, graceful=True)

View File

@ -355,7 +355,7 @@ def transfer_currency(v:User, username:str, currency_name:Literal['coins', 'mars
notif_text += f"\n\n> {reason}"
log_message += f"\n\n> {reason}"
if not v.charge_account(currency_name, amount):
if not v.charge_account(currency_name, amount)[0]:
abort(400, f"You don't have enough {currency_name}")
if not v.shadowbanned:

View File

@ -103,8 +103,7 @@ def vote_post_comment(target_id, new, v, cls, vote_cls):
existing.coins = coin_value
g.db.add(existing)
elif existing.vote_type != 0 and new == 0:
target.author.charge_account('coins', existing.coins,
should_check_balance=False)
target.author.charge_account('coins', existing.coins, should_check_balance=False)
target.author.truescore -= coin_delta
g.db.add(target.author)
g.db.delete(existing)

View File

@ -69,11 +69,7 @@
<td class="shop-table-actions" style="width:unset">
{% if hat.id not in owned_hat_ids and hat.is_purchasable %}
<div id="if-not-owned-{{hat.id}}">
<button type="button" id="buy1-{{hat.id}}" class="btn btn-success {% if v.coins < hat.price %}disabled{% endif %}" data-areyousure="postToastSwitch(this, '/buy_hat/{{hat.id}}', 'if-not-owned-{{hat.id}}', 'if-owned-{{hat.id}}', 'd-none', (xhr)=>{if(xhr.status == 200)document.getElementById('user-coins-amount').innerHTML-={{hat.price}}})" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)"><span class="m-auto">Buy</span></button>
{% if FEATURES['MARSEYBUX'] %}
<button type="button" id="buy2-{{hat.id}}" class="marseybux btn btn-success {% if v.marseybux < hat.price %}disabled{% endif %}" data-areyousure="postToastSwitch(this, '/buy_hat/{{hat.id}}?mb=true', 'if-not-owned-{{hat.id}}', 'if-owned-{{hat.id}}', 'd-none', (xhr)=>{if(xhr.status == 200)document.getElementById('user-bux-amount').innerHTML-={{hat.price}}})" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)"><span class="m-auto">MBux</span></button>
{% endif %}
<button type="button" id="buy-{{hat.id}}" class="btn btn-success {% if v.coins+v.marseybux < hat.price %}disabled{% endif %}" data-areyousure="postToastSwitch(this, '/buy_hat/{{hat.id}}', 'if-not-owned-{{hat.id}}', 'if-owned-{{hat.id}}', 'd-none')" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)"><span class="m-auto">Buy</span></button>
</div>
{% endif %}

View File

@ -79,9 +79,7 @@
<input autocomplete="off" id="giveaward" class="awardbtn btn btn-primary mt-3 fl-r" type="submit" data-nonce="{{g.nonce}}" data-onclick="giveaward(this)" value="Give Award" data-bs-dismiss="modal" disabled>
<button type="button" id="buy1" class="awardbtn btn btn-primary mt-3 mx-3 {% if not FEATURES['MARSEYBUX'] %}d-none{% endif %} fl-r" disabled data-areyousure="buy(true)" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)">Buy with marseybux</button>
<button type="button" id="buy2" class="awardbtn btn btn-primary mt-3 fl-r" disabled data-areyousure="buy()" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)">Buy</button>
<button type="button" id="buy" class="awardbtn btn btn-primary mt-3 mr-3 fl-r" disabled data-areyousure="buy()" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)">Buy</button>
<div id="award_price_block" class="fl-r mt-4 mr-3 d-none text-small-sm">
Price: <span id="award_price"></span> coins/marseybux

View File

@ -51,27 +51,21 @@
</thead>
<tbody>
{% for a in awards %}
{% set kind = a['kind'] %}
{% set price = a['price'] %}
<tr>
<td class="shop-table-icon"><i class="{{a['icon']}} {{a['color']}}" style="font-size: 30px"></i></td>
<td class="shop-table-title">{{a['title']}}</td>
{% if a['baseprice'] != a['price'] %}
{% if a['baseprice'] != price %}
<td class="shop-table-price">
<span class="discounted-price">{{a['baseprice']}}</span> <em class="text-success">{{a['price']}}</em>
<span class="discounted-price">{{a['baseprice']}}</span> <em class="text-success">{{price}}</em>
</td>
{% else %}
<td class="shop-table-price">{{a['price']}}</td>
<td class="shop-table-price">{{price}}</td>
{% endif %}
<td class="shop-table-owned">{{a['owned']}}</td>
{% set kind = a['kind'] %}
<td class="shop-table-actions">
{% if kind != "benefactor" %}
<button type="button" id="buy1-{{loop.index}}" class="btn btn-success {% if v.coins < a['price'] %}disabled{% endif %}" data-areyousure="postToastSwitch(this,'/buy/{{kind}}')" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)"><span class="m-auto">Buy</span></button>
{% endif %}
{% if FEATURES['MARSEYBUX'] %}
{% if kind != "grass" %}
<button type="button" id="buy2-{{loop.index}}" class="marseybux btn btn-success {% if v.marseybux < a['price'] %}disabled{% endif %}" data-areyousure="postToastSwitch(this,'/buy/{{kind}}?mb=true')" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)"><span class="m-auto">Buy with MBux</span></button>
{% endif %}
{% endif %}
<button type="button" id="buy-{{loop.index}}" class="btn btn-success {% if v.coins+v.marseybux < price or (kind == 'grass' and v.coins < price) or (kind == 'benefactor' and v.marseybux < price) %}disabled{% endif %}" data-areyousure="postToastSwitch(this,'/buy/{{kind}}')" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)"><span class="m-auto">Buy</span></button>
</td>
<td class="shop-table-description">{{a['description']}}</td>
</tr>