diff --git a/bemani/frontend/app.py b/bemani/frontend/app.py index 518707d..10eff99 100644 --- a/bemani/frontend/app.py +++ b/bemani/frontend/app.py @@ -426,6 +426,10 @@ def navigation() -> Dict[str, Any]: "label": "Personal Profile", "uri": url_for("danevo_pages.viewplayer", userid=g.userID), }, + { + "label": "Dance Mates", + "uri": url_for("danevo_pages.viewdancemates", userid=g.userID), + }, { "label": "Personal Records", "uri": url_for("danevo_pages.viewrecords", userid=g.userID), diff --git a/bemani/frontend/danevo/danevo.py b/bemani/frontend/danevo/danevo.py index 24ebf5e..9fcc6df 100644 --- a/bemani/frontend/danevo/danevo.py +++ b/bemani/frontend/danevo/danevo.py @@ -3,7 +3,7 @@ from typing import Any, Dict, Iterator, List, Tuple from bemani.backend.danevo import DanceEvolutionFactory, DanceEvolutionBase from bemani.common import Profile, ValidatedDict, GameConstants -from bemani.data import Attempt, Score, Song, UserID +from bemani.data import Attempt, Link, Score, Song, UserID from bemani.frontend.base import FrontendBase @@ -20,7 +20,7 @@ class DanceEvolutionFrontend(FrontendBase): DanceEvolutionBase.CHART_TYPE_PLAYTRACKING, ] - valid_rival_types: List[str] = [] + valid_rival_types: List[str] = ["dancemate"] def all_games(self) -> Iterator[Tuple[GameConstants, int, str]]: yield from DanceEvolutionFactory.all_games() @@ -87,3 +87,9 @@ class DanceEvolutionFrontend(FrontendBase): if existing["levels"][new.chart] == 0: new_song["levels"][new.chart] = new.data.get_int("level") return new_song + + def format_rival(self, link: Link, profile: Profile) -> Dict[str, Any]: + return { + "userid": str(link.other_userid), + "last_played": link.data.get_int("last_played"), + } diff --git a/bemani/frontend/danevo/endpoints.py b/bemani/frontend/danevo/endpoints.py index 2d17f80..bc7d228 100644 --- a/bemani/frontend/danevo/endpoints.py +++ b/bemani/frontend/danevo/endpoints.py @@ -282,3 +282,55 @@ def updatename() -> Dict[str, Any]: "version": version, "name": name, } + + +@danevo_pages.route("/dancemates/") +@loginrequired +def viewdancemates(userid: UserID) -> Response: + frontend = DanceEvolutionFrontend(g.data, g.config, g.cache) + info = frontend.get_latest_player_info([userid]).get(userid) + if info is None: + abort(404) + + # Since we have one version of DanEvo this is an ugly hack. + dancemates_by_version, profiles = frontend.get_rivals(userid) + dancemates = [] + for version, actual_dancemates in dancemates_by_version.items(): + dancemates.extend(actual_dancemates) + + return render_react( + f'{info["name"]}\'s Dance Evolution Dance Mates', + "danevo/dancemates.react.js", + { + "name": info["name"], + "version": version, + "dancemates": dancemates, + "profiles": profiles, + }, + { + "refresh": url_for("danevo_pages.listdancemates", userid=userid), + }, + ) + + +@danevo_pages.route("/dancemates//list") +@jsonify +@loginrequired +def listdancemates(userid: UserID) -> Dict[str, Any]: + frontend = DanceEvolutionFrontend(g.data, g.config, g.cache) + info = frontend.get_latest_player_info([userid]).get(userid) + if info is None: + abort(404) + + # Since we have one version of DanEvo this is an ugly hack. + dancemates_by_version, profiles = frontend.get_rivals(userid) + dancemates = [] + for version, actual_dancemates in dancemates_by_version.items(): + dancemates.extend(actual_dancemates) + + return { + "name": info["name"], + "version": version, + "dancemates": dancemates, + "profiles": profiles, + } diff --git a/bemani/frontend/static/components/timestamp.react.js b/bemani/frontend/static/components/timestamp.react.js index d416c32..7e56047 100644 --- a/bemani/frontend/static/components/timestamp.react.js +++ b/bemani/frontend/static/components/timestamp.react.js @@ -9,7 +9,7 @@ var Timestamp = createReactClass({ var t = new Date(this.props.timestamp * 1000); var formatted = t.format('Y/m/d @ g:i:s a'); return ( -
{ formatted }
+
{ formatted }
); }, }); diff --git a/bemani/frontend/static/controllers/danevo/dancemates.react.js b/bemani/frontend/static/controllers/danevo/dancemates.react.js new file mode 100644 index 0000000..b760813 --- /dev/null +++ b/bemani/frontend/static/controllers/danevo/dancemates.react.js @@ -0,0 +1,83 @@ +/*** @jsx React.DOM */ + +var dancemates_view = createReactClass({ + + getInitialState: function(props) { + return { + name: window.name, + version: window.version, + dancemates: window.dancemates, + profiles: window.profiles, + }; + }, + + componentDidMount: function() { + this.refreshDanceMates(); + }, + + refreshDanceMates: function() { + AJAX.get( + Link.get('refresh'), + function(response) { + this.setState({ + name: response.name, + version: response.version, + dancemates: response.dancemates, + profiles: response.profiles, + }); + setTimeout(this.refreshDanceMates, 5000); + }.bind(this) + ); + }, + + renderDanceMates: function(player) { + return( + ; + }, + sort: function(aid, bid) { + return aid.last_played - bid.last_played; + }.bind(this), + }, + ]} + defaultsort='Name' + rows={this.state.dancemates} + paginate={10} + /> + ); + }, + + render: function() { + return ( +
+
+

{this.state.name}'s Dance Mates

+

+ {this.renderDanceMates()} +

+
+
+ ); + }, +}); + +ReactDOM.render( + React.createElement(dancemates_view, null), + document.getElementById('content') +); diff --git a/bemani/frontend/static/controllers/danevo/player.react.js b/bemani/frontend/static/controllers/danevo/player.react.js index 53dd6b9..b3603ff 100644 --- a/bemani/frontend/static/controllers/danevo/player.react.js +++ b/bemani/frontend/static/controllers/danevo/player.react.js @@ -43,19 +43,6 @@ var profile_view = createReactClass({

{player.name}'s profile

- {this.state.profiles.map(function(version) { - return ( -
{player.extid} diff --git a/bemani/frontend/static/controllers/danevo/settings.react.js b/bemani/frontend/static/controllers/danevo/settings.react.js index 60d8753..4560a10 100644 --- a/bemani/frontend/static/controllers/danevo/settings.react.js +++ b/bemani/frontend/static/controllers/danevo/settings.react.js @@ -135,25 +135,6 @@ var settings_view = createReactClass({ var player = this.state.player[this.state.version]; return (
-
- {this.state.profiles.map(function(version) { - return ( -

User Profile

{this.renderName(player)}