simple profile screen

This commit is contained in:
Jill 2023-11-20 07:30:14 +03:00
parent ef08ef020b
commit 4ab739d681
5 changed files with 162 additions and 12 deletions

View File

@ -1,17 +1,47 @@
import express from 'express';
import { engine } from 'express-handlebars';
import { create } from 'express-handlebars';
import * as log from '../lib/log';
import { CustomItem, Session, db } from '../lib/db';
import { CustomItem, Counter, Session, CustomCraftingRecipe, db } from '../lib/db';
import { defaultItems } from '../lib/rpg/items';
import { Client, CDN } from 'discord.js';
import { getToken, getSessionString, getSession, setSession, updateCookie } from './oauth2';
import { getUser, getGuilds } from './user';
async function getGuildInfo(bot: Client, id: string) {
const guild = await bot.guilds.cache.get(id);
if (!guild) return;
const items = await db<CustomItem>('customItems')
.where('guild', guild)
.count({count: '*'});
const counters = await db<Counter>('counters')
.where('guild', guild)
.count({count: '*'});
const recipes = await db<CustomCraftingRecipe>('customCraftingRecipes')
.where('guild', guild)
.count({count: '*'});
return {
items: items[0].count as number,
counters: counters[0].count as number,
recipes: recipes[0].count as number,
}
}
export async function startServer(bot: Client, port: number) {
const app = express();
const cdn = new CDN();
app.engine('handlebars', engine());
const hbs = create({
helpers: {
avatar: (id: string, hash: string) => (id && hash) ? cdn.avatar(id, hash, { size: 128 }) : '/assets/avatar.png',
icon: (id: string, hash: string) => (id && hash) ? cdn.icon(id, hash, { size: 128, forceStatic: true }) : '/assets/avatar.png',
}
})
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
app.set('views', './views');
@ -70,7 +100,7 @@ export async function startServer(bot: Client, port: number) {
res.render('home', {
signedIn: session !== undefined,
username: user?.global_name,
avatar: user?.avatar ? cdn.avatar(user.id, user.avatar, { size: 128 }) : null,
avatar: user?.avatar ? cdn.avatar(user.id, user.avatar, { size: 128 }) : '/assets/avatar.png',
layout: false,
});
});
@ -80,12 +110,18 @@ export async function startServer(bot: Client, port: number) {
if (!session) return res.redirect(`https://discord.com/api/oauth2/authorize?client_id=${bot.config.clientId}&redirect_uri=${encodeURIComponent(bot.config.siteURL)}&response_type=code&scope=identify%20guilds`);
const user = await getUser(session);
if (!user) return;
const guilds = await getGuilds(session);
if (!guilds) return;
//res.sendFile('profile/index.html', { root: 'static/' });
res.json({
res.render('profile', {
user,
guilds
guilds: await Promise.all(
guilds.map(async guild =>
({...guild, jillo: await getGuildInfo(bot, guild.id)})
)
),
});
});

View File

@ -21,6 +21,7 @@ body {
-webkit-text-size-adjust: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
}
:root {
@ -133,7 +134,7 @@ a:hover {
#content {
max-width: 1000px;
width: 100%;
margin: auto;
margin: 0 auto;
margin-bottom: 6rem;
}
@ -293,4 +294,60 @@ pre {
.note {
font-style: italic;
color: var(--text-color-light);
}
.user {
display: flex;
flex-direction: row;
height: 2rem;
padding: 0.5em;
align-items: center;
width: fit-content;
margin: 0 auto;
}
.user .avatar {
display: block;
aspect-ratio: 1 / 1;
border-radius: 2rem;
width: auto;
height: 100%;
margin-right: 0.5em;
}
.guilds {
display: flex;
flex-direction: column;
align-items: center;
}
.guild {
order: 0;
display: flex;
width: 600px;
max-width: 100%;
height: 3rem;
padding: 0.5rem;
gap: 0.5rem;
margin: 0.5rem;
background-color: var(--background-color-dark);
}
.guild.unavailable {
order: 1;
}
.guild.unavailable .icon {
filter: grayscale(100%);
}
.guild .icon {
flex: 0 0 auto;
display: block;
aspect-ratio: 1 / 1;
border-radius: 2rem;
width: auto;
height: 100%;
}
.guild .right {
display: flex;
flex-direction: column;
}
.guild .info {
color: var(--text-color-light);
}

View File

@ -22,11 +22,7 @@
{{else}}
<div class="username logged-out">log in</div>
{{/if}}
{{#if avatar}}
<img class="avatar" src="{{avatar}}" width="128" height="128">
{{else}}
<img class="avatar" src="/assets/avatar.png" width="128" height="128">
{{/if}}
<img class="avatar" src="{{avatar}}" width="128" height="128">
</div>
<div id="main">
<img src="/assets/jillo.png" width="150" height="200">

View File

@ -0,0 +1,34 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>jillo</title>
<meta name="theme-color" content="light dark">
<link href="/style.css" rel="stylesheet">
<link rel="shortcut icon" href="/favicon.ico">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Balsamiq+Sans&display=swap" rel="stylesheet">
</head>
<body>
<div id="content">
<div class="header">
<div class="bg"></div>
<div class="left">
<a href="/">jillo</a>
</div>
<div class="links">
<a href="https://discord.com/oauth2/authorize?client_id=898850107892596776&scope=bot" target="_blank" rel="noopener">invite</a>
&middot;
<a href="https://git.oat.zone/dark-firepit/jillo-bot" target="_blank" rel="noopener">repo</a>
<img src="/assets/jillo_small.png">
</div>
</div>
{{{body}}}
</div>
</body>
</html>

27
views/profile.handlebars Normal file
View File

@ -0,0 +1,27 @@
<div class="user">
<img class="avatar" src="{{avatar user.id user.avatar}}" width="128" height="128">
<div class="username">Logged in as <b>{{user.global_name}}</b></div>
</div>
<div class="guilds">
<h2>Guilds</h2>
{{#each guilds}}
{{#if jillo}}
<div class="guild">
<img src="{{icon id icon}}" width="128" height="128" class="icon">
<div class="right">
<div class="name">{{name}}</div>
<div class="info">{{jillo.counters}} counters &middot; {{jillo.items}} items &middot; {{jillo.recipes}} recipes</div>
</div>
</div>
{{else}}
<div class="guild unavailable">
<img src="{{icon id icon}}" width="128" height="128" class="icon">
<div class="right">
<div class="name">{{name}}</div>
<div class="info">Jillo is not in this server</div>
</div>
</div>
{{/if}}
{{/each}}
</div>