Update profile page to live update

pull/5/head
sigonasr2 4 years ago
parent f9852b8ef1
commit c01cc3b5a4
  1. 2
      divabotguardian/DivaBotGuardian
  2. BIN
      divabotguardian/cropped.png
  3. 2
      divabotguardian/processes/3.divabotguardian
  4. 2
      divabotguardian/processes/3.ffmpeg
  5. BIN
      divabotguardian/streams/tempoutput0_3.png
  6. BIN
      divabotguardian/streams/tempoutput1_3.png
  7. BIN
      divabotguardian/streams/tempoutput2_3.png
  8. BIN
      divabotguardian/streams/tempoutput3_3.png
  9. BIN
      divabotguardian/streams/tempoutput4_3.png
  10. BIN
      divabotguardian/streams/tempoutput5_3.png
  11. BIN
      divabotguardian/streams/tempoutput6_3.png
  12. BIN
      divabotguardian/streams/tempoutput7_3.png
  13. BIN
      divabotguardian/streams/tempoutput8_3.png
  14. BIN
      divabotguardian/streams/tempoutput9_3.png
  15. 5
      frontend/package-lock.json
  16. 1
      frontend/package.json
  17. 95
      frontend/src/App.js
  18. 7
      frontend/src/setupProxy.js
  19. 2
      imgparser/projectDivaImgParser
  20. 53
      server/app.js
  21. 3
      server/invalidSongs

@ -1 +1 @@
Subproject commit e9b45b34b72f559faf87ea51d9746da802fd0aff
Subproject commit 729b36e47deaaa403ae45d8f94ce0ac67d31ed2b

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

