Skip to content

Commit dc5b12f

Browse files
committed
LevelUp - settings pre-buildout, leaderboard dash fix
1 parent 5f2c2df commit dc5b12f

File tree

6 files changed

+211
-5
lines changed

6 files changed

+211
-5
lines changed

levelup/dashboard/integration.py

Lines changed: 119 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
from pathlib import Path
55

66
import discord
7+
import pydantic
78
from redbot.core import commands
89
from redbot.core.i18n import Translator
910

1011
from ..abc import MixinMeta
11-
from ..common import formatter
12+
from ..common import formatter, models
1213

1314
_ = Translator("LevelUp", __file__)
1415
log = logging.getLogger("red.levelup.dashboard")
@@ -35,7 +36,6 @@ async def get_dashboard_leaderboard(
3536
guild: discord.Guild,
3637
lbtype: t.Literal["lb", "weekly"],
3738
stat: t.Literal["exp", "messages", "voice", "stars"] = "exp",
38-
query: t.Optional[str] = None,
3939
**kwargs,
4040
):
4141
"""
@@ -110,7 +110,6 @@ async def get_dashboard_leaderboard(
110110
member=guild.get_member(user.id),
111111
use_displayname=True,
112112
dashboard=True,
113-
query=query,
114113
)
115114
data = {
116115
"user_id": user.id,
@@ -145,3 +144,120 @@ async def weekly_page(
145144
) -> t.Dict[str, t.Any]:
146145
stat = stat if stat is not None and stat in {"exp", "messages", "voice", "stars"} else "exp"
147146
return await self.get_dashboard_leaderboard(user, guild, "weekly", stat, query, **kwargs)
147+
148+
async def save_settings(self, user: discord.User, guild: discord.Guild, data: dict, **kwargs):
149+
member = guild.get_member(user.id)
150+
if not member:
151+
return {
152+
"status": 1,
153+
"error_title": _("Member not found"),
154+
"error_message": _("You are not a member of this guild."),
155+
}
156+
if not await self.bot.is_admin(member):
157+
return {
158+
"status": 1,
159+
"error_title": _("Insufficient permissions"),
160+
"error_message": _("You need to be an admin to access this page."),
161+
}
162+
163+
try:
164+
new_conf = models.GuildSettings.model_validate(data)
165+
except pydantic.ValidationError as e:
166+
return {
167+
"status": 1,
168+
"error_title": _("Validation error"),
169+
"error_message": str(e),
170+
}
171+
172+
conf = self.db.get_conf(guild)
173+
for k, v in data.items():
174+
setattr(conf, k, getattr(new_conf, k, v))
175+
self.save()
176+
return {
177+
"status": 0,
178+
"success_title": _("Settings saved"),
179+
"success_message": _("The settings have been saved."),
180+
}
181+
182+
# @dashboard_page(name="settings", description="Configure the leveling system.")
183+
async def get_cog_settings(self, user: discord.User, guild: discord.Guild, **kwargs):
184+
if kwargs.get("save") and (data := kwargs.get("new_data")):
185+
log.info(f"Saving settings for {guild.name} by {user.name}")
186+
return await self.save_settings(user, guild, data, **kwargs)
187+
log.info(f"Getting settings for {guild.name} by {user.name}")
188+
member = guild.get_member(user.id)
189+
if not member:
190+
return {
191+
"status": 1,
192+
"error_title": _("Member not found"),
193+
"error_message": _("You are not a member of this guild."),
194+
}
195+
if not await self.bot.is_admin(member):
196+
return {
197+
"status": 1,
198+
"error_title": _("Insufficient permissions"),
199+
"error_message": _("You need to be an admin to access this page."),
200+
}
201+
202+
conf = self.db.get_conf(guild)
203+
settings = conf.model_dump(mode="json", exclude=["users", "users_weekly"])
204+
205+
users = []
206+
for user in guild.members:
207+
users.append(
208+
{
209+
"id": user.id,
210+
"name": user.name,
211+
"avatar": user.display_avatar.url,
212+
}
213+
)
214+
215+
emojis = []
216+
for emoji in guild.emojis:
217+
emojis.append(
218+
{
219+
"id": emoji.id,
220+
"name": emoji.name,
221+
"url": emoji.url,
222+
}
223+
)
224+
225+
# Add roles data for the settings page
226+
roles = []
227+
for role in sorted(guild.roles, reverse=True):
228+
if role.is_default():
229+
continue
230+
roles.append(
231+
{
232+
"id": role.id,
233+
"name": role.name,
234+
"color": str(role.color),
235+
"position": role.position,
236+
}
237+
)
238+
239+
parent = Path(__file__).parent
240+
source_path = parent / "templates" / "settings.html"
241+
static_dir = parent / "static"
242+
js_path = static_dir / "js" / "settings.js"
243+
css_path = static_dir / "css" / "settings.css"
244+
245+
# Inject JS and CSS into the HTML source for full page loads
246+
source = (
247+
f"<style>\n{css_path.read_text() if css_path.exists() else ''}\n</style>\n\n"
248+
+ source_path.read_text().strip()
249+
+ f"\n\n<script>\n{js_path.read_text()}\n</script>"
250+
)
251+
252+
payload = {
253+
"status": 0,
254+
"web_content": {
255+
"source": source,
256+
"expanded": True,
257+
"settings": settings,
258+
"users": users,
259+
"emojis": emojis,
260+
"roles": roles,
261+
},
262+
}
263+
return payload

levelup/dashboard/static/css/settings.css

Whitespace-only changes.

levelup/dashboard/static/js/leaderboard.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
document.addEventListener('alpine:init', () => {
22
Alpine.data('leaderBoard', (data = {}) => ({
33
// DATA INITIALIZATION
4-
searchQuery: data.query,
4+
searchQuery: '',
55
page: data.page,
66
perPage: 100,
77
users: data.users,
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
document.addEventListener('alpine:init', () => {
2+
Alpine.data('levelUpSettings', (data = {}) => ({
3+
// DATA INITIALIZATION
4+
settings: data.settings || {},
5+
users: data.users || [],
6+
emojis: data.emojis || [],
7+
roles: data.roles || [],
8+
newLevelRole: { level: 1, role: '' },
9+
10+
// METHODS
11+
async saveSettings(event) {
12+
if (event) event.preventDefault();
13+
console.log("Saving settings:", this.settings);
14+
try {
15+
// Get CSRF token from meta tag
16+
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content;
17+
18+
if (!csrfToken) {
19+
console.error("CSRF token not found");
20+
alert("CSRF token not found. Please refresh the page and try again.");
21+
return;
22+
}
23+
24+
const response = await fetch(window.location.href, {
25+
method: 'POST',
26+
headers: {
27+
'Content-Type': 'application/json',
28+
'X-CSRFToken': csrfToken // Changed from X-CSRF-Token to X-CSRFToken
29+
},
30+
credentials: 'same-origin', // Added to ensure cookies are sent
31+
body: JSON.stringify(this.settings)
32+
});
33+
34+
const result = await response.json();
35+
if (result.status === 0) {
36+
alert(result.success_message);
37+
} else {
38+
alert(`Error: ${result.error_message}`);
39+
}
40+
} catch (error) {
41+
console.error("Error saving settings:", error);
42+
alert("An error occurred while saving settings.");
43+
}
44+
}
45+
}));
46+
});
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<script
2+
defer
3+
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"
4+
></script>
5+
6+
<!-- Add CSRF token meta tag -->
7+
<meta name="csrf-token" content="{{ csrf_token }}" />
8+
9+
<div class="container-fluid" x-data="levelUpSettings({{ data }})">
10+
<div class="card mb-3">
11+
<div class="card-header">
12+
<h3>LevelUp Settings</h3>
13+
</div>
14+
<div class="card-body">
15+
<form @submit.prevent>
16+
<!-- Enable/Disable Leveling -->
17+
<div class="mb-3">
18+
<div class="form-check form-switch ps-0">
19+
<input
20+
id="setting-enabled"
21+
class="form-check-input ms-0"
22+
type="checkbox"
23+
x-model="settings.enabled"
24+
x-bind:checked="settings.enabled"
25+
/>
26+
<label class="form-check-label"
27+
>Enable the leveling system in this server.</label
28+
>
29+
</div>
30+
</div>
31+
<!-- Submit Button -->
32+
<div class="mt-4">
33+
<button
34+
type="button"
35+
class="btn btn-primary"
36+
x-bind:href="{{ url_for_query( save=True, new_data=settings ) }}"
37+
>
38+
Save Settings
39+
</button>
40+
</div>
41+
</form>
42+
</div>
43+
</div>
44+
</div>

levelup/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class LevelUp(
7777
"""
7878

7979
__author__ = "[vertyco](https://github.com/vertyco/vrt-cogs)"
80-
__version__ = "4.3.25"
80+
__version__ = "4.3.26"
8181
__contributors__ = [
8282
"[aikaterna](https://github.com/aikaterna/aikaterna-cogs)",
8383
"[AAA3A](https://github.com/AAA3A-AAA3A/AAA3A-cogs)",

0 commit comments

Comments
 (0)