Add in navigation / back to top of page button
This commit is contained in:
parent
6e01f96772
commit
d39482aadc
8
frontend/package-lock.json
generated
8
frontend/package-lock.json
generated
@ -10849,6 +10849,14 @@
|
|||||||
"tiny-warning": "^1.0.0"
|
"tiny-warning": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-router-hash-link": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router-hash-link/-/react-router-hash-link-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-U/WizkZwV2IoxLScRJX5CHJWreXjv/kCmjT/LpfYiFdXGnrKgPd0KqcA4KfmQbkwO411OwDmUKKz+bOKoMkzKg==",
|
||||||
|
"requires": {
|
||||||
|
"prop-types": "^15.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-scripts": {
|
"react-scripts": {
|
||||||
"version": "3.4.1",
|
"version": "3.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz",
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
"react-bootstrap": "^1.3.0",
|
"react-bootstrap": "^1.3.0",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
|
"react-router-hash-link": "^2.1.0",
|
||||||
"react-scripts": "3.4.1"
|
"react-scripts": "3.4.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -93,6 +93,28 @@ body {
|
|||||||
0 0 8px #999
|
0 0 8px #999
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.superglow{
|
||||||
|
color: #eee;
|
||||||
|
text-shadow:
|
||||||
|
0 0 1px #999,
|
||||||
|
0 0 2px #999,
|
||||||
|
0 0 4px #999,
|
||||||
|
0 0 8px #fff
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
h1.superglow{
|
||||||
|
font-size:6vw;
|
||||||
|
font-weight: bold;
|
||||||
|
background-color:rgba(1,1,1,0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
p.superglow{
|
||||||
|
font-size:1.5vw;
|
||||||
|
font-weight: bold;
|
||||||
|
background-color:rgba(1,1,1,0.6);
|
||||||
|
}
|
||||||
|
|
||||||
.nostyle{
|
.nostyle{
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
@ -5,17 +5,23 @@ import {
|
|||||||
BrowserRouter as Router,
|
BrowserRouter as Router,
|
||||||
Switch,
|
Switch,
|
||||||
Route,
|
Route,
|
||||||
Link,
|
Redirect,
|
||||||
useRouteMatch,
|
useRouteMatch,
|
||||||
useParams,
|
useParams,
|
||||||
useHistory
|
useHistory,
|
||||||
|
useLocation
|
||||||
} from "react-router-dom";
|
} from "react-router-dom";
|
||||||
|
|
||||||
|
import { HashLink as Link } from 'react-router-hash-link';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Modal,
|
Modal,
|
||||||
Button,
|
Button,
|
||||||
Form,
|
Form,
|
||||||
Badge
|
Badge,
|
||||||
|
Card,
|
||||||
|
Spinner,
|
||||||
|
Carousel
|
||||||
} from "react-bootstrap";
|
} from "react-bootstrap";
|
||||||
|
|
||||||
const REMOTE_ADDR = "http://45.33.13.215:4502";
|
const REMOTE_ADDR = "http://45.33.13.215:4502";
|
||||||
@ -64,6 +70,26 @@ var IMAGE_TABLET=(p)=>{
|
|||||||
</svg>
|
</svg>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
var IMAGE_CHECKMARK=(p)=>{
|
||||||
|
return (<svg width="1em" height="1em" {...p} viewBox="0 0 16 16" className="bi bi-check-circle-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fillRule="evenodd" d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
var IMAGE_X=(p)=>{
|
||||||
|
return (
|
||||||
|
<svg width="1em" height="1em" viewBox="0 0 16 16" {...p} className="bi bi-x-circle-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fillRule="evenodd" d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
var IMAGE_ARROWUP=(p)=>{
|
||||||
|
return (
|
||||||
|
<svg width="1em" height="1em" viewBox="0 0 16 16" {...p} className="bi bi-arrow-up-circle-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fillRule="evenodd" d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-7.5 3.5a.5.5 0 0 1-1 0V5.707L5.354 7.854a.5.5 0 1 1-.708-.708l3-3a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708L8.5 5.707V11.5z"/>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
var IMAGE_MIXMODE=(p)=>{
|
var IMAGE_MIXMODE=(p)=>{
|
||||||
return(
|
return(
|
||||||
<svg width="1em" height="1em" {...p} viewBox="0 0 16 16" className="bi" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
<svg width="1em" height="1em" {...p} viewBox="0 0 16 16" className="bi" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||||
@ -688,6 +714,7 @@ function LoadMore(p) {
|
|||||||
var [loading,setLoading] = useState(false)
|
var [loading,setLoading] = useState(false)
|
||||||
var [visible,setVisible] = useState(false)
|
var [visible,setVisible] = useState(false)
|
||||||
var [update,setUpdate] = useState(false)
|
var [update,setUpdate] = useState(false)
|
||||||
|
var [reloadLoadMore,setReloadLoadMore] = useState(false)
|
||||||
|
|
||||||
const firstUpdate = useRef(true);
|
const firstUpdate = useRef(true);
|
||||||
|
|
||||||
@ -698,7 +725,7 @@ function LoadMore(p) {
|
|||||||
setVisible(true)
|
setVisible(true)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},[update,p.profileUpdate])
|
},[update,p.profileUpdate,reloadLoadMore])
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if (firstUpdate.current) {
|
if (firstUpdate.current) {
|
||||||
@ -708,6 +735,7 @@ function LoadMore(p) {
|
|||||||
var obj = params
|
var obj = params
|
||||||
obj.offset=p.params.offset
|
obj.offset=p.params.offset
|
||||||
setParams(obj)
|
setParams(obj)
|
||||||
|
setReloadLoadMore(!reloadLoadMore)
|
||||||
},[p.profileUpdate,p.username])
|
},[p.profileUpdate,p.username])
|
||||||
|
|
||||||
function constructParams(params) {
|
function constructParams(params) {
|
||||||
@ -1140,6 +1168,7 @@ function Profile(p){
|
|||||||
|
|
||||||
const firstUpdate = useRef(true);
|
const firstUpdate = useRef(true);
|
||||||
let history = useHistory();
|
let history = useHistory();
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
function CalculateClear(easy,normal,hard,ex,exex,fcdata,pfcdata) {
|
function CalculateClear(easy,normal,hard,ex,exex,fcdata,pfcdata) {
|
||||||
return <>
|
return <>
|
||||||
@ -1213,6 +1242,7 @@ function Profile(p){
|
|||||||
<BestPlaysPanel profileUpdate={update} name="Best Plays" 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}/>
|
<CompletionPanel profileUpdate={update} name="Progress" user={user} setModalVisible={setModalVisible} setModalSrc={setModalSrc} username={username} songs={p.songs}/>
|
||||||
<Panel name="Activity" username={username}/>
|
<Panel name="Activity" username={username}/>
|
||||||
|
<Link smooth to={location.pathname+"#content"}><IMAGE_ARROWUP style={{fontSize:"32px",position:"fixed",right:"18px",bottom:"18px"}}/></Link>
|
||||||
</>
|
</>
|
||||||
:<></>
|
:<></>
|
||||||
}
|
}
|
||||||
@ -1469,7 +1499,7 @@ function Submit(p) {
|
|||||||
<Route path="/submitplay">
|
<Route path="/submitplay">
|
||||||
<h2>Select a submission method</h2>
|
<h2>Select a submission method</h2>
|
||||||
{false&&<><div className="card">
|
{false&&<><div className="card">
|
||||||
<Link to="/submitplay/simple" className="nostyle">
|
<Link smooth to="/submitplay/simple#content" className="nostyle">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<h5 className="card-title">Manual Submit</h5>
|
<h5 className="card-title">Manual Submit</h5>
|
||||||
<p className="card-text">Submit your plays by entering the clear % of a song</p>
|
<p className="card-text">Submit your plays by entering the clear % of a song</p>
|
||||||
@ -1479,7 +1509,7 @@ function Submit(p) {
|
|||||||
</div>
|
</div>
|
||||||
<br/></>}
|
<br/></>}
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<Link to="/submitplay/image" className="nostyle">
|
<Link smooth to="/submitplay/image#content" className="nostyle">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<h5 className="card-title">Image Upload</h5>
|
<h5 className="card-title">Image Upload</h5>
|
||||||
<p className="card-text">Upload images from your Playstation/Nintendo Switch for automatic processing/scoring!</p>
|
<p className="card-text">Upload images from your Playstation/Nintendo Switch for automatic processing/scoring!</p>
|
||||||
@ -1489,7 +1519,7 @@ function Submit(p) {
|
|||||||
</div>
|
</div>
|
||||||
<br/>
|
<br/>
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<Link to="/submitplay/switch" className="nostyle">
|
<Link smooth to="/submitplay/switch#content" className="nostyle">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<h5 className="card-title">Playstation/Nintendo Switch/Twitter Upload</h5>
|
<h5 className="card-title">Playstation/Nintendo Switch/Twitter Upload</h5>
|
||||||
<p className="card-text">Setup your account for uploading through Twitter using your Playstation or Nintendo Switch!</p>
|
<p className="card-text">Setup your account for uploading through Twitter using your Playstation or Nintendo Switch!</p>
|
||||||
@ -1497,6 +1527,26 @@ function Submit(p) {
|
|||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
<br/>
|
||||||
|
<div className="card">
|
||||||
|
<Link smooth to="/streampanel#content" className="nostyle">
|
||||||
|
<div className="card-body">
|
||||||
|
<h5 className="card-title">Stream Monitoring</h5>
|
||||||
|
<p className="card-text">Stream <b>Project Diva Future Tone</b> through your Playstation 4 to submit records!</p>
|
||||||
|
<p className="card-text"><small className="text-muted">Specify your Twitch account and then start up a stream monitor that will watch your game as you play, recording your results.</small></p>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<div className="card">
|
||||||
|
<Link smooth to="/divabot#content" className="nostyle">
|
||||||
|
<div className="card-body">
|
||||||
|
<h5 className="card-title">DivaBot</h5>
|
||||||
|
<p className="card-text">Use your capture card / stream setup to monitor your game screen as you play.</p>
|
||||||
|
<p className="card-text"><small className="text-muted">This uses software developed by <b>sigonasr2</b> that automatically records your results as you play.</small></p>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
</Route>
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
@ -1507,11 +1557,13 @@ function Submit(p) {
|
|||||||
function RecentPlays(p) {
|
function RecentPlays(p) {
|
||||||
const [update,setUpdate] = useState(false)
|
const [update,setUpdate] = useState(false)
|
||||||
const [recentPlayData,setRecentPlayData] = useState([])
|
const [recentPlayData,setRecentPlayData] = useState([])
|
||||||
|
var [modalsrc,setModalSrc] = useState({})
|
||||||
|
var [modalVisible,setModalVisible] = useState(false);
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
|
|
||||||
const interval = setInterval(()=>{
|
const interval = setInterval(()=>{
|
||||||
axios.get("http://projectdivar.com/recentplays/sigonasr2")
|
axios.get("http://projectdivar.com/recentplays/"+p.username)
|
||||||
.then((data)=>{
|
.then((data)=>{
|
||||||
setRecentPlayData(data.data);
|
setRecentPlayData(data.data);
|
||||||
})
|
})
|
||||||
@ -1523,7 +1575,8 @@ function RecentPlays(p) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{recentPlayData.map((play,i)=><Play index={i} play={play} song={p.songs[play.songid]} title={true} mini={true}/>)}
|
<ImageDisplayer username={p.username} songs={p.songs} play={modalsrc} modalVisible={modalVisible} setModalVisible={setModalVisible}></ImageDisplayer>
|
||||||
|
{recentPlayData.map((play,i)=><Play setModalVisible={setModalVisible} setModalSrc={setModalSrc} index={i} play={play} song={p.songs[play.songid]} title={true} mini={true}/>)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1561,14 +1614,12 @@ function LoginInfo(p) {
|
|||||||
<>
|
<>
|
||||||
{loggedIn?<>
|
{loggedIn?<>
|
||||||
Welcome, <b>{username}</b>!<br/>
|
Welcome, <b>{username}</b>!<br/>
|
||||||
<Link to={"/user/"+username}>My Profile</Link><br/>
|
<Link smooth to={"/user/"+username+"#content"}>My Profile</Link><br/>
|
||||||
<Link to={"/usersettings"}>Edit Profile Settings</Link><br/>
|
<Link smooth to={"/usersettings#content"}>Edit Profile Settings</Link><br/>
|
||||||
<Link to={"/streampanel"}>My Stream Panel</Link><br/>
|
<Link smooth to={"/streampanel#content"}>My Stream Panel</Link><br/>
|
||||||
<Link to="/auth">App Auth Code</Link><br/>
|
|
||||||
|
|
||||||
</>:<>
|
</>:<>
|
||||||
<Link to="/login">Login</Link><br/>
|
<Link smooth to="/login#content">Login</Link><br/>
|
||||||
<Link to="/register">Register</Link>
|
<Link smooth to="/register#content">Register</Link>
|
||||||
</>}
|
</>}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
@ -1584,7 +1635,7 @@ function Login(p) {
|
|||||||
let history = useHistory();
|
let history = useHistory();
|
||||||
|
|
||||||
if (p.isLoggedIn) {
|
if (p.isLoggedIn) {
|
||||||
history.push("/")
|
return (<Redirect to="/"/>)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -1678,7 +1729,7 @@ function Register(p) {
|
|||||||
</>}
|
</>}
|
||||||
<Form.Group controlId="formUsername">
|
<Form.Group controlId="formUsername">
|
||||||
<Form.Label>Username</Form.Label>
|
<Form.Label>Username</Form.Label>
|
||||||
<Form.Control disabled={authCodeVisible} isInvalid={username.length<1} onChange={(e)=>{setUsername(e.currentTarget.value)}} placeholder="MikuMiku" value={username} />
|
<Form.Control disabled={authCodeVisible} isInvalid={username.length<1||username.includes("/")||username.includes("\\")} onChange={(e)=>{setUsername(e.currentTarget.value)}} placeholder="MikuMiku" value={username} />
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
<Form.Group controlId="formEmail">
|
<Form.Group controlId="formEmail">
|
||||||
<Form.Label>Email Address</Form.Label>
|
<Form.Label>Email Address</Form.Label>
|
||||||
@ -1701,7 +1752,8 @@ function Register(p) {
|
|||||||
</div></>
|
</div></>
|
||||||
}
|
}
|
||||||
<Button disabled={disabled} variant="primary" type="submit" onClick={(e)=>{e.preventDefault()
|
<Button disabled={disabled} variant="primary" type="submit" onClick={(e)=>{e.preventDefault()
|
||||||
if (username.length>=1&&email.length>=1) {
|
if (username.length>=1&&email.length>=1
|
||||||
|
&&!username.includes("/")&&!username.includes("\\")) {
|
||||||
setDisabled(true)
|
setDisabled(true)
|
||||||
setError(false)
|
setError(false)
|
||||||
if (authCode.length===5) {
|
if (authCode.length===5) {
|
||||||
@ -1750,11 +1802,13 @@ function UserSettings(p) {
|
|||||||
const [playStyleHover,setPlayStyleHover] = useState(undefined)
|
const [playStyleHover,setPlayStyleHover] = useState(undefined)
|
||||||
const [twitter,setTwitter] = useState(p.userSettings.twitter_name)
|
const [twitter,setTwitter] = useState(p.userSettings.twitter_name)
|
||||||
const [twitterChange,setTwitterChange] = useState(false)
|
const [twitterChange,setTwitterChange] = useState(false)
|
||||||
|
const [twitch,setTwitch] = useState(p.userSettings.twitch_name)
|
||||||
|
const [twitchChange,setTwitchChange] = useState(false)
|
||||||
const [message,setMessage] = useState(false)
|
const [message,setMessage] = useState(false)
|
||||||
const [error,setError] = useState(false)
|
const [error,setError] = useState(false)
|
||||||
|
|
||||||
if (p.username===undefined) {
|
if (p.username===undefined) {
|
||||||
history.push("/")
|
return (<Redirect to="/"/>)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -1772,13 +1826,20 @@ function UserSettings(p) {
|
|||||||
</Form.Text>
|
</Form.Text>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
<hr/>
|
<hr/>
|
||||||
<Form.Group controlId="twitter" onMouseOut={()=>{setPlayStyleHover(undefined)}}>
|
<Form.Group controlId="twitter">
|
||||||
<Form.Label>Twitter Username:</Form.Label>
|
<Form.Label>Twitter Username:</Form.Label>
|
||||||
<Form.Control onChange={(e)=>{setTwitter(e.currentTarget.value);setTwitterChange(true)}} value={twitter} placeholder="MikuMiku"/>
|
<Form.Control onChange={(e)=>{setTwitter(e.currentTarget.value);setTwitterChange(true)}} value={twitter} placeholder="MikuMiku"/>
|
||||||
<Form.Text className="text-muted">
|
<Form.Text className="text-muted">
|
||||||
If you input your Twitter username, you can submit screenshots to <b>@divarbot</b> (with "@divarbot" in the message) and your plays will auto-submit from Twitter at any time.
|
If you input your Twitter username, you can submit screenshots to <b>@divarbot</b> (with "@divarbot" in the message) and your plays will auto-submit from Twitter at any time.
|
||||||
</Form.Text>
|
</Form.Text>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
|
<Form.Group controlId="twitch">
|
||||||
|
<Form.Label className="pt-4">Twitch Username:</Form.Label>
|
||||||
|
<Form.Control onChange={(e)=>{setTwitch(e.currentTarget.value);setTwitchChange(true)}} value={twitch} placeholder="MikuMikuStreams"/>
|
||||||
|
<Form.Text className="text-muted">
|
||||||
|
If you input your Twitch username, you can setup your stream using the <Link to="/streampanel">stream monitoring tool</Link>.
|
||||||
|
</Form.Text>
|
||||||
|
</Form.Group>
|
||||||
<Button onClick={()=>{
|
<Button onClick={()=>{
|
||||||
var obj = {username:localStorage.getItem("username"),
|
var obj = {username:localStorage.getItem("username"),
|
||||||
authCode:localStorage.getItem("authToken"),
|
authCode:localStorage.getItem("authToken"),
|
||||||
@ -1790,13 +1851,17 @@ function UserSettings(p) {
|
|||||||
if (twitterChange) {
|
if (twitterChange) {
|
||||||
obj.twitterName=twitter;
|
obj.twitterName=twitter;
|
||||||
}
|
}
|
||||||
|
if (twitchChange) {
|
||||||
|
obj.twitchName=twitch;
|
||||||
|
}
|
||||||
setError(false)
|
setError(false)
|
||||||
setMessage(false)
|
setMessage(false)
|
||||||
axios.post("http://projectdivar.com/updateuser",obj)
|
axios.post("http://projectdivar.com/updateuser",obj)
|
||||||
.then((data)=>{
|
.then((data)=>{
|
||||||
setMessage(data.data)
|
setMessage(data.data)
|
||||||
p.setUserSettings({...p.userSettings,playStyle:playStyle,twitter_name:twitter})
|
p.setUserSettings({...p.userSettings,playStyle:playStyle,twitter_name:twitter,twitch_name:twitch})
|
||||||
setTwitterChange(false)
|
setTwitterChange(false)
|
||||||
|
setTwitchChange(false)
|
||||||
})
|
})
|
||||||
.catch((err)=>{
|
.catch((err)=>{
|
||||||
setError(err.message)
|
setError(err.message)
|
||||||
@ -1804,6 +1869,8 @@ function UserSettings(p) {
|
|||||||
}}>Save Changes</Button>
|
}}>Save Changes</Button>
|
||||||
{message&&<h3 style={{color:"green"}}>{message}</h3>}
|
{message&&<h3 style={{color:"green"}}>{message}</h3>}
|
||||||
{error&&<h3 style={{color:"red"}}>{error}</h3>}
|
{error&&<h3 style={{color:"red"}}>{error}</h3>}
|
||||||
|
<hr/>
|
||||||
|
<UserAuth username={p.username} isLoggedIn={p.username!==undefined}/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1811,11 +1878,6 @@ function UserSettings(p) {
|
|||||||
function UserAuth(p) {
|
function UserAuth(p) {
|
||||||
const[showAuthCode,setShowAuthCode] = useState(false)
|
const[showAuthCode,setShowAuthCode] = useState(false)
|
||||||
const[authToken,setAuthToken] = useState("")
|
const[authToken,setAuthToken] = useState("")
|
||||||
let history = useHistory();
|
|
||||||
|
|
||||||
if (!p.isLoggedIn) {
|
|
||||||
history.push("/")
|
|
||||||
}
|
|
||||||
|
|
||||||
return(<>
|
return(<>
|
||||||
Your <b>App Authentication Code</b> is used for verifying your identity when using apps such as <b>DivaBot</b>. By clicking the <b>{"<Reveal Code>"}</b> button, you understand that you should not share this code or show it to anyone!
|
Your <b>App Authentication Code</b> is used for verifying your identity when using apps such as <b>DivaBot</b>. By clicking the <b>{"<Reveal Code>"}</b> button, you understand that you should not share this code or show it to anyone!
|
||||||
@ -1908,12 +1970,113 @@ function DivaBot() {
|
|||||||
function StreamPanel(p) {
|
function StreamPanel(p) {
|
||||||
|
|
||||||
const [update,setUpdate] = useState(false);
|
const [update,setUpdate] = useState(false);
|
||||||
|
const [monitor,setMonitor] = useState("LOADING");
|
||||||
|
const [image,setImage] = useState(<></>);
|
||||||
|
|
||||||
|
let history = useHistory();
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
//process.env.REACT_APP_FRONTEND_AUTH
|
||||||
|
const interval = setInterval(()=>{
|
||||||
|
if (monitor==="LOADING"||monitor==="RUNNING") {
|
||||||
|
axios.post("/streaminfo/"+p.userSettings.id,{username:p.userSettings.username,authentication_token:localStorage.getItem("authToken")})
|
||||||
|
.then((data)=>{
|
||||||
|
if (data.data>=2) {
|
||||||
|
setMonitor("RUNNING")
|
||||||
|
setImage(<img style={{width:"100%"}} src={"http://projectdivar.com:8080/divar/cropped/cropped"+p.userSettings.id+".png?"+Date.now()}/>)
|
||||||
|
} else {
|
||||||
|
setMonitor("WAITING")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},5000)
|
||||||
|
|
||||||
|
return ()=>clearInterval(interval)
|
||||||
|
},[update,monitor])
|
||||||
|
|
||||||
|
if (!p.isLoggedIn) {
|
||||||
|
return (<Redirect to="/"/>)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (p.userSettings.twitch_name!==undefined&&p.userSettings.twitch_name!==null&&p.userSettings.twitch_name.length>0) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
This panel is used to monitor score submissions as you play and to monitor a <b>Playstation 4</b> stream of <b>Project Diva Future Tone</b>. Read the instructions below before using this tool for the first time to properly set it up.
|
||||||
|
<Card className="mt-4" body>
|
||||||
|
<h3>Stream Monitor:
|
||||||
|
{monitor==="RUNNING"?<b style={{color:"green"}}>Online</b>:
|
||||||
|
monitor==="LOADING"?<b>Pending</b>:
|
||||||
|
<b style={{color:"red"}}>Offline</b>}</h3>
|
||||||
|
{monitor==="WAITING"?<Button onClick={()=>{
|
||||||
|
setMonitor("LOADING")
|
||||||
|
axios.post("http://projectdivar.com/streamstart/"+p.userSettings.id,{username:p.userSettings.username,authentication_token:localStorage.getItem("authToken")})
|
||||||
|
}}>Start Stream Monitor</Button>
|
||||||
|
:monitor==="LOADING"?<Button disabled><Spinner animation="border" size="sm"/> Checking Status...</Button>
|
||||||
|
:
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-2">
|
||||||
|
<Button variant="info" onClick={()=>{
|
||||||
|
setMonitor("LOADING")
|
||||||
|
axios.post("http://projectdivar.com/streamkill/"+p.userSettings.id,{username:p.userSettings.username,authentication_token:localStorage.getItem("authToken")})
|
||||||
|
}}>Stop Stream Monitor</Button>
|
||||||
|
</div>
|
||||||
|
<div className="col-4">
|
||||||
|
{image}
|
||||||
|
</div>
|
||||||
|
<div className="col-6">
|
||||||
|
<RecentPlays username={p.userSettings.username} songs={p.songs}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</Card>
|
||||||
|
<h4 className="pt-4">Prerequisite</h4>
|
||||||
|
If you haven't done so already, <a href="https://www.playstation.com/en-gb/get-help/help-library/apps---features/playstation-apps---features/how-to-broadcast-using-youtube/">setup your PS4 for Twitch Streaming</a>.
|
||||||
|
<h2 className="pt-4">Step 1</h2>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-6">
|
||||||
|
While on the game's <b>Main Menu</b>, select the <b>SHARE</b> button on your PS4.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h2 className="pt-4">Step 2</h2>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-6">
|
||||||
|
Setup your broadcasting settings and make sure you select <b>720p - High (60fps)</b> for best results. (Selecting a lower resolution will likely not work)
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<img style={{height:"320px"}} src="http://projectdivar.com/files/ps4startstream.png"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h2 className="pt-4">Step 3</h2>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-6">
|
||||||
|
Once you are broadcasting on PS4, click the <b>Start Stream Monitor</b> button and let it calibrate your screen.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h2 className="pt-4">Step 4</h2>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-6">
|
||||||
|
If the calibration looks good, then start playing! Otherwise stop the stream monitor, make sure you are on the main menu, then try starting it again.
|
||||||
|
After each song, if you want the score to submit, make sure you are on the Result screen for a second. (You don't have to wait for it to pop up on the scores list unless you really want to make sure)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
<h2 className="pt-4">Video</h2>
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12">
|
||||||
|
Alternatively, I explain how to use this feature in the below video:
|
||||||
|
{<iframe width="100%" height="480" src="https://www.youtube.com/embed/GhS8koB3N6s" frameBorder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowFullScreen></iframe>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
You will need to go to your <Link to="/usersettings">Profile Settings</Link> and update your Twitch username before using this feature.
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function StreamData() {
|
function StreamData() {
|
||||||
@ -1961,13 +2124,14 @@ function Website() {
|
|||||||
<h3 className="d-none d-md-block">Menu</h3>
|
<h3 className="d-none d-md-block">Menu</h3>
|
||||||
<LoginInfo setUserSettings={setUserSettings} setUsername={setUsername} update={loginPanelUpdate}/>
|
<LoginInfo setUserSettings={setUserSettings} setUsername={setUsername} update={loginPanelUpdate}/>
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
<Link to="/rankings/rating/desc">Rankings</Link><br/>
|
<Link to="/rankings/rating/desc#content">Rankings</Link><br/>
|
||||||
<Link to="/submitplay">Submit Scores</Link><br/>
|
<Link to="/submitplay#content">Submit Scores</Link><br/>
|
||||||
<Link to="/divabot">DivaBot</Link><br/>
|
<Link to="/divabot#content">DivaBot</Link><br/>
|
||||||
<hr/>
|
<hr/>
|
||||||
<a href="http://discord.gg/eJ3cMzM"><img src="http://projectdivar.com/files/discord_button_small.png"/></a>
|
<a href="http://discord.gg/eJ3cMzM"><img src="http://projectdivar.com/files/discord_button_small.png"/></a>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-10 pt-3 pb-3">
|
<div className="col-md-10 pt-3 pb-3">
|
||||||
|
<div id="content"/>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/rankings/:sort/:sortOrder">
|
<Route path="/rankings/:sort/:sortOrder">
|
||||||
<Rankings/>
|
<Rankings/>
|
||||||
@ -1989,14 +2153,6 @@ function Website() {
|
|||||||
<h1 className="title">DivaBot</h1>
|
<h1 className="title">DivaBot</h1>
|
||||||
<DivaBot/>
|
<DivaBot/>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/auth">
|
|
||||||
<h1 className="title">App Authentication Token</h1>
|
|
||||||
<UserAuth username={username} isLoggedIn={username!==undefined}/>
|
|
||||||
</Route>
|
|
||||||
<Route path="/recentplays">
|
|
||||||
<h1 className="title">Project DivaR</h1>
|
|
||||||
<RecentPlays songs={songs}/>
|
|
||||||
</Route>
|
|
||||||
<Route path="/login">
|
<Route path="/login">
|
||||||
<h1 className="title">Login to Project DivaR</h1>
|
<h1 className="title">Login to Project DivaR</h1>
|
||||||
<Login isLoggedIn={username!==undefined} setLoginPanelUpdate={setLoginPanelUpdate}/>
|
<Login isLoggedIn={username!==undefined} setLoginPanelUpdate={setLoginPanelUpdate}/>
|
||||||
@ -2007,7 +2163,7 @@ function Website() {
|
|||||||
</Route>
|
</Route>
|
||||||
<Route path="/streampanel">
|
<Route path="/streampanel">
|
||||||
<h1 className="title">Stream Panel</h1>
|
<h1 className="title">Stream Panel</h1>
|
||||||
<StreamPanel setUserSettings={setUserSettings} userSettings={userSettings} isLoggedIn={username!==undefined} setLoginPanelUpdate={setLoginPanelUpdate}/>
|
<StreamPanel songs={songs} setUserSettings={setUserSettings} userSettings={userSettings} isLoggedIn={username!==undefined} setLoginPanelUpdate={setLoginPanelUpdate}/>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/stream">
|
<Route path="/stream">
|
||||||
<h1 className="title">Stream</h1>
|
<h1 className="title">Stream</h1>
|
||||||
@ -2015,7 +2171,132 @@ function Website() {
|
|||||||
</Route>
|
</Route>
|
||||||
<Route path="/">
|
<Route path="/">
|
||||||
<h1 className="title">Project DivaR</h1>
|
<h1 className="title">Project DivaR</h1>
|
||||||
Under construction!
|
Welcome! This website is here to store and track all your Project Diva records for yours and others' enjoyment!
|
||||||
|
<div className="pt-4 d-flex justify-content-center">
|
||||||
|
<Carousel
|
||||||
|
className="d-block w-75">
|
||||||
|
<Carousel.Item>
|
||||||
|
<img
|
||||||
|
className="d-block w-100"
|
||||||
|
src="http://projectdivar.com/files/slide1.png"
|
||||||
|
alt="First slide"
|
||||||
|
/>
|
||||||
|
<Carousel.Caption>
|
||||||
|
<h1 className="superglow">Project Diva Records</h1>
|
||||||
|
<p className="superglow">A home for all your best plays.</p>
|
||||||
|
</Carousel.Caption>
|
||||||
|
</Carousel.Item>
|
||||||
|
<Carousel.Item>
|
||||||
|
<img
|
||||||
|
className="d-block w-100"
|
||||||
|
src="http://projectdivar.com/files/slide2.png"
|
||||||
|
alt="Third slide"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Carousel.Caption>
|
||||||
|
<h1 className="superglow">Statistics</h1>
|
||||||
|
<p className="superglow">Keep track of your all-time stats.</p>
|
||||||
|
</Carousel.Caption>
|
||||||
|
</Carousel.Item>
|
||||||
|
<Carousel.Item>
|
||||||
|
<img
|
||||||
|
className="d-block w-100"
|
||||||
|
src="http://projectdivar.com/files/slide3.png"
|
||||||
|
alt="Third slide"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Carousel.Caption>
|
||||||
|
<h1 className="superglow">Progression Tracking</h1>
|
||||||
|
<p className="superglow">Watch as you improve and become greater over time.</p>
|
||||||
|
</Carousel.Caption>
|
||||||
|
</Carousel.Item>
|
||||||
|
<Carousel.Item>
|
||||||
|
<img
|
||||||
|
className="d-block w-100"
|
||||||
|
src="http://projectdivar.com/files/slide4.png"
|
||||||
|
alt="Third slide"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Carousel.Caption>
|
||||||
|
<h1 className="superglow">Many Ways to Submit</h1>
|
||||||
|
<p className="superglow">Submit your scores by screenshots, Twitter, DivaBot, or streaming.</p>
|
||||||
|
</Carousel.Caption>
|
||||||
|
</Carousel.Item>
|
||||||
|
</Carousel>
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
<h3>Support</h3>
|
||||||
|
<Card className="mt-4" body>
|
||||||
|
<div className="border rounded p-2 mt-4" style={{backgroundColor:"#eeeeee"}} >
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12">
|
||||||
|
<img className="mr-2 rounded" style={{float:"left"}} src="http://projectdivar.com/files/mega39s.png"/>
|
||||||
|
<h5>Project Diva Megamix</h5>
|
||||||
|
<div className="row rounded">
|
||||||
|
<div className="col-md-3">
|
||||||
|
<b>Image Submission: </b> <IMAGE_CHECKMARK style={{color:"darkgreen"}}/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3">
|
||||||
|
<b>Twitter: </b> <IMAGE_CHECKMARK style={{color:"darkgreen"}}/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3">
|
||||||
|
<b>DivaBot: </b> <IMAGE_CHECKMARK style={{color:"darkgreen"}}/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3">
|
||||||
|
<b>Manual: </b> <IMAGE_X style={{color:"maroon"}}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="border rounded p-2 mt-4" style={{backgroundColor:"#eeeeee"}} >
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12">
|
||||||
|
<img className="mr-2 rounded" style={{float:"left"}} src="http://projectdivar.com/files/mixmode.png"/>
|
||||||
|
<h5>Project Diva Megamix Mix Mode</h5>
|
||||||
|
<div className="row rounded">
|
||||||
|
<div className="col-md-3">
|
||||||
|
<b>Image Submission: </b> <IMAGE_X style={{color:"maroon"}}/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3">
|
||||||
|
<b>Twitter: </b> <IMAGE_X style={{color:"maroon"}}/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3">
|
||||||
|
<b>DivaBot: </b> <IMAGE_X style={{color:"maroon"}}/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3">
|
||||||
|
<b>Manual: </b> <IMAGE_X style={{color:"maroon"}}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="border rounded p-2 mt-4" style={{backgroundColor:"#eeeeee"}} >
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-12">
|
||||||
|
<img className="mr-2 rounded" style={{float:"left"}} src="http://projectdivar.com/files/futuretone.png"/>
|
||||||
|
<h5>Project Diva Future Tone</h5>
|
||||||
|
<div className="row rounded">
|
||||||
|
<div className="col-md-3">
|
||||||
|
<b>Image Submission: </b> <IMAGE_CHECKMARK style={{color:"darkgreen"}}/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3">
|
||||||
|
<b>Twitter: </b> <IMAGE_CHECKMARK style={{color:"darkgreen"}}/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3">
|
||||||
|
<b>DivaBot: </b> <IMAGE_CHECKMARK style={{color:"darkgreen"}}/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3">
|
||||||
|
<b>Stream Monitor: </b> <IMAGE_CHECKMARK style={{color:"darkgreen"}}/>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-3">
|
||||||
|
<b>Manual: </b> <IMAGE_X style={{color:"maroon"}}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
</Route>
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,41 @@
|
|||||||
const { createProxyMiddleware } = require('http-proxy-middleware');
|
const { createProxyMiddleware } = require('http-proxy-middleware');
|
||||||
|
|
||||||
module.exports = function(app) {
|
module.exports = function(app) {
|
||||||
|
app.use(
|
||||||
|
"/recalculatePlayerData/:id",
|
||||||
|
createProxyMiddleware({
|
||||||
|
target: 'http://server:4501',
|
||||||
|
changeOrigin: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
app.use(
|
||||||
|
"/streamtop/:id",
|
||||||
|
createProxyMiddleware({
|
||||||
|
target: 'http://server:4501',
|
||||||
|
changeOrigin: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
app.use(
|
||||||
|
"/streamkill/:id",
|
||||||
|
createProxyMiddleware({
|
||||||
|
target: 'http://server:4501',
|
||||||
|
changeOrigin: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
app.use(
|
||||||
|
"/streamstart/:id",
|
||||||
|
createProxyMiddleware({
|
||||||
|
target: 'http://server:4501',
|
||||||
|
changeOrigin: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
app.use(
|
||||||
|
"/streaminfo/:id",
|
||||||
|
createProxyMiddleware({
|
||||||
|
target: 'http://server:4501',
|
||||||
|
changeOrigin: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
app.use(
|
app.use(
|
||||||
"/updates/:userid",
|
"/updates/:userid",
|
||||||
createProxyMiddleware({
|
createProxyMiddleware({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user