@ -8483,6 +8483,11 @@
"minimist": "^1.2.5"
}
},
"moment": {
"version": "2.29.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.0.tgz",
"integrity": "sha512-z6IJ5HXYiuxvFTI6eiQ9dm77uE0gyy1yXNApVHqTcnIKfY9tIwEjlzsZ6u1LQXvVgKeTnv9Xm7NDvJ7lso3MtA=="
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",

@ -9,6 +9,7 @@
"@testing-library/user-event": "^7.2.1",
"axios": "^0.19.2",
"http-proxy-middleware": "^1.0.5",
"moment": "^2.29.0",
"react": "^16.13.1",
"react-bootstrap": "^1.3.0",
"react-dom": "^16.13.1",

@ -21,6 +21,7 @@ import {
const REMOTE_ADDR = "http://45.33.13.215:4502";
const axios = require('axios');
const moment = require('moment');
var IMAGE_CAMERA=(p)=>{
return(
@ -688,6 +689,8 @@ function LoadMore(p) {
var [visible,setVisible] = useState(false)
var [update,setUpdate] = useState(false)
const firstUpdate = useRef(true);
useEffect(()=>{
axios.get(p.url+constructParams(params))
.then((data)=>{
@ -695,7 +698,17 @@ function LoadMore(p) {
setVisible(true)
}
})
},[update])
},[update,p.profileUpdate])
useEffect(()=>{
if (firstUpdate.current) {
firstUpdate.current = false;
return;
}
var obj = params
obj.offset=p.params.offset
setParams(obj)
},[p.profileUpdate,p.username])
function constructParams(params) {
var st = Object.keys(params).reduce((str,key)=>{
@ -791,14 +804,14 @@ function BestPlaysPanel(p) {
useEffect(()=>{
axios.get("http://www.projectdivar.com/bestplays/"+p.username+"?fails=false&limit=5&offset=0")
.then((data)=>{setBestPlays(data.data);})
},[update,p.username])
},[p.profileUpdate,update,p.username])
var content=<div className="col-md-12 mt-3 mb-3">
<ul className="list-group list-group-flush border border-danger rounded-lg">
{bestPlays.map((play,i)=>{return <li key={play.id} className={"list-group-item list-group-item-action "+(i%2==0?"background-list-1":"background-list-2")}>
{bestPlays.map((play,i)=>{return <li key={i} className={"list-group-item list-group-item-action "+(i%2==0?"background-list-1":"background-list-2")}>
<Play setModalSrc={p.setModalSrc} setModalVisible={p.setModalVisible} index={i} play={play} song={p.songs[play.songid]}/>
</li>})}
<LoadMore listItem={true} url={"http://www.projectdivar.com/bestplays/"+p.username} params={{fails:false,limit:15,offset:5}} value={bestPlays} setValue={setBestPlays}/>
<LoadMore username={p.username} profileUpdate={p.profileUpdate} listItem={true} url={"http://www.projectdivar.com/bestplays/"+p.username} params={{fails:false,limit:15,offset:5}} value={bestPlays} setValue={setBestPlays}/>
</ul>
</div>
@ -887,7 +900,7 @@ function PlayData(p) {
useEffect(()=>{
axios.get("http://projectdivar.com/plays/"+p.username+"/"+p.song.id)
.then((data)=>{setData(data.data);})
},[update])
},[p.profileUpdate,update])
return (
<>
@ -895,7 +908,7 @@ function PlayData(p) {
<h5>Individual Plays for {p.song.name} from {p.username}</h5>
<div className="border rounded">
{data.map((play,i)=><Play setModalSrc={p.setModalSrc} setModalVisible={p.setModalVisible} key={i} play={play} mini={true} song={p.song}/>)}
<LoadMore url={"http://www.projectdivar.com/plays/"+p.username+"/"+p.song.id} params={{limit:15,offset:5}} value={data} setValue={setData}/>
<LoadMore profileUpdate={p.profileUpdate} url={"http://www.projectdivar.com/plays/"+p.username+"/"+p.song.id} params={{limit:15,offset:5}} value={data} setValue={setData}/>
</div>
</div>
</>
@ -931,14 +944,16 @@ function HoverSongName(p) {
if ((p.song.report.ecount+p.song.report.ncount+p.song.report.hcount+p.song.report.excount+p.song.report.exexcount>0)) {
if (toggle) {
setExpand(<tr className="fadein">
<td colSpan="6"><PlayData setModalSrc={p.setModalSrc} setModalVisible={p.setModalVisible} song={p.song} username={p.username}/></td>
<td colSpan="6"><PlayData profileUpdate={p.profileUpdate} setModalSrc={p.setModalSrc} setModalVisible={p.setModalVisible} song={p.song} username={p.username}/></td>
</tr>)
window.scroll(0,cumulativeOffset(document.getElementById("songRow_"+p.song.name)).top-document.getElementById("songRow_"+p.song.name).getBoundingClientRect().height);
if (match!==null) {
window.scroll(0,cumulativeOffset(document.getElementById("songRow_"+p.song.name)).top-document.getElementById("songRow_"+p.song.name).getBoundingClientRect().height);
}
} else {
setExpand(<></>)
}
}
},[toggle])
},[p.profileUpdate,toggle])
return (
<>
@ -981,6 +996,15 @@ function CompletionPanel(p) {
.then((data)=>{setReport(data.data)})
.catch((err)=>{console.log(err.message)})
},[update,p.username])
useEffect(()=>{
if (firstUpdate.current) {
firstUpdate.current = false;
return;
}
setUpdate(!update)
},[p.profileUpdate])
const firstUpdate = useRef(true);
return (
<>
@ -1009,7 +1033,7 @@ function CompletionPanel(p) {
</tr>
</thead>
<tbody>
{report.filter((report)=>Object.keys(filter).length==0||report.id in filter).map((song,i)=>{return (HasSong(song,p.user))?<HoverSongName setModalSrc={p.setModalSrc} setModalVisible={p.setModalVisible} to={song.name} song={song} key={song.id} username={p.username}/>:<></>
{report.filter((report)=>Object.keys(filter).length==0||report.id in filter).map((song,i)=>{return (HasSong(song,p.user))?<HoverSongName profileUpdate={p.profileUpdate} setModalSrc={p.setModalSrc} setModalVisible={p.setModalVisible} to={song.name} song={song} key={song.id} username={p.username}/>:<></>
})}
</tbody>
<tfoot>
@ -1112,6 +1136,10 @@ function Profile(p){
var [modalsrc,setModalSrc] = useState({})
var [modalVisible,setModalVisible] = useState(false);
var [mouseOver,setMouseOver] = useState(false);
var [loadedTime,setLoadedTime] = useState(new Date());
const firstUpdate = useRef(true);
let history = useHistory();
function CalculateClear(easy,normal,hard,ex,exex,fcdata,pfcdata) {
return <>
@ -1123,12 +1151,39 @@ function Profile(p){
</>
}
useEffect(()=>{
if (firstUpdate.current) {
firstUpdate.current = false;
return;
}
setUpdate(!update)
},[loadedTime])
useEffect(()=>{
axios.get("http://projectdivar.com:4501/userdata/"+username)
.then((data)=>{setUserData(data.data);setPlayCount(data.data.playcount);setFCCount(data.data.fccount);setRating(data.data.rating);setLastPlayed(data.data.last_played);setAccuracy(CalculateAccuracy(data.data.cool,data.data.fine,data.data.safe,data.data.sad,data.data.worst))});
axios.get("http://projectdivar.com:4501/songdiffs")
.then((data)=>{setDiffs(data.data)})
setModalVisible(false);
const interval = setInterval(()=>{
axios.get("http://projectdivar.com/userdata/"+username)
.then((data)=>{
return axios.get("http://projectdivar.com/updates/"+data.data.id)
})
.then((data)=>{
//Positive number means new update is available for this profile.
//console.log(moment(data.data.date).diff(loadedTime))
if (moment(data.data.date).diff(loadedTime)>0) {
setLoadedTime(new Date())
history.push("/user/"+username)
}
})
.catch((err)=>{
//console.log(err.message)
})
},10000)
return ()=>clearInterval(interval)
},[update,username])
useEffect(()=>{
@ -1155,8 +1210,8 @@ function Profile(p){
</div>}
<StatisticsPanel name="Statistics" setMouseOver={setMouseOver} username={username} playcount={playcount} fccount={fccount} cleared={cleared} accuracy={accuracy}/>
<HitCountsPanel name="Hit Counts" username={username} user={user}/>
<BestPlaysPanel name="Best Plays" setModalVisible={setModalVisible} setModalSrc={setModalSrc} username={username} songs={p.songs}/>
<CompletionPanel name="Progress" user={user} setModalVisible={setModalVisible} setModalSrc={setModalSrc} username={username} songs={p.songs}/>
<BestPlaysPanel profileUpdate={update} name="Best Plays" setModalVisible={setModalVisible} setModalSrc={setModalSrc} username={username} songs={p.songs}/>
<CompletionPanel profileUpdate={update} name="Progress" user={user} setModalVisible={setModalVisible} setModalSrc={setModalSrc} username={username} songs={p.songs}/>
<Panel name="Activity" username={username}/>
</>
:<></>
@ -1508,6 +1563,7 @@ function LoginInfo(p) {
Welcome, <b>{username}</b>!<br/>
<Link to={"/user/"+username}>My Profile</Link><br/>
<Link to={"/usersettings"}>Edit Profile Settings</Link><br/>
<Link to={"/streampanel"}>My Stream Panel</Link><br/>
<Link to="/auth">App Auth Code</Link><br/>
</>:<>
@ -1849,6 +1905,17 @@ function DivaBot() {
)
}
function StreamPanel(p) {
const [update,setUpdate] = useState(false);
return (
<>
</>
)
}
function StreamData() {
const [imageSet,setImageSet] = useState(0);
const [rando1,setRando1] = useState(Date.now());
@ -1938,6 +2005,10 @@ function Website() {
<h1 className="title">Register New Account</h1>
<Register isLoggedIn={username!==undefined} setLoginPanelUpdate={setLoginPanelUpdate}/>
</Route>
<Route path="/streampanel">
<h1 className="title">Stream Panel</h1>
<StreamPanel setUserSettings={setUserSettings} userSettings={userSettings} isLoggedIn={username!==undefined} setLoginPanelUpdate={setLoginPanelUpdate}/>
</Route>
<Route path="/stream">
<h1 className="title">Stream</h1>
<StreamData/>

@ -1,6 +1,13 @@
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
"/updates/:userid",
createProxyMiddleware({
target: 'http://server:4501',
changeOrigin: true,
})
);
app.use(
"/passImageData",
createProxyMiddleware({

@ -1 +1 @@
Subproject commit 457bbb6fa840d8a36b2f6b935bb2fc4066891a5f
Subproject commit bcf04481d4cb70d35b8c5a9d8602eb2fde115cc3

@ -117,7 +117,9 @@ app.delete('/remove',(req,res)=>{
.then((data)=>{if(data && data.rows.length>0){songObj=data.rows[0];return CalculateRating(req.body.username)}else{throw new Error("Could not find play!")}})
.then((data)=>{rating=data;return db.query("select * from plays where songid=$1 and userid=$2 and difficulty=$3 and score>0 limit 1",[songObj.songid,userObj.id,songObj.difficulty])})
.then((data)=>{if(data && data.rows.length===0){isFirstClear=true;}/*console.log([data,userObj.playcount-1,(songObj.safe==0&&songObj.sad==0&&songObj.worst==0)?userObj.fccount-1:userObj.fccount,userObj.cool-songObj.cool,userObj.fine-songObj.fine,userObj.safe-songObj.safe,userObj.sad-songObj.sad,userObj.worst-songObj.worst,(songObj.difficulty=="E")?userObj.ecount-1:userObj.ecount,(songObj.difficulty=="N")?userObj.ncount-1:userObj.ncount,(songObj.difficulty=="H")?userObj.hcount-1:userObj.hcount,(songObj.difficulty=="EX")?userObj.excount-1:userObj.excount,(songObj.difficulty=="EXEX")?userObj.exexcount-1:userObj.exexcount]);*/return db.query("update users set rating=$1,playcount=$2,fccount=$3,cool=$4,fine=$5,safe=$6,sad=$7,worst=$8,eclear=$9,nclear=$10,hclear=$11,exclear=$12,exexclear=$13 where id=$14 returning rating,playcount,fccount,cool,fine,safe,sad,worst,eclear,nclear,hclear,exclear,exexclear",[rating,userObj.playcount-1,(songObj.safe==0&&songObj.sad==0&&songObj.worst==0)?userObj.fccount-1:userObj.fccount,userObj.cool-songObj.cool,userObj.fine-songObj.fine,userObj.safe-songObj.safe,userObj.sad-songObj.sad,userObj.worst-songObj.worst,(songObj.difficulty=="E" && isFirstClear)?userObj.eclear-1:userObj.eclear,(songObj.difficulty=="N" && isFirstClear)?userObj.nclear-1:userObj.nclear,(songObj.difficulty=="H" && isFirstClear)?userObj.hclear-1:userObj.hclear,(songObj.difficulty=="EX" && isFirstClear)?userObj.exclear-1:userObj.exclear,(songObj.difficulty=="EXEX" && isFirstClear)?userObj.exexclear-1:userObj.exexclear,userObj.id])})
.then((data)=>{if(data && data.rows.length>0){res.status(200).json({user:data.rows[0],song:songObj})}else{throw new Error("Could not update user information, but song is deleted!")}})
.then((data)=>{if(data && data.rows.length>0){res.status(200).json({user:data.rows[0],song:songObj})
axios.post("http://projectdivar.com/updates/"+userObj.id,{password:process.env.GMAIL,type:"delete"})
}else{throw new Error("Could not update user information, but song is deleted!")}})
.catch((err)=>{res.status(500).json(err.message)})
} else {
res.status(400).send("Missing required parameters!");
@ -296,10 +298,14 @@ app.post('/submit', (req, res) => {
.then((data)=>{return db.query("update users set rating=$1,last_played=$3,playcount=$4,fccount=$5,cool=$6,fine=$7,safe=$8,sad=$9,worst=$10,eclear=$11,nclear=$12,hclear=$13,exclear=$14,exexclear=$15,megamix=$16,futuretone=$17 where username=$2",[data,req.body.username,new Date(),++playcount,fccount+((isFC)?1:0),cool+Number(req.body.cool),fine+Number(req.body.fine),safe+Number(req.body.safe),sad+Number(req.body.sad),worst+Number(req.body.worst),eclear,nclear,hclear,exclear,exexclear,(songdata.mega39s||userObj.megamix),(songdata.futuretone&&!songdata.mega39s)||userObj.futuretone])})
.then((data)=>{return songsubmitdata;})
.then((data)=>{
//userId
//password, type
axios.post("http://projectdivar.com/updates/"+userId,{password:process.env.GMAIL,type:"submit"})
if (req.body.src) {
db.query("delete from uploadedplays where filename=$1",[req.body.src])
}
res.status(200).json(data);})
res.status(200).json(data);
})
.catch((err)=>{
//console.log(req.body);
console.log(err);
@ -384,6 +390,42 @@ app.get('/accuracy/:username',(req,res)=>{
.catch((err)=>{res.status(500).send(err.message)})
})
app.get('/updates/:userid',(req,res)=>{
db.query('select * from userupdate where userid=$1',[req.params.userid])
.then((data)=>{
if (data.rows.length>0) {
res.status(200).json(data.rows[0])
} else {
res.status(400).send("No user update found!")
}
})
.catch((err)=>{
res.status(500).send(err.message)
})
})
app.post('/updates/:userid',(req,res)=>{
if (req.body&&req.body.password&&req.body.type) {
if (req.body.password===process.env.GMAIL) {
db.query("insert into userupdate(userid,update_type,date) values($1,$2,$3) on conflict(userid) do update set update_type=$2,date=$3 where userupdate.userid=$1 returning *",[req.params.userid,req.body.type,moment()])
.then((data)=>{
if (data.rows.length>=0) {
res.status(200).send(data.rows[0])
} else {
throw new Error("Could not update user.")
}
})
.catch((err)=>{
res.status(500).send(err.message)
})
} else {
res.status(403).send("Could not authenticate")
}
} else {
res.status(400).send("Invalid credentials!")
}
})
app.get('/recalculatescore/:playid',(req,res)=>{
var userId=-1;
var username=null;
@ -400,6 +442,9 @@ app.get('/recalculatescore/:playid',(req,res)=>{
return db.query('select username from users where id=$1',[userId]).then((data)=>{username=data.rows[0].username; return CalculateRating(username)}).then((data)=>{db.query("update users set rating=$1 where username=$2",[data,username])})
.then(()=>{return scoreData;})
}else{throw new Error("Failed to update score!")}})
.then((data)=>{
axios.post("http://projectdivar.com/updates/"+userId,{password:process.env.GMAIL,type:"recalculate"})
})
.then((data)=>res.status(200).json(data)).catch((err)=>{console.log(err);res.status(500).send(err.message);})
});
@ -492,7 +537,7 @@ app.get('/bestplay/:username/:songname/:difficulty',(req,res)=>{
app.get('/userdata/:username',(req,res)=>{
var songId=-1,userId=-1,finalData={};
db.query('select megamix,futuretone,playstyle,playcount,fccount,rating,last_played,cool,fine,safe,sad,worst,eclear,nclear,hclear,exclear,exexclear from users where username=$1 limit 1',[req.params.username])
db.query('select id,megamix,futuretone,playstyle,playcount,fccount,rating,last_played,cool,fine,safe,sad,worst,eclear,nclear,hclear,exclear,exexclear from users where username=$1 limit 1',[req.params.username])
.then((data)=>{if(data && data.rows.length>0){finalData=data.rows[0];return db.query("select t.difficulty,COUNT(t.difficulty) from (select distinct on(songid) songid,*,users.id from plays join users on userid=users.id where users.username=$1 and plays.safe=0 and plays.worst=0 and plays.sad=0)t group by t.difficulty",[req.params.username])}else{throw new Error("Could not retrieve user data!")}})
.then((data)=>{
if (data) {
@ -799,7 +844,7 @@ function GetUserInfo(username) {
return db.query("select id,username,email,code_time from users where username=$1 limit 1",[username])
}
function GetUserLoginAllowed(username,authCode) {
return db.query("select id,username,email,code_time,playstyle,twitter_name from users where username=$1 and code=$2 limit 1",[username,authCode])
return db.query("select id,username,email,code_time,playstyle,twitter_name,twitch_name from users where username=$1 and code=$2 limit 1",[username,authCode])
}
app.post('/authenticate/authToken',(req,res)=>{
if (req.body&&req.body.username&&req.body.authCode) {

@ -81,3 +81,6 @@
{"song":"深海シティアンダーグラウンド","username":"sigonasr2","authentication_token":"sig","difficulty":"","cool":"-1","fine":"-1","safe":"-1","sad":"-1","worst":"-1","percent":"-1.0","fail":"false","combo":"-1","mod":"","gameScore":"-1","src":"http://pbs.twimg.com/media/EiK0POLVkAIFpho.jpg"}
{"song":"深海シティアンダーグラウンド","username":"sigonasr2","authentication_token":"sig","difficulty":"","cool":"-1","fine":"-1","safe":"-1","sad":"-1","worst":"-1","percent":"-1.0","fail":"false","combo":"-1","mod":"","gameScore":"-1","src":"http://pbs.twimg.com/media/EiK0POLVkAIFpho.jpg"}
{"song":"スノーマン","username":"sigonasr2","authentication_token":"sig","difficulty":"","cool":"-1","fine":"-1","safe":"-1","sad":"-1","worst":"-1","percent":"-1.0","fail":"false","combo":"-1","mod":"","gameScore":"-1","src":"http://projectdivar.com/files/plays/3/690"}
{"song":"恋は戦争","username":"sigonasr2","authentication_token":"sig","difficulty":"","cool":"-1","fine":"-1","safe":"-1","sad":"-1","worst":"-1","percent":"-1.0","fail":"false","combo":"-1","mod":"","gameScore":"-1","src":"http://projectdivar.com/files/plays/3/692"}
{"song":"スノーマン","username":"sigonasr2","authentication_token":"sig","difficulty":"","cool":"-1","fine":"-1","safe":"-1","sad":"-1","worst":"-1","percent":"-1.0","fail":"false","combo":"-1","mod":"","gameScore":"-1","src":"http://projectdivar.com/files/plays/3/695"}
{"song":"スノーマン","username":"testStreamer","authentication_token":"test","difficulty":"","cool":"-1","fine":"-1","safe":"-1","sad":"-1","worst":"-1","percent":"-1.0","fail":"false","combo":"-1","mod":"","gameScore":"-1","src":"http://projectdivar.com/files/plays/64/7"}

Loading…
Cancel
Save