GhostWipe report: chronological order, mobile layout, Ruby branding
Messages within each channel now sort oldest-first (history()/purge() return newest-first, which read backwards). Added a real mobile layout: below 700px the sidebar stacks above the message view and its channel list becomes a horizontally-scrolling chip strip instead of a cramped vertical column. Report title/footer and the Discord log embeds now carry Ruby branding alongside the GhostWipe module name. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
039e85d65a
commit
fdf41cfcbc
2 changed files with 41 additions and 7 deletions
|
|
@ -309,6 +309,9 @@ class GhostWipe(commands.Cog):
|
|||
"messages": [],
|
||||
}
|
||||
|
||||
# channel.history()/purge() return newest-first; the report reads far
|
||||
# more naturally in actual conversation order.
|
||||
collected.sort(key=lambda m: m.created_at)
|
||||
messages = [self._serialize_message(m) for m in collected]
|
||||
return {
|
||||
"id": str(channel.id),
|
||||
|
|
@ -541,7 +544,7 @@ class GhostWipe(commands.Cog):
|
|||
if top:
|
||||
breakdown = "\n".join(f"**{c['name']}** — {c['message_count']}" for c in top)
|
||||
embed.add_field(name="Per-Channel Breakdown", value=breakdown, inline=False)
|
||||
embed.set_footer(text=f"GhostWipe v{self.__version__}")
|
||||
embed.set_footer(text=f"Ruby · GhostWipe v{self.__version__}")
|
||||
|
||||
file_obj = None
|
||||
if conf["attach_html_report"]:
|
||||
|
|
@ -903,7 +906,7 @@ class GhostWipe(commands.Cog):
|
|||
f"{humanize_number(stats.get('total_messages_deleted', 0))} messages deleted",
|
||||
inline=False,
|
||||
)
|
||||
embed.set_footer(text=f"GhostWipe v{self.__version__}")
|
||||
embed.set_footer(text=f"Ruby · GhostWipe v{self.__version__}")
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
@ghostwipe.command(name="history")
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ STYLE = r"""
|
|||
--danger: #f04747;
|
||||
--warn: #faa61a;
|
||||
--ok: #3ba55d;
|
||||
--ruby: #e0115f;
|
||||
--radius: 10px;
|
||||
--shadow: 0 8px 24px rgba(0,0,0,0.35);
|
||||
}
|
||||
|
|
@ -171,12 +172,42 @@ html, body {
|
|||
padding: 8px 20px; border-top: 1px solid var(--border); color: var(--text-faint);
|
||||
font-size: 11px; text-align: center; flex-shrink: 0;
|
||||
}
|
||||
.brand-ruby { color: var(--ruby); font-weight: 700; }
|
||||
::-webkit-scrollbar { width: 10px; }
|
||||
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 6px; }
|
||||
::-webkit-scrollbar-track { background: transparent; }
|
||||
@media (max-width: 720px) {
|
||||
#sidebar { width: 200px; }
|
||||
#header .stats { gap: 12px; }
|
||||
@media (max-width: 700px) {
|
||||
html, body { font-size: 15px; }
|
||||
#header { padding: 12px 14px; gap: 10px; }
|
||||
.avatar, .avatar-fallback { width: 40px; height: 40px; }
|
||||
#header .username { font-size: 14px; }
|
||||
#header .id-block { min-width: 0; }
|
||||
#header .stats { order: 3; width: 100%; margin-left: 0; justify-content: space-around; gap: 10px; }
|
||||
#header .stat .num { font-size: 16px; }
|
||||
#header .meta-row { order: 4; }
|
||||
|
||||
/* Stack sidebar above main content, and turn the channel list into a
|
||||
horizontally-scrolling strip of chips instead of a tall vertical list —
|
||||
the classic mobile pattern for a channel/tab picker. */
|
||||
#body { flex-direction: column; }
|
||||
#sidebar {
|
||||
width: 100%; max-height: none;
|
||||
border-right: none; border-bottom: 1px solid var(--border);
|
||||
}
|
||||
#sidebar .sidebar-title { padding: 10px 14px 4px; }
|
||||
#channel-list {
|
||||
display: flex; flex-direction: row; flex-wrap: nowrap;
|
||||
overflow-x: auto; -webkit-overflow-scrolling: touch;
|
||||
gap: 6px; padding: 4px 10px;
|
||||
}
|
||||
.ch-item { flex: 0 0 auto; margin-bottom: 0; }
|
||||
.ch-item .ch-name { white-space: nowrap; }
|
||||
#search-wrap { padding: 8px 10px; }
|
||||
|
||||
#main { width: 100%; }
|
||||
.panel-header { padding: 10px 14px; }
|
||||
.panel-body { padding: 12px 14px; }
|
||||
.attachment-img { max-width: 100%; }
|
||||
}
|
||||
"""
|
||||
|
||||
|
|
@ -398,7 +429,7 @@ def generate_report_html(
|
|||
main_content = '<div class="empty-state">Nothing was deleted for this event.</div>'
|
||||
sidebar_content = '<div class="empty-state" style="padding:20px 10px;">No channels affected.</div>'
|
||||
|
||||
title = f"GhostWipe Report — {html_lib.escape(member_name)}"
|
||||
title = f"Ruby — GhostWipe Report — {html_lib.escape(member_name)}"
|
||||
|
||||
doc = f"""<!doctype html>
|
||||
<html lang="en">
|
||||
|
|
@ -442,7 +473,7 @@ def generate_report_html(
|
|||
{main_content}
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">Generated by GhostWipe {html_lib.escape(version)} · {html_lib.escape(generated_at or event_time_str)}</div>
|
||||
<div id="footer"><span class="brand-ruby">Ruby</span> · GhostWipe v{html_lib.escape(version)} · {html_lib.escape(generated_at or event_time_str)}</div>
|
||||
</div>
|
||||
<script>{SEARCH_SCRIPT}</script>
|
||||
</body>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue