546 lines
22 KiB
Python
546 lines
22 KiB
Python
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import datetime
|
|
from collections.abc import Awaitable, Callable
|
|
|
|
import discord
|
|
from discord import app_commands
|
|
|
|
import economy
|
|
import strings as S
|
|
|
|
|
|
def register_economy_profile_commands(
|
|
tree: app_commands.CommandTree,
|
|
coin: Callable[[int], str],
|
|
cd_ts: Callable[[datetime.timedelta], str],
|
|
ensure_level_role: Callable[[discord.Member, int], Awaitable[None]],
|
|
) -> None:
|
|
def _profile_main_embed(target: discord.User | discord.Member, data: dict) -> discord.Embed:
|
|
exp = data.get("exp", 0)
|
|
level = economy.get_level(exp)
|
|
role_name = economy.level_role_name(level)
|
|
next_level = level + 1
|
|
exp_this = economy.exp_for_level(level)
|
|
exp_next = economy.exp_for_level(next_level)
|
|
progress = exp - exp_this
|
|
needed = exp_next - exp_this
|
|
pct = progress / needed if needed > 0 else 1.0
|
|
filled = int(pct * 12)
|
|
bar = "█" * filled + "░" * (12 - filled)
|
|
embed = discord.Embed(
|
|
title=S.PROFILE_UI["main_title"].format(name=target.display_name),
|
|
color=0xF4C430,
|
|
)
|
|
embed.add_field(name=S.PROFILE_UI["f_balance"], value=coin(data.get("balance", 0)), inline=True)
|
|
embed.add_field(
|
|
name=S.PROFILE_UI["f_level"],
|
|
value=S.PROFILE_UI["level_val"].format(level=level, role=role_name),
|
|
inline=True,
|
|
)
|
|
streak = data.get("daily_streak", 0)
|
|
if streak:
|
|
embed.add_field(
|
|
name=S.PROFILE_UI["f_streak"],
|
|
value=S.BALANCE_UI["streak_val"].format(streak=streak),
|
|
inline=True,
|
|
)
|
|
p_level = data.get("prestige_level", 0)
|
|
if p_level > 0:
|
|
p_pp = data.get("prestige_points", 0)
|
|
embed.add_field(
|
|
name=S.PROFILE_UI["f_prestige"],
|
|
value=S.PROFILE_UI["prestige_val"].format(level=p_level, pp=p_pp),
|
|
inline=True,
|
|
)
|
|
jail_remaining = economy._is_jailed(data)
|
|
if jail_remaining:
|
|
embed.add_field(name=S.PROFILE_UI["f_jail"], value=cd_ts(jail_remaining), inline=True)
|
|
embed.add_field(
|
|
name=S.PROFILE_UI["f_progress"].format(next=next_level),
|
|
value=S.PROFILE_UI["progress_bar"].format(bar=bar, done=progress, needed=needed),
|
|
inline=False,
|
|
)
|
|
if level < 10:
|
|
embed.set_footer(text=S.PROFILE_UI["footer_t1"])
|
|
elif level < 20:
|
|
embed.set_footer(text=S.PROFILE_UI["footer_t2"])
|
|
else:
|
|
embed.set_footer(text=S.PROFILE_UI["footer_t3"])
|
|
return embed
|
|
|
|
def _profile_items_embed(target: discord.User | discord.Member, data: dict) -> discord.Embed:
|
|
embed = discord.Embed(
|
|
title=S.PROFILE_UI["items_title"].format(name=target.display_name),
|
|
color=0xF4C430,
|
|
)
|
|
uses_map = data.get("item_uses", {})
|
|
item_lines = []
|
|
for item_id in data.get("items", []):
|
|
if item_id not in economy.SHOP:
|
|
continue
|
|
line = f"{economy.SHOP[item_id]['emoji']} **{economy.SHOP[item_id]['name']}**"
|
|
if item_id in uses_map:
|
|
uses = uses_map[item_id]
|
|
line += (
|
|
S.BALANCE_UI["uses_one"].format(uses=uses)
|
|
if uses == 1
|
|
else S.BALANCE_UI["uses_many"].format(uses=uses)
|
|
)
|
|
item_lines.append(line)
|
|
embed.description = "\n".join(item_lines) if item_lines else S.PROFILE_UI["items_empty"]
|
|
return embed
|
|
|
|
def _profile_stats_embed(target: discord.User | discord.Member, data: dict) -> discord.Embed:
|
|
def _s(key: str) -> int:
|
|
return data.get(key, 0)
|
|
|
|
embed = discord.Embed(
|
|
title=S.PROFILE_UI["stats_title"].format(name=target.display_name),
|
|
color=0x5865F2,
|
|
)
|
|
embed.add_field(
|
|
name=S.STATS_UI["economy_field"],
|
|
value=S.STATS_UI["economy_val"].format(
|
|
peak=coin(_s("peak_balance")),
|
|
earned=coin(_s("lifetime_earned")),
|
|
lost=coin(_s("lifetime_lost")),
|
|
),
|
|
inline=True,
|
|
)
|
|
embed.add_field(
|
|
name=S.STATS_UI["work_field"],
|
|
value=S.STATS_UI["work_val"].format(work=_s("work_count"), beg=_s("beg_count")),
|
|
inline=True,
|
|
)
|
|
embed.add_field(name="\u200b", value="\u200b", inline=False)
|
|
embed.add_field(
|
|
name=S.STATS_UI["gamble_field"],
|
|
value=S.STATS_UI["gamble_val"].format(
|
|
wagered=coin(_s("total_wagered")),
|
|
win=coin(_s("biggest_win")),
|
|
loss=coin(_s("biggest_loss")),
|
|
jackpots=_s("slots_jackpots"),
|
|
),
|
|
inline=True,
|
|
)
|
|
embed.add_field(
|
|
name=S.STATS_UI["crime_field"],
|
|
value=S.STATS_UI["crime_val"].format(
|
|
crimes=_s("crimes_attempted"),
|
|
succeeded=_s("crimes_succeeded"),
|
|
heists=_s("heists_joined"),
|
|
heists_won=_s("heists_won"),
|
|
jailed=_s("times_jailed"),
|
|
bail=coin(_s("total_bail_paid")),
|
|
),
|
|
inline=True,
|
|
)
|
|
embed.add_field(name="\u200b", value="\u200b", inline=False)
|
|
embed.add_field(
|
|
name=S.STATS_UI["social_field"],
|
|
value=S.STATS_UI["social_val"].format(
|
|
given=coin(_s("total_given")),
|
|
received=coin(_s("total_received")),
|
|
),
|
|
inline=True,
|
|
)
|
|
embed.add_field(
|
|
name=S.STATS_UI["records_field"],
|
|
value=S.STATS_UI["records_val"].format(streak=_s("best_daily_streak")),
|
|
inline=True,
|
|
)
|
|
return embed
|
|
|
|
def _profile_fish_embed(target: discord.User | discord.Member, fish_res: dict) -> discord.Embed:
|
|
embed = discord.Embed(
|
|
title=S.PROFILE_UI["fish_title"].format(name=target.display_name),
|
|
color=0x5865F2,
|
|
)
|
|
book: dict = fish_res["book"]
|
|
if not book:
|
|
embed.description = S.FISH_UI["book_empty"]
|
|
return embed
|
|
inv_counts: dict = fish_res.get("inv_counts", {})
|
|
caught_count = fish_res["unique_caught"]
|
|
total = fish_res["total_species"]
|
|
lines = [S.FISH_UI["book_caught"].format(caught=caught_count, total=total)]
|
|
for fish_id, fish_data in economy.FISH_CATALOGUE.items():
|
|
rarity = fish_data["rarity"]
|
|
emoji = S.FISH_RARITY_EMOJI[rarity]
|
|
rarity_name = S.FISH_RARITY_NAMES[rarity]
|
|
count = book.get(fish_id, 0)
|
|
if count > 0:
|
|
n_inv = inv_counts.get(fish_id, 0)
|
|
inv_str = S.FISH_UI["book_inv"].format(n=n_inv) if n_inv > 0 else ""
|
|
lines.append(
|
|
S.FISH_UI["book_yes"].format(
|
|
emoji=emoji,
|
|
name=S.FISH_NAMES[fish_id],
|
|
rarity=rarity_name,
|
|
count=count,
|
|
inv=inv_str,
|
|
)
|
|
)
|
|
else:
|
|
lines.append(S.FISH_UI["book_no"].format(rarity=rarity_name))
|
|
embed.description = "\n".join(lines)
|
|
embed.set_footer(
|
|
text=S.FISH_UI["book_footer"].format(
|
|
page=1,
|
|
total_pages=1,
|
|
caught=caught_count,
|
|
total=total,
|
|
)
|
|
)
|
|
return embed
|
|
|
|
class ProfileView(discord.ui.View):
|
|
def __init__(self, target: discord.User | discord.Member, invoker_id: int, tab: str = "main"):
|
|
super().__init__(timeout=120)
|
|
self.target = target
|
|
self.invoker_id = invoker_id
|
|
self.tab = tab
|
|
self._rebuild()
|
|
|
|
def _rebuild(self):
|
|
self.clear_items()
|
|
tabs = [
|
|
("main", S.PROFILE_UI["btn_profile"]),
|
|
("items", S.PROFILE_UI["btn_items"]),
|
|
("stats", S.PROFILE_UI["btn_stats"]),
|
|
("fish", S.PROFILE_UI["btn_fish"]),
|
|
]
|
|
for tab_id, label in tabs:
|
|
btn = discord.ui.Button(
|
|
label=label,
|
|
style=(
|
|
discord.ButtonStyle.primary
|
|
if tab_id == self.tab
|
|
else discord.ButtonStyle.secondary
|
|
),
|
|
disabled=(tab_id == self.tab),
|
|
)
|
|
btn.callback = self._make_cb(tab_id)
|
|
self.add_item(btn)
|
|
|
|
def _make_cb(self, tab_id: str):
|
|
async def _cb(interaction: discord.Interaction):
|
|
if interaction.user.id != self.invoker_id:
|
|
await interaction.response.send_message(S.ERR["not_your_menu"], ephemeral=True)
|
|
return
|
|
self.tab = tab_id
|
|
self._rebuild()
|
|
await interaction.response.defer()
|
|
data = await economy.get_user(self.target.id)
|
|
if tab_id == "fish":
|
|
fish_res = await economy.do_fishbook(self.target.id)
|
|
embed = _profile_fish_embed(self.target, fish_res)
|
|
inv: list = data.get("fish_inventory") or []
|
|
if inv and self.target.id == self.invoker_id:
|
|
total_value = sum(entry.get("value", 0) for entry in inv)
|
|
sell_btn = discord.ui.Button(
|
|
label=(
|
|
f"{S.FISH_UI['btn_sell']} "
|
|
f"({len(inv)} kala · {total_value:,} {economy.COIN})"
|
|
),
|
|
style=discord.ButtonStyle.success,
|
|
row=1,
|
|
)
|
|
sell_btn.callback = self._sell_fish_cb()
|
|
self.add_item(sell_btn)
|
|
elif tab_id == "items":
|
|
embed = _profile_items_embed(self.target, data)
|
|
elif tab_id == "stats":
|
|
embed = _profile_stats_embed(self.target, data)
|
|
else:
|
|
embed = _profile_main_embed(self.target, data)
|
|
await interaction.edit_original_response(embed=embed, view=self)
|
|
|
|
return _cb
|
|
|
|
def _sell_fish_cb(self):
|
|
async def _cb(interaction: discord.Interaction):
|
|
if interaction.user.id != self.invoker_id:
|
|
await interaction.response.send_message(S.ERR["not_your_menu"], ephemeral=True)
|
|
return
|
|
await interaction.response.defer()
|
|
res = await economy.do_fish_sell(self.invoker_id)
|
|
self.tab = "fish"
|
|
self._rebuild()
|
|
fish_res = await economy.do_fishbook(self.target.id)
|
|
embed = _profile_fish_embed(self.target, fish_res)
|
|
sold_line = S.FISH_UI["inv_sold_all"].format(
|
|
count=res.get("count", 0),
|
|
coins=coin(res.get("coins", 0)),
|
|
balance=coin(res.get("balance", 0)),
|
|
)
|
|
embed.description = f"{sold_line}\n\n{embed.description or ''}"
|
|
await interaction.edit_original_response(embed=embed, view=self)
|
|
|
|
return _cb
|
|
|
|
def _balance_embed(user: discord.User | discord.Member, data: dict) -> discord.Embed:
|
|
embed = discord.Embed(
|
|
title=f"{economy.COIN} {user.display_name}",
|
|
color=0xF4C430,
|
|
)
|
|
embed.add_field(name=S.BALANCE_UI["saldo"], value=coin(data["balance"]), inline=True)
|
|
streak = data.get("daily_streak", 0)
|
|
if streak:
|
|
embed.add_field(
|
|
name=S.BALANCE_UI["streak"],
|
|
value=S.BALANCE_UI["streak_val"].format(streak=streak),
|
|
inline=True,
|
|
)
|
|
jail_remaining = economy._is_jailed(data)
|
|
if jail_remaining:
|
|
embed.add_field(name=S.BALANCE_UI["jailed_until"], value=cd_ts(jail_remaining), inline=True)
|
|
item_lines = []
|
|
uses_map = data.get("item_uses", {})
|
|
for item_id in data.get("items", []):
|
|
if item_id not in economy.SHOP:
|
|
continue
|
|
line = f"{economy.SHOP[item_id]['emoji']} {economy.SHOP[item_id]['name']}"
|
|
if item_id in uses_map:
|
|
uses = uses_map[item_id]
|
|
line += (
|
|
S.BALANCE_UI["uses_one"].format(uses=uses)
|
|
if uses == 1
|
|
else S.BALANCE_UI["uses_many"].format(uses=uses)
|
|
)
|
|
item_lines.append(line)
|
|
if item_lines:
|
|
embed.add_field(name=S.BALANCE_UI["items"], value="\n".join(item_lines), inline=False)
|
|
return embed
|
|
|
|
@tree.command(name="profile", description=S.CMD["profile"])
|
|
@app_commands.describe(kasutaja=S.OPT["profile_kasutaja"])
|
|
async def cmd_profile(interaction: discord.Interaction, kasutaja: discord.Member | None = None):
|
|
target = kasutaja or interaction.user
|
|
data = await economy.get_user(target.id)
|
|
embed = _profile_main_embed(target, data)
|
|
invoker_id = interaction.user.id
|
|
await interaction.response.send_message(embed=embed, view=ProfileView(target, invoker_id))
|
|
if not kasutaja and interaction.guild:
|
|
member = interaction.guild.get_member(target.id)
|
|
if member:
|
|
asyncio.create_task(ensure_level_role(member, economy.get_level(data.get("exp", 0))))
|
|
|
|
@tree.command(name="balance", description=S.CMD["balance"])
|
|
async def cmd_balance(interaction: discord.Interaction, kasutaja: discord.Member | None = None):
|
|
target = kasutaja or interaction.user
|
|
data = await economy.get_user(target.id)
|
|
await interaction.response.send_message(embed=_balance_embed(target, data))
|
|
|
|
@tree.command(name="cooldowns", description=S.CMD["cooldowns"])
|
|
async def cmd_cooldowns(interaction: discord.Interaction):
|
|
data = await economy.get_user(interaction.user.id)
|
|
now = datetime.datetime.now(datetime.timezone.utc)
|
|
items = set(data.get("items", []))
|
|
|
|
def _status(last_key: str, cooldown: datetime.timedelta) -> str:
|
|
raw = data.get(last_key)
|
|
if not raw:
|
|
return S.COOLDOWNS_UI["ready"]
|
|
last = economy._parse_dt(raw)
|
|
if last is None:
|
|
return S.COOLDOWNS_UI["ready"]
|
|
expires = last + cooldown
|
|
if expires <= now:
|
|
return S.COOLDOWNS_UI["ready"]
|
|
ts = int(expires.timestamp())
|
|
return f"⏳ <t:{ts}:R>"
|
|
|
|
work_cd = datetime.timedelta(minutes=40) if "monitor" in items else economy.COOLDOWNS["work"]
|
|
beg_cd = datetime.timedelta(minutes=3) if "hiirematt" in items else economy.COOLDOWNS["beg"]
|
|
daily_cd = datetime.timedelta(hours=18) if "korvaklapid" in items else economy.COOLDOWNS["daily"]
|
|
fish_cd = datetime.timedelta(seconds=90) if "ussipurk" in items else economy.COOLDOWNS["fish"]
|
|
|
|
lines = [
|
|
S.COOLDOWNS_UI["daily_line"].format(
|
|
status=_status("last_daily", daily_cd),
|
|
note=S.COOLDOWNS_UI["note_korvak"] if "korvaklapid" in items else "",
|
|
),
|
|
S.COOLDOWNS_UI["work_line"].format(
|
|
status=_status("last_work", work_cd),
|
|
note=S.COOLDOWNS_UI["note_monitor"] if "monitor" in items else "",
|
|
),
|
|
S.COOLDOWNS_UI["beg_line"].format(
|
|
status=_status("last_beg", beg_cd),
|
|
note=S.COOLDOWNS_UI["note_hiirematt"] if "hiirematt" in items else "",
|
|
),
|
|
S.COOLDOWNS_UI["crime_line"].format(status=_status("last_crime", economy.COOLDOWNS["crime"])),
|
|
S.COOLDOWNS_UI["rob_line"].format(status=_status("last_rob", economy.COOLDOWNS["rob"])),
|
|
S.COOLDOWNS_UI["fish_line"].format(
|
|
status=_status("last_fish", fish_cd),
|
|
note=S.COOLDOWNS_UI["note_ussipurk"] if "ussipurk" in items else "",
|
|
),
|
|
]
|
|
|
|
jailed = data.get("jailed_until")
|
|
if jailed:
|
|
jail_dt = datetime.datetime.fromisoformat(jailed)
|
|
if jail_dt > now:
|
|
ts = int(jail_dt.timestamp())
|
|
lines.append(S.COOLDOWNS_UI["jailed"].format(ts=ts))
|
|
else:
|
|
lines.append(S.COOLDOWNS_UI["jail_expired"])
|
|
|
|
embed = discord.Embed(
|
|
title=S.TITLE["cooldowns"],
|
|
description="\n".join(lines),
|
|
color=0x5865F2,
|
|
)
|
|
await interaction.response.send_message(embed=embed, ephemeral=True)
|
|
|
|
@tree.command(name="jailed", description=S.CMD["jailed"])
|
|
@app_commands.guild_only()
|
|
async def cmd_jailed(interaction: discord.Interaction):
|
|
await interaction.response.defer()
|
|
jailed = await economy.do_get_jailed()
|
|
if not jailed:
|
|
embed = discord.Embed(
|
|
title=S.JAILED_UI["title"],
|
|
description=S.JAILED_UI["empty"],
|
|
color=0x57F287,
|
|
)
|
|
await interaction.followup.send(embed=embed)
|
|
return
|
|
|
|
now = datetime.datetime.now(datetime.timezone.utc)
|
|
lines = []
|
|
for uid, remaining in jailed:
|
|
ts = int((now + remaining).timestamp())
|
|
member = interaction.guild.get_member(uid) if interaction.guild else None
|
|
mention = member.mention if member else f"<@{uid}>"
|
|
lines.append(S.JAILED_UI["entry"].format(mention=mention, ts=ts))
|
|
|
|
plural = "" if len(jailed) == 1 else "i"
|
|
embed = discord.Embed(
|
|
title=S.JAILED_UI["title"],
|
|
description="\n".join(lines),
|
|
color=0xED4245,
|
|
)
|
|
embed.set_footer(text=S.JAILED_UI["footer"].format(count=len(jailed), plural=plural))
|
|
await interaction.followup.send(embed=embed)
|
|
|
|
@tree.command(name="rank", description=S.CMD["rank"])
|
|
@app_commands.describe(kasutaja=S.OPT["rank_kasutaja"])
|
|
async def cmd_rank(interaction: discord.Interaction, kasutaja: discord.Member | None = None):
|
|
target = kasutaja or interaction.user
|
|
data = await economy.get_user(target.id)
|
|
exp = data.get("exp", 0)
|
|
level = economy.get_level(exp)
|
|
role_name = economy.level_role_name(level)
|
|
next_level = level + 1
|
|
exp_this = economy.exp_for_level(level)
|
|
exp_next = economy.exp_for_level(next_level)
|
|
progress = exp - exp_this
|
|
needed = exp_next - exp_this
|
|
pct = progress / needed if needed > 0 else 1.0
|
|
filled = int(pct * 12)
|
|
bar = "█" * filled + "░" * (12 - filled)
|
|
embed = discord.Embed(
|
|
title=S.RANK_UI["title"].format(name=target.display_name, level=level),
|
|
color=0x5865F2,
|
|
)
|
|
embed.add_field(name=S.RANK_UI["field_title"], value=f"**{role_name}**", inline=True)
|
|
embed.add_field(name=S.RANK_UI["field_exp"], value=str(exp), inline=True)
|
|
embed.add_field(
|
|
name=S.RANK_UI["field_progress"].format(next=next_level),
|
|
value=S.RANK_UI["progress_val"].format(bar=bar, progress=progress, needed=needed),
|
|
inline=False,
|
|
)
|
|
p_level = data.get("prestige_level", 0)
|
|
p_pp = data.get("prestige_points", 0)
|
|
s_exp = data.get("season_total_exp", 0)
|
|
if p_level > 0 or s_exp > 0:
|
|
embed.add_field(
|
|
name="\u200b",
|
|
value=(
|
|
S.PRESTIGE_UI["rank_line"].format(level=p_level, pp=p_pp)
|
|
+ "\n"
|
|
+ S.PRESTIGE_UI["rank_season"].format(exp=s_exp)
|
|
),
|
|
inline=False,
|
|
)
|
|
if level < 10:
|
|
embed.set_footer(text=S.RANK_UI["footer_t1"])
|
|
elif level < 20:
|
|
embed.set_footer(text=S.RANK_UI["footer_t2"])
|
|
else:
|
|
embed.set_footer(text=S.RANK_UI["footer_t3"])
|
|
await interaction.response.send_message(embed=embed, ephemeral=True)
|
|
if not kasutaja and interaction.guild:
|
|
member = interaction.guild.get_member(target.id)
|
|
if member:
|
|
asyncio.create_task(ensure_level_role(member, level))
|
|
|
|
@tree.command(name="stats", description=S.CMD["stats"])
|
|
@app_commands.describe(kasutaja=S.OPT["stats_kasutaja"])
|
|
async def cmd_stats(interaction: discord.Interaction, kasutaja: discord.Member | None = None):
|
|
target = kasutaja or interaction.user
|
|
data = await economy.get_user(target.id)
|
|
|
|
def _s(key: str) -> int:
|
|
return data.get(key, 0)
|
|
|
|
embed = discord.Embed(
|
|
title=f"{S.TITLE['stats']} - {target.display_name}",
|
|
color=0x5865F2,
|
|
)
|
|
embed.add_field(
|
|
name=S.STATS_UI["economy_field"],
|
|
value=S.STATS_UI["economy_val"].format(
|
|
peak=coin(_s("peak_balance")),
|
|
earned=coin(_s("lifetime_earned")),
|
|
lost=coin(_s("lifetime_lost")),
|
|
),
|
|
inline=True,
|
|
)
|
|
embed.add_field(
|
|
name=S.STATS_UI["work_field"],
|
|
value=S.STATS_UI["work_val"].format(work=_s("work_count"), beg=_s("beg_count")),
|
|
inline=True,
|
|
)
|
|
embed.add_field(name="\u200b", value="\u200b", inline=False)
|
|
embed.add_field(
|
|
name=S.STATS_UI["gamble_field"],
|
|
value=S.STATS_UI["gamble_val"].format(
|
|
wagered=coin(_s("total_wagered")),
|
|
win=coin(_s("biggest_win")),
|
|
loss=coin(_s("biggest_loss")),
|
|
jackpots=_s("slots_jackpots"),
|
|
),
|
|
inline=True,
|
|
)
|
|
embed.add_field(
|
|
name=S.STATS_UI["crime_field"],
|
|
value=S.STATS_UI["crime_val"].format(
|
|
crimes=_s("crimes_attempted"),
|
|
succeeded=_s("crimes_succeeded"),
|
|
heists=_s("heists_joined"),
|
|
heists_won=_s("heists_won"),
|
|
jailed=_s("times_jailed"),
|
|
bail=coin(_s("total_bail_paid")),
|
|
),
|
|
inline=True,
|
|
)
|
|
embed.add_field(name="\u200b", value="\u200b", inline=False)
|
|
embed.add_field(
|
|
name=S.STATS_UI["social_field"],
|
|
value=S.STATS_UI["social_val"].format(
|
|
given=coin(_s("total_given")),
|
|
received=coin(_s("total_received")),
|
|
),
|
|
inline=True,
|
|
)
|
|
embed.add_field(
|
|
name=S.STATS_UI["records_field"],
|
|
value=S.STATS_UI["records_val"].format(streak=_s("best_daily_streak")),
|
|
inline=True,
|
|
)
|
|
await interaction.response.send_message(embed=embed, ephemeral=True)
|