Implement profile page, UserInfo packet.

This commit is contained in:
yukirij 2024-10-17 14:50:19 -07:00
parent b2a035931a
commit f3425cfac4
9 changed files with 189 additions and 112 deletions

View File

@ -220,6 +220,8 @@ async fn main()
WebCache::file("www/css/ui.css"), WebCache::file("www/css/ui.css"),
WebCache::file("www/css/form.css"), WebCache::file("www/css/form.css"),
WebCache::file("www/css/game.css"), WebCache::file("www/css/game.css"),
WebCache::file("www/css/text.css"),
WebCache::file("www/css/profile.css"),
WebCache::file("www/css/util.css"), WebCache::file("www/css/util.css"),
]).ok(); ]).ok();
cache.cache("text/javascript", "/.js", &[ cache.cache("text/javascript", "/.js", &[

View File

@ -63,6 +63,44 @@ pub struct PacketSessionListResponseRecord {
pub is_turn:bool, pub is_turn:bool,
pub is_complete:u8, pub is_complete:u8,
} }
impl PacketSessionListResponseRecord {
pub fn encode(&self) -> Vec<u8>
{
let mut output = self.token.to_vec();
let mut flags = 0u32;
flags |= self.player as u32;
flags |= (self.is_turn as u32) << 2;
flags |= (self.is_complete as u32) << 3;
// Flags
output.append(&mut pack_u32(flags));
// Dawn handle
let mut bytes = self.handles[0].as_bytes().to_vec();
output.append(&mut pack_u16(bytes.len() as u16));
if bytes.len() > 0 { output.append(&mut bytes); }
// Dusk handle
let mut bytes = self.handles[1].as_bytes().to_vec();
output.append(&mut pack_u16(bytes.len() as u16));
if bytes.len() > 0 { output.append(&mut bytes); }
// Turn number
output.append(&mut pack_u16(self.turn));
// Last move
output.append(&mut pack_u32(self.last_move));
// Spectator count
output.append(&mut pack_u32(self.viewers));
// User is player
//chunk.append(&mut vec![record.player as u8]);
output
}
}
#[derive(Clone)] #[derive(Clone)]
pub struct PacketSessionListResponse { pub struct PacketSessionListResponse {
@ -82,41 +120,8 @@ impl Packet for PacketSessionListResponse {
fn encode(&self) -> Vec<u8> fn encode(&self) -> Vec<u8>
{ {
let mut result = pack_u16(self.records.len() as u16); let mut result = pack_u16(self.records.len() as u16);
for record in &self.records { for record in &self.records {
let mut chunk = record.token.to_vec(); result.append(&mut record.encode());
let mut flags = 0u32;
flags |= record.player as u32;
flags |= (record.is_turn as u32) << 2;
flags |= (record.is_complete as u32) << 3;
// Flags
chunk.append(&mut pack_u32(flags));
// Dawn handle
let mut bytes = record.handles[0].as_bytes().to_vec();
chunk.append(&mut pack_u16(bytes.len() as u16));
if bytes.len() > 0 { chunk.append(&mut bytes); }
// Dusk handle
let mut bytes = record.handles[1].as_bytes().to_vec();
chunk.append(&mut pack_u16(bytes.len() as u16));
if bytes.len() > 0 { chunk.append(&mut bytes); }
// Turn number
chunk.append(&mut pack_u16(record.turn));
// Last move
chunk.append(&mut pack_u32(record.last_move));
// Spectator count
chunk.append(&mut pack_u32(record.viewers));
// User is player
//chunk.append(&mut vec![record.player as u8]);
result.append(&mut chunk);
} }
result result
} }

View File

@ -1,10 +1,14 @@
use crate::util::pack::pack_u16; use crate::util::pack::{pack_u8, pack_u16};
use super::Packet; use super::{
Packet,
PacketSessionListResponseRecord,
};
#[derive(Clone)] #[derive(Clone)]
pub struct PacketUserInfo { pub struct PacketUserInfo {
pub handle:String, pub handle:String,
} }
impl PacketUserInfo { impl PacketUserInfo {
pub fn new() -> Self pub fn new() -> Self
@ -28,6 +32,7 @@ pub struct PacketUserInfoResponse {
pub status:u16, pub status:u16,
pub handle:String, pub handle:String,
pub is_online:bool, pub is_online:bool,
pub history:Vec<PacketSessionListResponseRecord>,
} }
impl PacketUserInfoResponse { impl PacketUserInfoResponse {
pub fn new() -> Self pub fn new() -> Self
@ -36,6 +41,7 @@ impl PacketUserInfoResponse {
status:0, status:0,
handle:String::new(), handle:String::new(),
is_online:false, is_online:false,
history:Vec::new(),
} }
} }
} }
@ -44,8 +50,23 @@ impl Packet for PacketUserInfoResponse {
fn encode(&self) -> Vec<u8> fn encode(&self) -> Vec<u8>
{ {
let handle_bytes = self.handle.as_bytes().to_vec();
let flags = self.is_online as u16;
let mut history_bytes = pack_u16(self.history.len() as u16);
for record in &self.history {
history_bytes.append(&mut record.encode());
}
[ [
pack_u16(self.status as u16), pack_u16(self.status as u16),
pack_u16(flags),
pack_u8(handle_bytes.len() as u8),
handle_bytes,
history_bytes,
].concat() ].concat()
} }
} }

25
www/css/profile.css Normal file
View File

@ -0,0 +1,25 @@
main.profile>header {
display: block;
position: relative;
width: 100%;
background-color: #282828;
border-bottom: 1px solid #303030;
}
main.profile>header>h1 {
display: block;
position: relative;
padding: 1rem 2rem 1rem 2rem;
margin: 0;
line-height: 3rem;
font-size: 2.5rem;
color: #f0f0f0;
}
main.profile>section.history {
flex-grow: 1;
}

60
www/css/text.css Normal file
View File

@ -0,0 +1,60 @@
main article.text{
display:block;
position:relative;
width:100%;
flex-grow:1;
padding:1rem;
margin:0;
line-height:1.4em;
font-size:1.2rem;
color:#c0c0c0;
overflow:auto;
}
main article.text>h1{
padding:0.5rem;
margin:0 0 0.5rem 0;
font-size:1.8rem;
font-weight:bold;
background-color:#a0a0a0;
color:#202020;
}
main article.text>h2{
padding:0 0 0.5rem 0.25rem;
margin:1.5rem 0 0.5rem 0;
font-size:1.6rem;
font-weight:bold;
border-bottom:2px solid #c0c0c0;
color:#c0c0c0;
}
main article.text>h3{
padding:0 0 0 0.25rem;
margin:1.5rem 0 0.5rem 0;
font-size:1.5rem;
font-weight:bold;
text-decoration:underline;
color:#b0b0b0;
}
main article.text>h4{
padding:0 0 0 0.25rem;
margin:1.5rem 0 0.5rem 0;
font-size:1.3rem;
text-decoration:underline;
color:#a0a0a0;
}
main article.text>p{
padding:0 0.5rem 0 0.5rem;
}
main article.text a{
color:#db758e;
text-decoration:none;
}
main article.text>a:hover{
text-decoration:underline;
}

View File

@ -86,67 +86,6 @@ main table.list td>canvas {
margin: 0 -1.5rem 0 -1.5rem; margin: 0 -1.5rem 0 -1.5rem;
} }
main article{
display:block;
position:relative;
width:100%;
flex-grow:1;
padding:1rem;
margin:0;
line-height:1.4em;
font-size:1.2rem;
color:#c0c0c0;
overflow:auto;
}
main article>h1{
padding:0.5rem;
margin:0 0 0.5rem 0;
font-size:1.8rem;
font-weight:bold;
background-color:#a0a0a0;
color:#202020;
}
main article>h2{
padding:0 0 0.5rem 0.25rem;
margin:1.5rem 0 0.5rem 0;
font-size:1.6rem;
font-weight:bold;
border-bottom:2px solid #c0c0c0;
color:#c0c0c0;
}
main article>h3{
padding:0 0 0 0.25rem;
margin:1.5rem 0 0.5rem 0;
font-size:1.5rem;
font-weight:bold;
text-decoration:underline;
color:#b0b0b0;
}
main article>h4{
padding:0 0 0 0.25rem;
margin:1.5rem 0 0.5rem 0;
font-size:1.3rem;
text-decoration:underline;
color:#a0a0a0;
}
main article>p{
padding:0 0.5rem 0 0.5rem;
}
main article a{
color:#db758e;
text-decoration:none;
}
main article>a:hover{
text-decoration:underline;
}
main div.turn-slider-padding{ main div.turn-slider-padding{
display:block; display:block;
position:relative; position:relative;

View File

@ -640,6 +640,7 @@ const SCENES = {
let body = document.createElement("article"); let body = document.createElement("article");
body.setAttribute("id", "article"); body.setAttribute("id", "article");
body.setAttribute("class", "text");
UI.maincontent(body); UI.maincontent(body);
this.refresh("game.html"); this.refresh("game.html");
@ -668,6 +669,7 @@ const SCENES = {
let body = document.createElement("article"); let body = document.createElement("article");
body.setAttribute("id", "article"); body.setAttribute("id", "article");
body.setAttribute("class", "text");
UI.maincontent(body); UI.maincontent(body);
this.refresh("main.html"); this.refresh("main.html");
@ -700,18 +702,27 @@ const SCENES = {
Profile:class{ Profile:class{
constructor() { constructor() {
this.data = { this.handle = "";
handle: "", this.stats = {
stats: {
games_played: 0, games_played: 0,
},
history: [ ],
}; };
this.history = [ ];
} }
load(data) { /*preload(data) {
if(sessionStorage.getItem("auth") === null) return false; this.data.handle = data.handle;
MESSAGE_COMPOSE([
PACK.u16(OpCode.UserInfo),
PACK.string(this.data.handle, PACK.u8),
]);
return true;
}*/
load(msg) {
/*if(msg.code != OpCode.UserInfo) {
return null;
}*/
this.handle = msg.handle;
UI.mainmenu_account(data, "profile"); UI.mainmenu_account(this.handle, "profile");
// Left Buttons // Left Buttons
let buttons_left = [ ]; let buttons_left = [ ];
@ -722,8 +733,24 @@ const SCENES = {
UI.mainnav(buttons_left, buttons_right); UI.mainnav(buttons_left, buttons_right);
// Main Content // Main Content
MAIN.setAttribute("class", "profile");
history.pushState(null, "Dzura - About", "/u/" + data.handle); let header = document.createElement("header");
let title = document.createElement("h1");
title.innerText = this.handle;
header.appendChild(title);
MAIN.appendChild(header);
let table_stats = document.createElement("table");
let container_history = document.createElement("section");
container_history.setAttribute("class", "history");
let table_history = document.createElement("table");
container_history.appendChild(table_history);
MAIN.appendChild(container_history);
history.pushState(null, "Dzura - About", "/u/" + this.handle);
return true; return true;
} }
}, },
@ -898,7 +925,7 @@ const SCENES = {
// Resume / Review Buttons // Resume / Review Buttons
if(msg.data.player != 0) { if(msg.data.player != 0) {
if(this.mode == INTERFACE.Mode.Review) { if(this.mode == INTERFACE.Mode.Review) {
if(!data.view.is_complete) { if(!msg.data.is_complete) {
let callback_resume = function() { let callback_resume = function() {
SCENE.load(SCENES.Game, { SCENE.load(SCENES.Game, {
token:this.token, token:this.token,

View File

@ -41,7 +41,6 @@ function RESUME() {
secret, secret,
]); ]);
} else { } else {
console.log("HERE");
SCENE.load_url(); SCENE.load_url();
} }
} }

View File

@ -189,16 +189,15 @@ const UI = {
} }
}, },
mainmenu_account(data, page) { mainmenu_account(handle, page) {
let buttons_top = [ ]; let buttons_top = [ ];
let buttons_bottom = [ ]; let buttons_bottom = [ ];
// Top Buttons // Top Buttons
buttons_top.push(UI.button("Profile", () => { SCENE.load(SCENES.Profile, { handle:CONTEXT.Auth.handle }) }, page == "profile")); buttons_top.push(UI.button("Profile", () => { SCENE.load(SCENES.Profile, { handle:CONTEXT.Auth.handle }) }, page == "profile"));
buttons_top.push(UI.button("History", () => { }, page == "history"));
// Bottom Buttons // Bottom Buttons
if(data === null || data.handle === CONTEXT.Auth.handle) { if(CONTEXT.Auth !== null && (handle === null || handle == CONTEXT.Auth.handle)) {
buttons_bottom.push(UI.button("Account", () => { SCENE.load(SCENES.Account) }, page == "account")); buttons_bottom.push(UI.button("Account", () => { SCENE.load(SCENES.Account) }, page == "account"));
buttons_bottom.push(UI.button("Subscription", () => { SCENE.load(SCENES.Subscription) }, page == "subscription")); buttons_bottom.push(UI.button("Subscription", () => { SCENE.load(SCENES.Subscription) }, page == "subscription"));
buttons_bottom.push(UI.button("Invitations", () => { SCENE.load(SCENES.Invitations) }, page == "invitations")); buttons_bottom.push(UI.button("Invitations", () => { SCENE.load(SCENES.Invitations) }, page == "invitations"));