replace zxq.co/ripple/hanayo
This commit is contained in:
39
templates/2fa_gateway.html
Normal file
39
templates/2fa_gateway.html
Normal file
@@ -0,0 +1,39 @@
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
{{ if .Session.Get "2fa_must_validate" }}
|
||||
{{ $e := is2faEnabled .Context.User.ID }}
|
||||
<div class="tiny container">
|
||||
<div class="ui raised segments">
|
||||
<div class="ui segment">
|
||||
{{ .T "Hey, %s." .Context.User.Username }}
|
||||
{{ if eq $e 1 }}
|
||||
{{ .T "Before proceding any further on Ripple, we require you to use the message you just received on telegram to log in to your account." }}
|
||||
{{ else }}
|
||||
{{ .T "Before proceding further on Ripple, we require you to use your Google Authenticator App to use the code for Ripple, so that we can log you in." }}
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<div class="ui form">
|
||||
<div class="field">
|
||||
<label>{{ if eq $e 1 }}{{ .T "Telegram code" }} <a href="/2fa_gateway/clear">{{ .T "(send again?)" }}</a>{{ else }}Google Authenticator passcode{{ end }}</label>
|
||||
<input tabindex="1" type="text" placeholder="{{ if eq $e 1 }}AWYXZ13Y{{ else }}612 511{{ end }}" id="telegram-code">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ if eq $e 2 }}
|
||||
<div class="ui segment">
|
||||
<b>{{ .T "Lost your phone, or can't access Google Authenticator?" }}</b> <a href="/2fa_gateway/recover">{{ .T "Click here to use a recovery code." }}</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var redir = {{ .RequestInfo.redir }};
|
||||
</script>
|
||||
{{ else }}
|
||||
<div class="ui segment">
|
||||
<code style="word-break: break-all">LVstLS0tLS0tPis8XT4tLlstLS0+KysrKzxdPisuK1stLS0+KzxdPi4rWy0+KysrPF0+Li0tWy0tLT4rPF0+LS5bLT4rKys8XT4rLisrKysrKysrKysrKysuLVstPisrKysrPF0+LS5bLT4rKzxdPisuPi1bLS0tPis8XT4tLS4tLVstPisrKys8XT4tLisrKysrKy4uLVstPisrKys8XT4uK1stPisrKzxdPisuKysrKysuLS0tLS0tLisrKysrKysrLi0tWy0+KysrPF0+LS4+KysrKysrKysrKy4rWy0+KysrKys8XT4rLisrKysrLi4uLi4uKysrKysrKy4=</code>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
22
templates/2fa_gateway_recover.html
Normal file
22
templates/2fa_gateway_recover.html
Normal file
@@ -0,0 +1,22 @@
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="tiny container">
|
||||
<div class="ui segments">
|
||||
<div class="ui segment">
|
||||
{{ .T "Can't find a way to get back access to your Ripple account? Fear not! If you have your recovery codes which we recommended you to print you can type one in here and we'll magically log you in this time. After you've managed to get in, please disable and then re-enable 2FA, so you won't risk losing your account again." }}
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<form method="POST" class="ui form">
|
||||
{{ ieForm .Gin }}
|
||||
<div class="ui fluid action input">
|
||||
<input tabindex="1" type="text" placeholder="1QW4RX5P" name="recovery_code" required>
|
||||
<button tabindex="2" class="ui green button">
|
||||
{{ .T "Recover account" }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
7
templates/500.html
Normal file
7
templates/500.html
Normal file
@@ -0,0 +1,7 @@
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui segment">
|
||||
{{ .T "Ooops! Looks like something went really wrong while trying to process your request. Perhaps report this to a Ripple developer? Retrying doing what you were trying to do might work, too." }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
86
templates/about.html
Normal file
86
templates/about.html
Normal file
@@ -0,0 +1,86 @@
|
||||
{{/*###
|
||||
Handler=/about
|
||||
TitleBar=About
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui centered segments">
|
||||
<div class="ui segment">
|
||||
<img src="/static/logos/logo-pink.svg">
|
||||
<h1 class="ui no bottom margin header">
|
||||
{{ .T "Welcome to Ripple." }}
|
||||
</h1>
|
||||
<div class="about subtitle">{{ .T "Ripple is a private osu! server." }}<br>
|
||||
{{ .T "There are many like it, but this one is ours." }}</div>
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<img src="/static/about/intro.jpg">
|
||||
<div class="about title twemoji">{{ .T "Don't you like %s?" "🍆" }}</div>
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header">
|
||||
{{ .T "We have leaderboards." }}
|
||||
</h1>
|
||||
<img src="/static/about/leaderboards.jpg">
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header">
|
||||
{{ .T "Online user listing." }}
|
||||
</h1>
|
||||
<img src="/static/about/onlineusers.jpg">
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header">
|
||||
{{ .T "Free osu!direct." }}
|
||||
</h1>
|
||||
<img src="/static/about/osudirect.jpg">
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<h1 class="ui no bottom margin header">
|
||||
{{ .T "Global leaderboards." }}
|
||||
</h1>
|
||||
<p class="about subtitle">{{ .T "and PP for all game modes" }}</p>
|
||||
<img src="/static/about/global_leaderboards.jpg">
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header">
|
||||
{{ .T "Ranking queue for unranked beatmaps." }}
|
||||
</h1>
|
||||
<img src="/static/about/request_beatmaps.jpg">
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header">
|
||||
{{ .T "Spectator." }}
|
||||
</h1>
|
||||
<img src="/static/about/spectator.jpg">
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header">
|
||||
{{ .T "Multiplayer." }}
|
||||
</h1>
|
||||
<img src="/static/about/multi.jpg">
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header">
|
||||
{{ .T "FokaBot, our chat bot" }}
|
||||
</h1>
|
||||
<p class="about subtitle">{{ .T "with plenty of functions for just about anything, <a href=\"/doc/4\">check it out!</a>" | html }}</p>
|
||||
<img src="/static/about/foka.jpg">
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header">
|
||||
{{ .T "And a lot more to come!" }}
|
||||
</h1>
|
||||
<p class="about title">
|
||||
{{ .T "Ripple is the result of the hard work of two Italian developers, who got tired about the whole osu! ecosystem, and also because they wanted to play with a few banned friends." }}
|
||||
</p>
|
||||
<p class="about title twemoji">
|
||||
{{ .T "It has now evolved into the largest available osu! private server, with more than 50,000 registered users. <a href=\"/register\">Signing up</a> on Ripple won't result in getting your account on osu! restricted, so what are you waiting for?! Come join us! %s" "😉" | html }}
|
||||
</p>
|
||||
<p class="about subtitle">
|
||||
{{ .T "In case you want to make sure we're not doing shady stuff with your data, you can also check the <a href=\"https://zxq.co/ripple/ripple\">source code</a> Ripple is running on." | html }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
138
templates/base.html
Normal file
138
templates/base.html
Normal file
@@ -0,0 +1,138 @@
|
||||
{{ define "base" }}
|
||||
{{ $cf := .ClientFlags }}
|
||||
{{ $ds := band $cf 1 }}
|
||||
{{ $ := . }}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>{{ if .TitleBar }}{{ .T .TitleBar }} - {{ end }}Ripple</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/static/{{ if $ds }}dark/{{ end }}semantic.min.css?{{ unixNano }}">
|
||||
<link rel="stylesheet" type="text/css" href="/static/ripple.css?{{ unixNano }}">
|
||||
<link rel="stylesheet" type="text/css" href="/static/snow/snow.css?{{ unixNano }}">
|
||||
</head>
|
||||
<body {{ if $ds }} class="ds"{{ end }}>
|
||||
{{/*
|
||||
If we're asked to disable the hugeheading, but a KyutGrill is set, it will become the background of the page.
|
||||
This is mainly used in user profiles, allowing users to set their profile background.
|
||||
If we're asked to disable the hugeheading, and a KyutGrill is not set, navbar has the `dropped` class.
|
||||
*/}}
|
||||
<div class="ui full height main wrapper"
|
||||
{{ if and .DisableHH .KyutGrill }}
|
||||
style="background-image: url('{{ if .KyutGrillAbsolute }}{{ .KyutGrill }}{{ else }}/static/headers/{{ .KyutGrill }}{{ end }}');"
|
||||
{{ else if .SolidColour }}
|
||||
style="background-color: {{ .SolidColour }}"
|
||||
{{ end }}>
|
||||
{{ template "navbar" . }}
|
||||
{{ if not .DisableHH }}
|
||||
<div class="huge heading {{ if .HeadingOnRight }}right{{ end }} dropped"
|
||||
style="background-image: url('{{ if .KyutGrillAbsolute }}{{ .KyutGrill }}{{ else }}/static/headers/{{ or .KyutGrill "default.jpg" }}{{ end }}');">
|
||||
<div id="snow-container">
|
||||
<div>
|
||||
<div class="snow large"></div>
|
||||
<div class="snow large delayed"></div>
|
||||
|
||||
<div class="snow medium"></div>
|
||||
<div class="snow medium delayed"></div>
|
||||
|
||||
<div class="snow small"></div>
|
||||
<div class="snow small delayed"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui container">
|
||||
<h1>{{ if .HeadingTitle }}{{ .T .HeadingTitle | html }}{{ else }}{{ .T .TitleBar }}{{ end }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
<div class="h-container">
|
||||
<div class="ui margined container" id="messages-container">
|
||||
<noscript>Research has proven this website works 10000% better if you have JavaScript enabled.</noscript>
|
||||
{{ if and .Context.User.Username (not (has .Context.User.Privileges 1)) }}
|
||||
<div class="ui warning message">
|
||||
{{ $.T "Your account is currently in restricted mode. You will not be able to do certain actions, and your profile can only be seen by you and by Ripple's staff. If you believe we have mistaken putting you in restricted mode, or a month has passed since you first saw this, then you can send an appeal at <a href='https://support.ripple.moe'>support.ripple.moe</a>." | html }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ if .Messages }}
|
||||
{{ range $i, $v := .Messages }}
|
||||
<div class="ui {{ $v.Type }} message">
|
||||
<i class="close icon"></i>
|
||||
{{ html $v.Content }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ $settings := systemSettings "website_maintenance" "game_maintenance" "website_global_alert" }}
|
||||
{{ with $settings.website_global_alert.String }}
|
||||
<div class="ui warning message">
|
||||
{{ . | html }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ with $settings.game_maintenance.Int }}
|
||||
<div class="ui warning message">
|
||||
{{ $.T "Ripple's score submission is currently in maintenance mode. You will not be allowed to submit scores for the time being." }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ with $settings.website_maintenance.Int }}
|
||||
<div class="ui warning message">
|
||||
{{ $.T "The Ripple website is currently in maintenance mode. Only certain users are allowed to access the full website." }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ template "tpl" . }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
{{ .T "© 2015-%d Ripple, using Hanayo %s." (curryear) (version) | html }}
|
||||
<a href="/team" title="{{ .T "Who is working on this thing?" }}"><i class="users icon"></i>{{ .T "Team" }}</a> |
|
||||
<a href="https://docs.ripple.moe" title="59 6f 75 27 72 65 20 73 6f 20 31 33 33 37 2e"><i class="wrench icon"></i>{{ .T "Developer docs" }}</a> |
|
||||
<a href="/changelog" title="{{ .T "See what changed!" }}"><i class="bug icon"></i>{{ .T "Changelog" }}</a> |
|
||||
<a href="https://blog.ripple.moe"><i class="anchor icon"></i>{{ .T "Blog" }}</a> |
|
||||
<a href="http://status.ripple.moe"><i class="signal icon"></i>{{ .T "Status" }}</a> |
|
||||
<a href="https://zxq.co/ripple" title="{{ .T "What's going on under the hood?"}}{{/*'"*/}}"><i class="git square icon"></i></a>
|
||||
<a href="https://twitter.com/_ripple" title="{{ .T "Follow us on Twitter!" }}"><i class="twitter icon"></i></a>
|
||||
<a href="https://reddit.com/r/osuripple" title="{{ .T "Share irrelevant opinions on reddit!" }}"><i class="reddit square icon"></i></a> |
|
||||
<div class="ui scrolling dropdown" style="margin-left: 5px;" id="language-selector">
|
||||
{{ $lang := .Context.Language }}
|
||||
{{ with $lang }}
|
||||
{{ $info := languageInformationByNameShort . }}
|
||||
<div class="text"><i class="{{ $info.CountryShort }} flag"></i>{{ $info.Name }}</div>
|
||||
{{ else }}
|
||||
<div class="default text">{{ .T "Language" }}</div>
|
||||
{{ end }}
|
||||
<i class="dropdown icon"></i>
|
||||
<div class="menu">
|
||||
{{ range languageInformation }}
|
||||
<div class="{{ if eq .NameShort $lang }}selected {{ end }}item" data-lang="{{ .NameShort }}"><i class="{{ .CountryShort }} flag"></i>{{ .Name }}</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var hanayoConf = {
|
||||
avatars: {{ .Conf.AvatarURL }},
|
||||
banchoAPI: {{ .Conf.BanchoAPI }},
|
||||
baseAPI: {{ .Conf.BaseAPIPublic }},
|
||||
cheesegullAPI: {{ .Conf.CheesegullAPI }},
|
||||
language: {{ with $lang }}{{ . }}{{ else }}"en"{{ end }},
|
||||
};
|
||||
var currentUserID = {{ .Context.User.ID }};
|
||||
</script>
|
||||
{{/* If we got some more scripts to print, print'em */}}
|
||||
<script src="//twemoji.maxcdn.com/2/twemoji.min.js?2.2"></script>
|
||||
<script src="/static/dist.min.js?{{ unixNano }}"></script>
|
||||
{{ with $lang }}
|
||||
<script src="/static/timeago-locale/jquery.timeago.{{ . }}.js"></script>
|
||||
{{ end }}
|
||||
{{ if .Scripts }}
|
||||
{{ range .Scripts }}
|
||||
<script src="{{ . }}?{{ unixNano }}"></script>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</body>
|
||||
</html>
|
||||
{{ end }}
|
98
templates/beatmap.html
Normal file
98
templates/beatmap.html
Normal file
@@ -0,0 +1,98 @@
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
{{ $ := . }}
|
||||
{{ if ne .Beatmapset.ID 0 }}
|
||||
<div class="ui floating icon labeled dropdown button" id="diff-menu">
|
||||
<i class="caret down icon"></i>
|
||||
<span class="text">
|
||||
<i class="attention icon"></i>
|
||||
{{ .Beatmap.DiffName }}
|
||||
(<i class="fitted star icon" style="margin-right:0"></i> {{ printf "%.2f" .Beatmap.DifficultyRating }})
|
||||
</span>
|
||||
<div class="menu">
|
||||
{{ range .Beatmapset.ChildrenBeatmaps }}
|
||||
<a href="/b/{{ .ID }}" class="item {{ if eq .ID $.Beatmap.ID }}active{{ end }}" data-bid="{{ .ID }}">
|
||||
<i class="attention icon"></i>
|
||||
{{ .DiffName }}
|
||||
(<i class="fitted star icon" style="margin-right:0"></i> {{ printf "%.2f" .DifficultyRating }})
|
||||
</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui segments">
|
||||
<div class="ui segment">
|
||||
<div class="ui four column divided stackable grid">
|
||||
<div class="row">
|
||||
<div class="column">
|
||||
<b>{{ $.T "Artist" }}:</b> {{ .Beatmapset.Artist }}<br />
|
||||
<b>{{ $.T "Title" }}:</b> {{ .Beatmapset.Title }}<br />
|
||||
<b>{{ $.T "Creator" }}:</b> {{ .Beatmapset.Creator }}<br />
|
||||
<b>{{ $.T "Source" }}:</b> {{ .Beatmapset.Source }}<br />
|
||||
</div>
|
||||
<div class="column">
|
||||
<b>{{ $.T "Circle Size" }}:</b> <span id="cs"></span><br />
|
||||
<b>{{ $.T "HP Drain" }}:</b> <span id="hp"></span><br />
|
||||
<b>{{ $.T "Overall Difficulty" }}:</b> <span id="od"></span><br />
|
||||
<b>{{ $.T "Passes/Plays" }}:</b> <span id="passcount"></span> / <span id="playcount"></span>
|
||||
</div>
|
||||
<div class="column">
|
||||
<b>{{ $.T "Approach Rate" }}:</b> <span id="ar"></span><br />
|
||||
<b>{{ $.T "Star Difficulty" }}:</b> <span id="stars"></span><br />
|
||||
<b>{{ $.T "Length" }}:</b> <span id="length"></span> (<span id="drainLength"></span> drain)<br />
|
||||
<b>{{ $.T "BPM" }}:</b> <span id="bpm"></span><br />
|
||||
</div>
|
||||
<div class="full-centered column">
|
||||
<div class="ui vertical buttons">
|
||||
<a href="osu://dl/{{ .Beatmapset.ID }}" class="ui pink labeled icon button"><i class="download icon"></i>{{ $.T "osu!direct" }}</a>
|
||||
<a href="http://storage.ripple.moe/d/{{ .Beatmapset.ID }}" class="ui green labeled icon button"><i class="download icon"></i>{{ $.T "download" }}</a>
|
||||
{{ if .Beatmapset.HasVideo }}
|
||||
<a href="http://storage.ripple.moe/d/{{ .Beatmapset.ID }}?novideo" class="ui gray labeled icon button"><i class="download icon"></i>{{ $.T "download (no video)" }}</a>
|
||||
{{ end }}
|
||||
{{ if has $.Context.User.Privileges 256 }}
|
||||
<a href="https://old.ripple.moe/index.php?p=124&bsid={{ .Beatmapset.ID }}" class="ui violet labeled icon button"><i class="thumbs up icon"></i>{{ $.T "Rank in RAP"}}</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
{{ $p := .Gin.Query "p" }}
|
||||
{{ $favModeRaw := .Get "users/self/favourite_mode" }}
|
||||
|
||||
var beatmapID = {{ .Beatmap.ID }};
|
||||
var setData = JSON.parse({{ .SetJSON }});
|
||||
var page = {{ $p | atoint | atLeastOne }};
|
||||
// defaults to 0
|
||||
var currentMode = {{ atoi (.Gin.Query "mode") }};
|
||||
var currentModeChanged = false;
|
||||
var favMode = parseInt({{ $favModeRaw.favourite_mode }}) || 0;
|
||||
</script>
|
||||
|
||||
<div class="ui four item menu" id="mode-menu">
|
||||
{{ range $k, $v := modes }}
|
||||
<a class="item" id="mode-{{ $k }}" data-mode="{{ $k }}" href="/b/{{ $.Beatmap.ID }}?mode={{ $k }}">{{ $v }}</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<table class="ui sortable fixed table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="one wide">{{ .T "Rank" }} </th>
|
||||
<th class="four wide">{{ .T "Player" }} </th>
|
||||
<th class="three wide">{{ .T "Score" }} </th>
|
||||
<th class="two wide">{{ .T "Mods" }} </th>
|
||||
<th class="two wide">{{ .T "Accuracy" }} </th>
|
||||
<th class="two wide">{{ .T "Combo" }} </th>
|
||||
<th class="two wide">{{ .T "PP" }} </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
51
templates/beatmaps/rank_request.html
Normal file
51
templates/beatmaps/rank_request.html
Normal file
@@ -0,0 +1,51 @@
|
||||
{{/*###
|
||||
Handler=/beatmaps/rank_request
|
||||
TitleBar=Request beatmap ranking
|
||||
KyutGrill=request_beatmap_ranking.jpg
|
||||
MinPrivileges=2
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
{{ $ := . }}
|
||||
<div class="ui container">
|
||||
<div class="ui raised segment center aligned">
|
||||
{{ $f := ieForm .Gin }}
|
||||
<h4>{{ .T "Want to play an unranked beatmap and get pp? You can submit beatmaps rank requests here!" }}</h4>
|
||||
{{ with .Get "beatmaps/rank_requests/status" }}
|
||||
<h4 class="ui horizontal divider header">
|
||||
<i class="wait icon"></i>
|
||||
{{ $.T "Queue status" }}
|
||||
</h4>
|
||||
<h2 style="display: inline; font-weight: normal;"><span id="queue-info">{{ .submitted }}/{{ .queue_size }}</span> <i{{ if not .submitted_by_user }} hidden{{ end }} id="by-you">(<span id="submitted-by-user">{{ .submitted_by_user }}</span>/<span id="max-per-user">{{ .max_per_user }}</span> {{ $.T "by you" }})</i></h2><br>
|
||||
<h3 style="display: inline; font-weight: normal;">{{ $.T "Requests submitted" }}</h3><br>
|
||||
<h4 style="display: inline; font-weight: normal;">{{ $.T "In the past 24 hours" }}</h4><br>
|
||||
{{ $perc := perc .submitted .queue_size }}
|
||||
<div class="ui container" style="width: 50%; margin-top: 8px; margin-bottom: 8px;">
|
||||
<div class="ui green progress" data-percent="{{ $perc }}" id="progressbar">
|
||||
<div class="bar">
|
||||
<div class="progress">{{ $perc }}%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="ui horizontal divider header">
|
||||
<i class="music icon"></i>
|
||||
{{ $.T "Request a beatmap" }}
|
||||
</h4>
|
||||
{{ if .can_submit }}
|
||||
<form class="ui form" id="b-form">
|
||||
<div class="ui fluid action input">
|
||||
<input tabindex="1" type="text" placeholder="https://osu.ppy.sh/s/xxxx" id="beatmap">
|
||||
{{ $f }}
|
||||
<button tabindex="2" class="ui right labeled icon green button">
|
||||
<i class="right arrow icon"></i>
|
||||
{{ $.T "Submit" }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{{ else }}
|
||||
<h3 class="ui header">{{ $.T "You cannot currently request beatmaps!" }}</h3>
|
||||
{{ with .next_expiration }}<p>{{ $.T "Please try again " }}<b>{{ timeAddDay . }}</b></p>{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
63
templates/changelog.html
Normal file
63
templates/changelog.html
Normal file
@@ -0,0 +1,63 @@
|
||||
{{/*###
|
||||
Handler=/changelog
|
||||
TitleBar=Changelog
|
||||
KyutGrill=changelog.jpg
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui segments">
|
||||
<div class="ui segment">
|
||||
<p>
|
||||
{{ .T "This is the changelog. Changes are published here as soon as they hit the production status (as in, live on the website)." }}
|
||||
</p>
|
||||
<p>
|
||||
{{ .T "For various reasons, some software of Ripple does not contribute to the changelog, to which this website is a part of. In case you want to see the changelog of Hanayo, you can do so by <a href=\"https://github.com/osuYozora/hanayo/commits/master\">clicking here</a>." | html }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<table class="ui fixed celled table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ .T "Author" }}</th>
|
||||
<th>{{ .T "Subject" }}</th>
|
||||
<th>{{ .T "Time" }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ $page := or (atoint (.Gin.Query "p")) 1 }}
|
||||
{{ $ch := loadChangelog $page }}
|
||||
{{ with $ch }}
|
||||
{{ range . }}
|
||||
<tr>
|
||||
<td><b>{{ .Username }}</b></td>
|
||||
<td title="Git commit hash: {{ .Hash }}">{{ .Subject }}</td>
|
||||
<td>{{ timeFromTime .UnixTimestamp }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</tbody>
|
||||
{{ $left := gt $page 1 }}
|
||||
{{ $right := eq (len $ch) 50 }}
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="3">
|
||||
<div class="ui right floated pagination menu">
|
||||
{{ if $left }}
|
||||
<a class="icon item" href="/changelog?p={{ minus (float $page) 1 }}">
|
||||
<i class="left chevron icon"></i>
|
||||
</a>
|
||||
{{ end }}
|
||||
{{ if $right }}
|
||||
<a class="icon item" href="/changelog?p={{ plus (float $page) 1 }}">
|
||||
<i class="right chevron icon"></i>
|
||||
</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
43
templates/dev/apps.html
Normal file
43
templates/dev/apps.html
Normal file
@@ -0,0 +1,43 @@
|
||||
{{/*###
|
||||
TitleBar=Your OAuth2 Applications
|
||||
KyutGrill=dev.jpg
|
||||
MinPrivileges=2
|
||||
Include=menu.html
|
||||
HugeHeadingRight=true
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
{{ $ := . }}
|
||||
<div class="ui container">
|
||||
<div class="ui stackable grid">
|
||||
{{ template "devSidebar" . }}
|
||||
<div class="twelve wide column">
|
||||
<div class="ui segment">
|
||||
From this page you can create, modify and delete your API applications that use OAuth 2.
|
||||
<div class="ui divider"></div>
|
||||
{{ $csrf := csrfGenerate .Context.User.ID }}
|
||||
{{ with .RequestInfo.apps }}
|
||||
<table class="ui very basic fixed table">
|
||||
{{ range . }}
|
||||
<tr>
|
||||
<td class="avatar-cell">
|
||||
{{ if .Avatar }}
|
||||
<a href="/dev/apps/edit?id={{ .ID }}" title="Edit"><img src="/static/oauth-apps/{{ .Avatar }}" alt="Avatar" class="ui tiny rounded image"></a>
|
||||
{{ end }}
|
||||
</td>
|
||||
<td>
|
||||
<a href="/dev/apps/edit?id={{ .ID }}" title="Edit"><b>{{ .Name }}</b></a>
|
||||
<div class="subtitle">{{ .ID }}</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</table>
|
||||
<div class="ui divider"></div>
|
||||
{{ end }}
|
||||
<div class="little margin top right aligned">
|
||||
<a class="ui blue labeled icon button" href="/dev/apps/edit?id=new"><i class="plus icon"></i>Create new</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
65
templates/dev/edit_app.html
Normal file
65
templates/dev/edit_app.html
Normal file
@@ -0,0 +1,65 @@
|
||||
{{/*###
|
||||
TitleBar=Edit OAuth 2 Application
|
||||
KyutGrill=dev.jpg
|
||||
MinPrivileges=2
|
||||
Include=menu.html
|
||||
HugeHeadingRight=true
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
{{ $ := . }}
|
||||
<div class="ui container">
|
||||
<div class="ui stackable grid">
|
||||
{{ template "devSidebar" . }}
|
||||
<div class="twelve wide column">
|
||||
<div class="ui segment">
|
||||
{{ $app := .RequestInfo.app }}
|
||||
{{ $id := .Gin.Query "id" }}
|
||||
{{ if $app }}
|
||||
{{ if $app.ID }}
|
||||
<div class="centered">
|
||||
{{ with $app.Avatar }}
|
||||
<img src="/static/oauth-apps/{{ . }}" alt="Avatar" class="ui small rounded image" style="margin: 0 auto;">
|
||||
{{ end }}
|
||||
<h2 class="ui header little top margin"><code>{{ $app.ID }}</code></h2>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
{{ end }}
|
||||
<form class="ui form" method="POST" enctype="multipart/form-data" action="/dev/apps/edit" id="edit-form">
|
||||
<div class="field">
|
||||
<label>Name</label>
|
||||
<input type="text" name="name" value="{{ $app.Name }}" maxlength="25">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Redirect URI</label>
|
||||
<input name="redirect_uri" value="{{ $app.RedirectURI }}" maxlength="255">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Avatar</label>
|
||||
<input name="avatar" type="file">
|
||||
</div>
|
||||
<input type="hidden" name="id" value="{{ $id }}">
|
||||
{{ csrfGenerate .Context.User.ID }}
|
||||
{{ ieForm .Gin }}
|
||||
</form>
|
||||
{{ if ne $id "new" }}
|
||||
<form action="/dev/apps/delete" method="POST" id="delete-form">
|
||||
{{ csrfGenerate $.Context.User.ID }}
|
||||
<input type="hidden" name="id" value="{{ $id }}">
|
||||
{{ ieForm $.Gin }}
|
||||
</form>
|
||||
{{ end }}
|
||||
<div class="ui divider"></div>
|
||||
<div style="text-align: right">
|
||||
<button type="submit" class="ui blue button" form="edit-form">Save</button>
|
||||
{{ if ne $id "new" }}
|
||||
<button type="submit" class="ui red button" form="delete-form">Delete</button>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ else }}
|
||||
That application could not be found!
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
55
templates/dev/edit_token.html
Normal file
55
templates/dev/edit_token.html
Normal file
@@ -0,0 +1,55 @@
|
||||
{{/*###
|
||||
Handler=/dev/tokens/edit
|
||||
TitleBar=Edit API token
|
||||
KyutGrill=dev.jpg
|
||||
MinPrivileges=2
|
||||
Include=menu.html
|
||||
HugeHeadingRight=true
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
{{ $ := . }}
|
||||
<div class="ui container">
|
||||
<div class="ui stackable grid">
|
||||
{{ template "devSidebar" . }}
|
||||
<div class="twelve wide column">
|
||||
<div class="ui segment">
|
||||
{{ with .Get "tokens?id=%d" (.Gin.Query "id" | atoint) }}
|
||||
{{ if .tokens }}
|
||||
{{ with index .tokens 0 }}
|
||||
<form class="ui form" method="POST" action="/dev/tokens/edit" id="edit-form">
|
||||
<div class="field">
|
||||
<label>Last used</label>
|
||||
<input type="text" value="{{ .last_updated }}" disabled>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Privileges</label>
|
||||
<input name="privileges" type="number" min="0" value="{{ printf "%.0f" .privileges }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Description</label>
|
||||
<input name="description" type="text" value="{{ .description }}">
|
||||
</div>
|
||||
<input type="hidden" name="id" value="{{ $.Gin.Query "id" | atoint }}">
|
||||
{{ csrfGenerate $.Context.User.ID }}
|
||||
{{ ieForm $.Gin }}
|
||||
</form>
|
||||
<form action="/dev/tokens/delete" method="POST" id="delete-form">
|
||||
{{ csrfGenerate $.Context.User.ID }}
|
||||
<input type="hidden" name="id" value="{{ $.Gin.Query "id" | atoint }}">
|
||||
{{ ieForm $.Gin }}
|
||||
</form>
|
||||
<div class="ui divider"></div>
|
||||
<div style="text-align: right">
|
||||
<button type="submit" class="ui blue button" form="edit-form">Save</button>
|
||||
<button type="submit" class="ui red button" form="delete-form">Delete</button>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
That token could not be found!
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
12
templates/dev/menu.html
Normal file
12
templates/dev/menu.html
Normal file
@@ -0,0 +1,12 @@
|
||||
{{/*###
|
||||
NoCompile=true
|
||||
*/}}
|
||||
{{ define "devSidebar" }}
|
||||
<div class="four wide column">
|
||||
<div class="ui fluid vertical menu">
|
||||
{{ navbarItem .Path "Tokens" "/dev/tokens" }}
|
||||
{{ navbarItem .Path "My Applications" "/dev/apps" }}
|
||||
{{ navbarItem .Path "Documentation" "https://docs.ripple.moe" }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
103
templates/dev/tokens.html
Normal file
103
templates/dev/tokens.html
Normal file
@@ -0,0 +1,103 @@
|
||||
{{/*###
|
||||
Handler=/dev/tokens
|
||||
TitleBar=Your API tokens
|
||||
KyutGrill=dev.jpg
|
||||
MinPrivileges=2
|
||||
Include=menu.html
|
||||
HugeHeadingRight=true
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
{{ $ := . }}
|
||||
<div class="ui container">
|
||||
<div class="ui stackable grid">
|
||||
{{ template "devSidebar" . }}
|
||||
<div class="twelve wide column">
|
||||
<div class="ui segment">
|
||||
From this page you can create, modify and delete your personal <a href="https://docs.ripple.moe/docs/api/appendix#authorization">API tokens</a>.<br>
|
||||
{{ .T "The Ripple API is the system through which developers can create applications to interact with Ripple. <b>If you're asked to fill out an API token from this page, be wary and only actually create the token if you really trust the owner of the application.</b>" | html }}
|
||||
<div class="ui divider"></div>
|
||||
{{ $csrf := csrfGenerate .Context.User.ID }}
|
||||
{{ $page := or (atoint (.Gin.Query "p")) 1 }}
|
||||
{{ with .Get "tokens?p=%d&l=50" $page }}
|
||||
{{ with .tokens }}
|
||||
<table class="ui fixed table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Privileges</th>
|
||||
<th>Description</th>
|
||||
<th>Last used</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range . }}
|
||||
<tr>
|
||||
{{/* We are using printf with %.0f so that
|
||||
it gets printed as if it was a normal int */}}
|
||||
<td><span title="{{ privilegesToString .privileges }}">{{ printf "%.0f" .privileges }}</span></td>
|
||||
<td>{{ with .description }}{{ . }}{{ else }}<i>(None)</i>{{ end }}</td>
|
||||
<td>{{ if ne (nativeTime .last_updated).Year 1970 }}{{ time .last_updated }}{{ else }}Never{{ end }}</td>
|
||||
<td>
|
||||
<form action="/dev/tokens/delete" method="POST">
|
||||
<input type="hidden" name="id" value="{{ .id }}">
|
||||
{{ $csrf }}
|
||||
{{ ieForm $.Gin }}
|
||||
<div class="ui buttons">
|
||||
<a class="ui blue icon button" href="/dev/tokens/edit?id={{ .id }}" title="Edit">
|
||||
<i class="edit icon"></i>
|
||||
</a>
|
||||
<button class="ui red icon button" type="submit" title="Delete">
|
||||
<i class="remove icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
{{ $left := gt $page 1 }}
|
||||
{{ $right := eq (len .) 50 }}
|
||||
{{ if or $left $right }}
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="4">
|
||||
<div class="ui right floated pagination menu">
|
||||
{{ if $left }}
|
||||
<a class="icon item" href="/dev/tokens?p={{ minus (float $page) 1 }}">
|
||||
<i class="left chevron icon"></i>
|
||||
</a>
|
||||
{{ end }}
|
||||
{{ if $right }}
|
||||
<a class="icon item" href="/dev/tokens?p={{ plus (float $page) 1 }}">
|
||||
<i class="right chevron icon"></i>
|
||||
</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
{{ end }}
|
||||
</table>
|
||||
<div class="ui divider"></div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
<h2 class="ui header" style="margin-top:0">Create new token</h2>
|
||||
<form action="/dev/tokens/create" method="POST" class="ui form">
|
||||
<div class="field">
|
||||
<label>Privileges</label>
|
||||
<input type="number" name="privileges" value="0" id="privileges-number" min="0">
|
||||
<div id="privileges-text"></div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>Description</label>
|
||||
<input type="text" name="description" value="" placeholder="For what are you making this token?">
|
||||
</div>
|
||||
<button class="ui blue button" type="submit">Create</button>
|
||||
{{ $csrf }}
|
||||
{{ ieForm $.Gin }}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
28
templates/doc.html
Normal file
28
templates/doc.html
Normal file
@@ -0,0 +1,28 @@
|
||||
{{/*###
|
||||
Handler=/doc
|
||||
TitleBar=Documentation
|
||||
KyutGrill=documentation.jpg
|
||||
HugeHeadingRight=true
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui segments">
|
||||
<div class="ui segment">
|
||||
{{ .T "Need some help getting around? Look no further! From here you will be able to view our documentation, which is basically a very simplistic wiki." }}
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
{{ with documentationFiles .Context.Language }}
|
||||
{{ if . }}
|
||||
<ul class="ui list">
|
||||
{{ range . }}
|
||||
<li><a href="/doc/{{ .Slug }}">{{ .Title }}</a></li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ else }}
|
||||
{{ .T "Looks like there is no documentation on this ripple instance!" }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
38
templates/doc_content.html
Normal file
38
templates/doc_content.html
Normal file
@@ -0,0 +1,38 @@
|
||||
{{/*###
|
||||
Handler=/doc/:id
|
||||
TitleBar=View document
|
||||
KyutGrill=documentation.jpg
|
||||
HugeHeadingRight=true
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui segments">
|
||||
{{ $ := . }}
|
||||
{{ with documentationData (.Gin.Param "id") (or (.Gin.Query "lang") .Context.Language) }}
|
||||
{{ if .Title }}
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header">{{ .Title }}</h1>
|
||||
</div>
|
||||
{{ if not .IsUpdated }}
|
||||
<div class="ui yellow segment">
|
||||
{{ $.T "It seems like the original version of this file has been updated, so this file is out of date and may contain inaccurate information. If you want to make sure to be up-to-date, please refer to the <a href=\"%s%s\">English version</a>." $.Gin.Request.URL.Path "?lang=en" | html }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="ui segment">
|
||||
{{ blackfriday .Data }}
|
||||
</div>
|
||||
{{ else }}
|
||||
<div class="ui segment">
|
||||
{{ $.T "Documentation file not found!" }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
<div class="ui right aligned segment">
|
||||
<a class="ui labeled icon button" href="/doc">
|
||||
<i class="left arrow icon"></i>
|
||||
{{ .T "View all docs" }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
3
templates/empty.html
Normal file
3
templates/empty.html
Normal file
@@ -0,0 +1,3 @@
|
||||
{{ define "tpl" }}
|
||||
|
||||
{{ end }}
|
59
templates/friends.html
Normal file
59
templates/friends.html
Normal file
@@ -0,0 +1,59 @@
|
||||
{{/*###
|
||||
Handler=/friends
|
||||
TitleBar=Friends
|
||||
MinPrivileges=2
|
||||
KyutGrill=friends.jpg
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui segments">
|
||||
<div class="ui segment">
|
||||
{{ .T "On this page you can see all of your friends, and unfriend them as you see fit." }}
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
{{ $ := . }}
|
||||
{{ $page := or (atoint (.Gin.Query "p")) 1 }}
|
||||
{{ $friends := .Get "friends?p=%d&l=40&sort=username,asc" $page }}
|
||||
{{ with $friends }}
|
||||
<div class="ui four column stackable grid">
|
||||
{{ range .friends }}
|
||||
<div class="ui column">
|
||||
<h4 class="ui image header">
|
||||
<img src="{{ config "AvatarURL" }}/{{ .id }}" class="ui mini rounded image"{{ if not (has .privileges 1) }} style="opacity: 0.5"{{ end }}>
|
||||
<div class="content">
|
||||
<a href="/u/{{ .id }}"{{ if not (has .privileges 1) }} style="opacity: 0.5"{{ end }}>{{ .username }}</a>
|
||||
<div class="sub header">
|
||||
<div class="ui compact circular smalltext icon labeled {{ if .is_mutual }}red{{ else }}green{{ end }} button"
|
||||
data-userid="{{ .id }}">
|
||||
<i class="{{ if .is_mutual }}heart{{ else }}minus{{ end }} icon"></i>
|
||||
<span>{{ if .is_mutual }}{{ $.T "Mutual" }}{{ else }}{{ $.T "Remove" }}{{ end }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h4>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ $left := gt $page 1 }}
|
||||
{{ $right := eq (len (rsin $friends.friends)) 40 }}
|
||||
{{ if or $left $right }}
|
||||
<div class="ui right aligned segment">
|
||||
<div class="ui pagination menu">
|
||||
{{ if $left }}
|
||||
<a class="icon item" href="/friends?p={{ minus (float $page) 1 }}">
|
||||
<i class="left chevron icon"></i>
|
||||
</a>
|
||||
{{ end }}
|
||||
{{ if $right }}
|
||||
<a class="icon item" href="/friends?p={{ plus (float $page) 1 }}">
|
||||
<i class="right chevron icon"></i>
|
||||
</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
61
templates/homepage.html
Normal file
61
templates/homepage.html
Normal file
@@ -0,0 +1,61 @@
|
||||
{{/*###
|
||||
Handler=/
|
||||
TitleBar=Home Page
|
||||
KyutGrill=homepage2.jpg
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
{{ $cf := .ClientFlags }}
|
||||
{{ $ds := band $cf 1 }}
|
||||
{{ $ := . }}
|
||||
<div class="ui container">
|
||||
<div class="ui center aligned segment">
|
||||
<img src="/static/logos/logo-{{ randomLogoColour }}{{ if $ds }}-dark{{ end }}.svg">
|
||||
</div>
|
||||
{{ $set := systemSettings "website_home_alert" }}
|
||||
{{ with $set.website_home_alert.String }}
|
||||
<div class="ui warning message">
|
||||
{{ . | html }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{/* Not logged in block */}}
|
||||
{{ if not .Context.User.ID }}
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header">{{ .T "Welcome to Ripple." }}</h1>
|
||||
<p>
|
||||
{{ .T "You look new here. Allow us to introduce you to what Ripple is." }}
|
||||
</p>
|
||||
<p>
|
||||
{{ .T "Ripple is a private osu! server, featuring multiplayer, PP, a very active community and a development team going strong implementing new features and squashing bugs. <a href='/about'>You can check out even more features here.</a> It has also a very friendly community, and it's <a href='https://zxq.co/ripple/ripple'>open source!</a> Just so you know, <b>we currently have %s users online and %s registered users!</b>" (rediget "ripple:online_users") (rediget "ripple:registered_users") | html }}
|
||||
</p>
|
||||
<h3 class="ui header center aligned">{{ .T "What are you waiting for? Join Ripple! It's risk-free: you won't get your account banned on the official server if you play on Ripple.<br>You can also switch anytime between the official osu! server and Ripple!" | html }}</h3>
|
||||
</div>
|
||||
{{ else }}
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header">{{ .T "Howdy, %s!" .Context.User.Username }}</h1>
|
||||
<p>
|
||||
{{ .T "Welcome back to Ripple. We currently have <b>%s online users and %s total registered users.</b> Nice day to farm a few maps, isn't it?" (rediget "ripple:online_users") (rediget "ripple:registered_users") | html }}
|
||||
</p>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ with (.Get "blog/posts?l=5") }}
|
||||
<div class="ui raised segment">
|
||||
<h1 class="ui center aligned header">
|
||||
{{ $.T "Latest news from our <a href='https://blog.ripple.moe'>blog</a>" | html }}
|
||||
</h1>
|
||||
</div>
|
||||
<div class="ui segments">
|
||||
{{ range $i, $v := .posts }}
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header no top margin">
|
||||
<a href="https://blog.ripple.moe/{{ $v.unique_slug }}" class="inherit">{{ html $v.title }}</a>
|
||||
<div class="sub header"><a href="https://blog.ripple.moe/@{{ $v.creator.username }}">{{ $v.creator.name }}</a>, {{ time $v.created_at }}</div>
|
||||
</h1>
|
||||
<p>
|
||||
{{ $v.snippet }}
|
||||
</p>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
22
templates/irc.html
Normal file
22
templates/irc.html
Normal file
@@ -0,0 +1,22 @@
|
||||
{{/*###
|
||||
Handler=/irc
|
||||
TitleBar=IRC token
|
||||
MinPrivileges=2
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui segments">
|
||||
<div class="ui segment">
|
||||
{{ .T "Here you can generate a new IRC token. You can use it to connect to Ripple's chat using IRC. Remember that your IRC token is like a password, anyone who knows it, has access to your account. If you're interested knowing how to connect to Ripple's chat via IRC, you may want to check out <a href=\"/doc/11\">this</a>." | html }}
|
||||
</div>
|
||||
<div class="ui right aligned segment">
|
||||
<form action="/irc/generate" method="POST">
|
||||
{{ ieForm .Gin }}
|
||||
<button tabindex="1" type="submit" class="ui right blue button">
|
||||
{{ .T "Generate a new token!" }}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
58
templates/leaderboard.html
Normal file
58
templates/leaderboard.html
Normal file
@@ -0,0 +1,58 @@
|
||||
{{/*###
|
||||
Handler=/leaderboard
|
||||
TitleBar=Leaderboard
|
||||
KyutGrill=leaderboard2.jpg
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
{{ $favModeRaw := .Get "users/self/favourite_mode" }}
|
||||
{{ $favMode := _or (atoi (.Gin.Query "mode")) $favModeRaw.favourite_mode (float 0) }}
|
||||
<script>
|
||||
var favouriteMode = {{ $favMode }};
|
||||
var page = {{ .Gin.Query "p" | atoint | atLeastOne }};
|
||||
var country = {{ .Gin.Query "country" }}.toLowerCase();
|
||||
if (country.length != 2)
|
||||
country = "";
|
||||
</script>
|
||||
<div class="ui four item menu" id="mode-menu">
|
||||
{{ range $k, $v := modes }}
|
||||
<a class="{{ favMode $favMode $k }}item" data-mode="{{ $k }}" href="/leaderboard?mode={{ $k }}">{{ $v }}</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="ui twelve item stackable menu">
|
||||
{{ range countryList 11 }}
|
||||
<a class="item lb-country" data-country="{{ . }}"><i class="{{ . }} flag nopad"></i></a>
|
||||
{{ end }}
|
||||
<a class="item" id="country-chooser-modal">...</a>
|
||||
</div>
|
||||
<table class="ui fixed table">
|
||||
<thead>
|
||||
{{ template "simplepag" 5 }}
|
||||
<tr>
|
||||
<th class="two wide">{{ .T "Rank" }} </th>
|
||||
<th class="four wide">{{ .T "Player" }} </th>
|
||||
<th class="four wide">{{ .T "PP/Score" }} </th>
|
||||
<th class="three wide">{{ .T "Accuracy" }} </th>
|
||||
<th class="three wide">{{ .T "Playcount" }} </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
{{ template "simplepag" 5 }}
|
||||
</tfoot>
|
||||
</table>
|
||||
<div class="ui modal">
|
||||
<div class="content">
|
||||
<div class="ui four column grid">
|
||||
{{ range countryList 500 }}
|
||||
{{ $short := . }}
|
||||
{{ with country . true }}
|
||||
<div class="ui clickable column lb-country" data-country="{{ $short }}">{{ . }}</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
37
templates/login.html
Normal file
37
templates/login.html
Normal file
@@ -0,0 +1,37 @@
|
||||
{{/*###
|
||||
Handler=/login
|
||||
TitleBar=Log in
|
||||
KyutGrill=login2.jpg
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
{{/* Not logged in block */}}
|
||||
{{ if .Context.User.Username }}
|
||||
<div class="ui segment">
|
||||
{{ .T "You're already logged in!" }}
|
||||
</div>
|
||||
{{ else }}
|
||||
<div class="tiny container">
|
||||
<div class="ui raised segments">
|
||||
<div class="ui segment">
|
||||
<form id="login-form" class="ui form" method="post" action="/login">
|
||||
<div class="field">
|
||||
<label>{{ .T "Username (or email)" }}</label>
|
||||
<input tabindex="1" type="text" name="username" placeholder="{{ .T "Username" }}" value="{{ .FormData.username }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>{{ .T "Password" }} <a href="/pwreset">{{ .T "(forgot?)" }}</a></label>
|
||||
<input tabindex="2" type="password" name="password" placeholder="{{ .T "Password" }}" value="{{ .FormData.password }}" required>
|
||||
</div>
|
||||
<input type="hidden" name="redir" value="{{ or (.Gin.Query "redir") .FormData.redir }}">
|
||||
{{ ieForm .Gin }}
|
||||
</form>
|
||||
</div>
|
||||
<div class="ui right aligned segment">
|
||||
<button tabindex="3" class="ui primary button" type="submit" form="login-form">{{ .T "Submit" }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
69
templates/navbar.html
Normal file
69
templates/navbar.html
Normal file
@@ -0,0 +1,69 @@
|
||||
{{ define "navbar" }}
|
||||
{{ $isRAP := and (hasAdmin .Context.User.Privileges) (isRAP .Path) }}
|
||||
{{ $isAdmin := hasAdmin .Context.User.Privileges }}
|
||||
{{ $ds := band .ClientFlags 1 }}
|
||||
<div class="ui secondary fixed-height stackable white background main menu no margin bottom{{ if .DisableHH }} dropped{{ end }}" id="navbar">
|
||||
<div class="ui container">
|
||||
<div class="item">
|
||||
<b><a href="/" title="{{ .T "Home page" }}"><img class="ripple logo" src="/static/logos/text-{{ if $ds }}white{{ else }}black{{ end }}.png" alt="Ripple"></a></b>
|
||||
</div>
|
||||
{{ if $isRAP }}
|
||||
{{/*
|
||||
Note:
|
||||
RAP navbar will be completely different from standard navbar,
|
||||
meaning it will have the buttons and all the stuff that are in
|
||||
the current RAP's sidebar.
|
||||
*/}}
|
||||
{{ else }}
|
||||
{{ navbarItem .Path (.T "Leaderboard") "/leaderboard" }}
|
||||
<div class="ui dropdown item">
|
||||
<span>{{ .T "Help" }}</span>
|
||||
<div class="menu">
|
||||
{{ navbarItem .Path (.T "About") "/about" }}
|
||||
{{ navbarItem .Path (.T "Rules") "/doc/rules" }}
|
||||
{{ navbarItem .Path (.T "Documentation") "/doc" }}
|
||||
{{ navbarItem .Path (.T "Server switcher") "https://mu.nyodev.xyz/upd.php?id=18" }}
|
||||
<div class="divider"></div>
|
||||
{{ navbarItem .Path (.T "Chat (Discord)") .Conf.DiscordServer }}
|
||||
{{ navbarItem .Path (.T "Contact support") "https://support.ripple.moe" }}
|
||||
</div>
|
||||
</div>
|
||||
{{ if .Context.User.Username }}
|
||||
<div class="ui dropdown item">
|
||||
<span>{{ .T "Beatmaps" }}</span>
|
||||
<div class="menu">
|
||||
{{ navbarItem .Path (.T "Request beatmap ranking") "/beatmaps/rank_request" }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ navbarItem .Path (.T "Donate" | printf "<i class=\"red heart icon\"></i>%s") "/donate" }}
|
||||
{{ if $isAdmin }}{{ navbarItem .Path (.T "RAP" | printf "<b>%s</b>") "https://old.ripple.moe/index.php?p=100" }}{{ end }}
|
||||
{{ end }}
|
||||
<div class="firetrucking-right-menu">
|
||||
<div class="item">
|
||||
<div class="ui search" id="user-search">
|
||||
<div class="ui icon input">
|
||||
<input class="prompt" type="text" placeholder="{{ .T "Looking for someone?" }}" id="user-search-input">
|
||||
<i class="search link icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ if .Context.User.Username }}
|
||||
<div class="ui dropdown item">
|
||||
<img class="ui avatar image" src="{{ config "AvatarURL" }}/{{ .Context.User.ID }}">
|
||||
<span>{{ .Context.User.Username }}</span>
|
||||
<div class="menu">
|
||||
{{ navbarItem .Path (.T "Profile") (printf "/u/%d" .Context.User.ID) }}
|
||||
{{ navbarItem .Path (.T "Friends") "/friends" }}
|
||||
{{ navbarItem .Path (.T "Settings") "/settings" }}
|
||||
{{ navbarItem .Path (.T "Log out") (printf "/logout?k=%s" (.Session.Get "logout")) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ else }}
|
||||
{{ navbarItem .Path (.T "Log in") "/login" }}
|
||||
{{ navbarItem .Path (.T "Register") "/register" }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
7
templates/not_found.html
Normal file
7
templates/not_found.html
Normal file
@@ -0,0 +1,7 @@
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui segment">
|
||||
{{ .T "We're sorry, but we were unable to find the content you were looking for!" }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
59
templates/oauth.html
Normal file
59
templates/oauth.html
Normal file
@@ -0,0 +1,59 @@
|
||||
{{/*###
|
||||
TitleBar=Log in with Ripple
|
||||
KyutGrill=login2.jpg
|
||||
MinPrivileges=2
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
{{ $client := .RequestInfo.Client }}
|
||||
<div class="ui container">
|
||||
<div class="tiny container">
|
||||
<div class="ui grid segment internally divided">
|
||||
<div class="ten wide column">
|
||||
<p>{{ .T "This application will be able to:" }}</p>
|
||||
<div class="ui section divider"></div>
|
||||
<h3 class="ui header"><i class="user icon"></i><div class="content">{{ .T "Identify" }}</i></h3>
|
||||
<p>
|
||||
{{ .T "See your public information (everything somebody can see on your user profile), however with this alone it will not be able to see your private information (for instance your email address)." }}
|
||||
</p>
|
||||
<div class="ui section divider"></div>
|
||||
{{ $ := . }}
|
||||
{{ range $client.Authorizations }}
|
||||
{{ if eq . "read_confidential" }}
|
||||
<h3 class="ui header"><i class="eye icon"></i><div class="content">{{ $.T "Read private information" }}</i></h3>
|
||||
<p>
|
||||
{{ $.T "This application will be able to see your email address, and any private information we will add in the future." }}
|
||||
</p>
|
||||
{{ end }}
|
||||
{{ if eq . "write" }}
|
||||
<h3 class="ui header"><i class="pencil icon"></i><div class="content">{{ $.T "Write" }}</i></h3>
|
||||
<p>
|
||||
{{ $.T "This application will be able to make modifications to your Ripple account. This is potentially really dangerous! Use this only with applications that you trust." }}
|
||||
</p>
|
||||
{{ end }}
|
||||
<div class="ui section divider"></div>
|
||||
{{ end }}
|
||||
<p>
|
||||
<form method="POST" action="{{ .Gin.Request.URL.String }}">
|
||||
<input type="hidden" name="appid" value="{{ $client.ID }}">
|
||||
{{ ieForm .Gin }}
|
||||
{{ csrfGenerate .Context.User.ID }}
|
||||
<button type="submit" name="approve" value="1" class="ui primary button">
|
||||
{{ .T "Approve" }}
|
||||
</button>
|
||||
<button type="submit" name="approve" value="0" class="ui button">
|
||||
{{ .T "Deny" }}
|
||||
</button>
|
||||
</form>
|
||||
</p>
|
||||
</div>
|
||||
<div class="six wide column centered">
|
||||
{{ with $client.Avatar }}<img src="/static/oauth-apps/{{ . }}" alt="Avatar" class="ui small rounded image" style="margin: 0 auto">{{ end }}
|
||||
<h1 class="ui header">
|
||||
{{ $client.Name }}
|
||||
<div class="sub header">{{ .T "created by %s" (printf "<a href=\"/u/%s\" target=\"_blank\">%s</a>" $client.CreatorID .RequestInfo.CreatorName) | html }}</div>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
215
templates/profile.html
Normal file
215
templates/profile.html
Normal file
@@ -0,0 +1,215 @@
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
{{ if .UserID }}
|
||||
{{ $gqm := atoi (.Gin.Query "mode") }}
|
||||
{{ $global := . }}
|
||||
{{ with (.Get "users/full?id=%d" .UserID) }}
|
||||
{{ $favouritemode := _or $gqm .favourite_mode }}
|
||||
<script>
|
||||
window.favouriteMode = {{ $favouritemode }};
|
||||
window.userID = {{ .id }};
|
||||
</script>
|
||||
{{ if after .silence_info.end }}
|
||||
<div class="ui error centered message">{{ $global.T "User is <b>silenced</b> for %s, expires %s." (.silence_info.reason | htmlescaper) (time .silence_info.end) | html }}</div>
|
||||
{{ end }}
|
||||
{{ if hasAdmin $global.Context.User.Privileges }}
|
||||
{{ $restr := not (has .privileges 1) }}
|
||||
{{ $disab := not (has .privileges 2) }}
|
||||
{{ $pend := has .privileges 1048576 }}
|
||||
{{ if and $disab $restr }}
|
||||
{{ if $pend }}
|
||||
<div class="ui warning centered message">{{ $global.T "User is <b>%s</b>" "pending verification" | html }}.</div>
|
||||
{{ else }}
|
||||
<div class="ui error centered message">{{ $global.T "User is <b>%s</b>" "banned" | html }}.</div>
|
||||
{{ end }}
|
||||
{{ else if $restr }}
|
||||
<div class="ui error centered message">{{ $global.T "User is <b>%s</b>" "restricted" | html }}.</div>
|
||||
{{ else if $disab }}
|
||||
<div class="ui error centered message">{{ $global.T "User is <b>%s</b>" "locked" | html }}.</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ with $global.Get "users/userpage?id=%.0f" .id }}
|
||||
{{ if .userpage }}
|
||||
{{ with parseUserpage .userpage }}
|
||||
<div class="ui raised segment twemoji" id="userpage-content">
|
||||
{{ html . }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
<div class="ui top attached segment overflow auto">
|
||||
<div class="magic table">
|
||||
<div class="table element">
|
||||
{{ if eq $global.UserID $global.Context.User.ID }}
|
||||
<a href="/settings/avatar">
|
||||
{{ end }}
|
||||
<img src="{{ config "AvatarURL" }}/{{ .id }}" alt="avatar" class="user avatar">
|
||||
{{ if eq $global.UserID $global.Context.User.ID }}
|
||||
</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="table element">
|
||||
<h1 class="ui header">
|
||||
{{ .username }}
|
||||
</h1>
|
||||
{{ if .username_aka }}
|
||||
<div class="subtitle">
|
||||
{{ $global.T "(aka <b>%s</b>)" (.username_aka | htmlescaper) | html }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ with bget "isOnline?id=%.0f" .id }}
|
||||
<div class="subtitle">
|
||||
<i class="{{ if .result }}green{{ else }}grey{{ end }} circle icon"></i>
|
||||
{{ if .result }}{{ $global.T "Online" }}{{ else }}{{ $global.T "Offline" }}{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="magic table floating right">
|
||||
<div class="table element">
|
||||
{{ range $k, $v := (slice .std .taiko .ctb .mania) }}
|
||||
<h1 data-mode="{{ $k }}"{{ if ne $k (int $favouritemode) }} hidden{{ end }}>{{ with and $v $v.global_leaderboard_rank }}#{{ . }}{{ else }}{{ $global.T "Unknown" }}{{ end }}</h1>
|
||||
{{ end }}
|
||||
<div id="profile-actions">
|
||||
{{ if and (ne $global.Context.User.ID $global.UserID) (ne $global.Context.User.ID 0) }}
|
||||
<button class="ui circular mini icon loading button" id="add-friend-button">
|
||||
<i class="horizontal ellipsis icon"></i>
|
||||
</button>
|
||||
{{ end }}
|
||||
{{ if eq $global.Context.User.ID $global.UserID }}
|
||||
<a href="/settings" class="ui circular mini teal icon button"
|
||||
title="{{ $global.T "Settings" }}">
|
||||
<i class="edit icon"></i>
|
||||
</a>
|
||||
{{ end }}
|
||||
{{ if hasAdmin $global.Context.User.Privileges }}
|
||||
<a href="https://old.ripple.moe/index.php?p=103&id={{ $global.UserID }}"
|
||||
target="_blank" title="Quick edit" class="ui circular mini blue icon button">
|
||||
<i class="folder open outline icon"></i>
|
||||
</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ $user := . }}
|
||||
<div class="ui four item bottom attached menu" id="mode-menu">
|
||||
{{ range $k, $v := modes }}
|
||||
<a class="{{ favMode $favouritemode $k }}item" data-mode="{{ $k }}" href="/u/{{ $user.id }}?mode={{ $k }}">{{ $v }}</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<div class="ui three column divided stackable grid">
|
||||
<div class="row">
|
||||
<div class="column">
|
||||
{{ $global.T "<b>%s</b> is a Ripple player from <b>%s</b>." .username (country .country true) | html }}
|
||||
<br>{{ $global.T "They signed up on Ripple %s." (time $user.registered_on) | html }}
|
||||
<br>{{ $global.T "Last seen: %s." (time $user.latest_activity) | html }}
|
||||
<br>{{ with playstyle .play_style $global }}{{ $global.T "They play with %s." . }}{{ end }}
|
||||
</div>
|
||||
<div class="column">
|
||||
{{ if and (not .badges) (not .custom_badge) }}
|
||||
{{ $global.T "This user hasn't got any badges!" }}
|
||||
{{ else }}
|
||||
<div class="ui grid">
|
||||
{{ range .badges }}
|
||||
<div class="eight wide centered column">
|
||||
<i class="circular {{ faIcon .icon }} big icon"></i><br>
|
||||
<b>{{ .name }}</b>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ with .custom_badge }}
|
||||
<div class="eight wide centered column">
|
||||
<i class="circular {{ faIcon .icon }} big icon"></i><br>
|
||||
<b><i>{{ .name }}</i></b>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="column">
|
||||
{{ range $k, $v := (slice .std .taiko .ctb .mania) }}
|
||||
<div data-mode="{{ $k }}" {{ if ne $k (int $favouritemode) }} hidden{{ end }}>
|
||||
<table class="ui very basic two column compact table nopad">
|
||||
<tbody>
|
||||
{{ with .global_leaderboard_rank }}
|
||||
<tr>
|
||||
<td><b>{{ $global.T "Global rank" }}</b></td>
|
||||
<td class="right aligned">#{{ . }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
{{ with .country_leaderboard_rank }}
|
||||
<tr>
|
||||
<td><b>{{ $global.T "Country rank" }} {{ country $user.country false }}</b></td>
|
||||
<td class="right aligned">#{{ . }}</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
<tr>
|
||||
<td><b>{{ $global.T "PP" }}</b></td>
|
||||
<td class="right aligned">{{ humanize .pp }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>{{ $global.T "Ranked score" }}</b></td>
|
||||
<td class="right aligned">{{ humanize .ranked_score }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>{{ $global.T "Total score" }}</b></td>
|
||||
<td class="right aligned">{{ humanize .total_score }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>{{ $global.T "Playcount" }}</b></td>
|
||||
<td class="right aligned">{{ humanize .playcount }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>{{ $global.T "Replays watched" }}</b></td>
|
||||
<td class="right aligned">{{ humanize .replays_watched }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>{{ $global.T "Total hits" }}</b></td>
|
||||
<td class="right aligned">{{ humanize .total_hits }}</td>
|
||||
</tr> <tr>
|
||||
<td><b>{{ $global.T "Accuracy" }}</b></td>
|
||||
<td class="right aligned">{{ printf "%.2f" .accuracy }}%</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="ui blue progress little margin top" data-percent="{{ levelPercent .level }}">
|
||||
<div class="bar">
|
||||
<div class="progress">{{ levelPercent .level }}%</div>
|
||||
</div>
|
||||
<div class="label">{{ $global.T "Level %s" (level .level) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- end grid segment -->
|
||||
<div id="scores-zone">
|
||||
{{ range _range 4 }}
|
||||
<div data-mode="{{ . }}" {{ if ne . (int $favouritemode) }} hidden{{ end }} data-loaded="0">
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<div class="ui segment">
|
||||
<h2 class="ui header">{{ $global.T "Achievements" }}</h2>
|
||||
<div id="achievements" class="ui grid">
|
||||
</div>
|
||||
<div class="right aligned">
|
||||
<button class="ui disabled button" id="load-more-achievements">
|
||||
{{ $global.T "Load more" }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui modal">
|
||||
<i class="close icon"></i>
|
||||
<div class="content">
|
||||
<table class="ui definition table" id="score-data-table">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
34
templates/pwreset.html
Normal file
34
templates/pwreset.html
Normal file
@@ -0,0 +1,34 @@
|
||||
{{/*###
|
||||
Handler=/pwreset
|
||||
TitleBar=Reset password
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
{{ if .Context.User.ID }}
|
||||
<div class="ui segment">
|
||||
{{ .T "You're already logged in!" }}
|
||||
</div>
|
||||
{{ else }}
|
||||
<!-- TODO: captcha -->
|
||||
<div class="tiny container">
|
||||
<div class="ui raised segments">
|
||||
<div class="ui segment">
|
||||
{{ .T "Forgot your password? Worry not! Here you can reset it. Just tell us your username or email address, and we'll take care of it. You will receive an email at the email address you used to sign up on Ripple. To continue the password reset procedure, click the link on that email." }}
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<form id="pw-reset-form" class="ui form" method="post" action="/pwreset">
|
||||
{{ ieForm .Gin }}
|
||||
<div class="field">
|
||||
<label>{{ .T "Username (or email)" }}</label>
|
||||
<input tabindex="1" type="text" name="username" placeholder="{{ .T "Username" }}" value="{{ .FormData.username }}" required>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="ui right aligned segment">
|
||||
<button tabindex="2" class="ui primary button" type="submit" form="pw-reset-form">{{ .T "Username" }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
27
templates/pwreset/continue.html
Normal file
27
templates/pwreset/continue.html
Normal file
@@ -0,0 +1,27 @@
|
||||
{{/*###
|
||||
TitleBar=Reset password
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="tiny container">
|
||||
<div class="ui raised segments">
|
||||
<div class="ui segment">
|
||||
{{ .T "Glad to have you back here, %s! To finish the password recovery, type in a new password:" .RequestInfo.Username }}
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<form id="pw-reset-form" class="ui form" method="post" action="/pwreset/continue">
|
||||
<div class="field">
|
||||
<label>{{ .T "Password" }}</label>
|
||||
<input type="password" name="password" placeholder="{{ .T "Password" }}" value="{{ .FormData.password }}" required>
|
||||
</div>
|
||||
<input type="hidden" name="k" value="{{ .RequestInfo.Key }}">
|
||||
{{ ieForm .Gin }}
|
||||
</form>
|
||||
</div>
|
||||
<div class="ui right aligned segment">
|
||||
<button class="ui primary button" type="submit" form="pw-reset-form">{{ .T "Submit" }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
45
templates/register/elmo.html
Normal file
45
templates/register/elmo.html
Normal file
@@ -0,0 +1,45 @@
|
||||
{{/*###
|
||||
TitleBar=Elmo! Stop!
|
||||
HeadingTitle=Stop!
|
||||
KyutGrill=stop_sign.png
|
||||
HeadingOnRight=true
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui raised segments">
|
||||
<div class="ui segment">
|
||||
{{ $username := .RequestInfo.Username }}
|
||||
<img src="/static/jack_black.jpg" class="ui small right floated image" alt="Jack black">
|
||||
|
||||
<p>{{ .T "We see that you're trying to sign up while having already signed up as %s! Please note that multiaccounting is punishable, and can lead to a one month restriction!" $username }}</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
{{ .T "If you're %s, keep in mind that multiaccounting = ban." $username }}
|
||||
</li>
|
||||
<li>
|
||||
{{ .T "If you're not %s, but you're using %s's computer, please sign up on Ripple from your own computer." $username $username }}
|
||||
</li>
|
||||
<li>
|
||||
{{ .T "If you live with %s and you don't have your own computer from which to sign up on Ripple, then please contact support@ripple.moe, and we'll deal with your specific case." $username }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
{{ .T "This warning may pop up also if you're using another computer on the same network of %s. As long as you're not using the same computer, you should be all good." $username }}
|
||||
</p>
|
||||
<p style="margin-bottom:40px;">
|
||||
<a href="/register?stopsign=1" class="camouflaged">{{ .T "If you truly have understood what's written above and you have understood that creating a multiaccount will lead to a restriction on your main account, you can click here and you'll be brought to the sign up page." }}</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="ui right aligned segment">
|
||||
<div class="ui buttons">
|
||||
<a tabindex="1" class="ui labeled blue icon button" href="/">
|
||||
<i class="left chevron icon"></i>
|
||||
{{ .T "Bring me back to safety!" }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
49
templates/register/register.html
Normal file
49
templates/register/register.html
Normal file
@@ -0,0 +1,49 @@
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
{{ $regEnabled := qb "SELECT value_int FROM system_settings WHERE name = 'registrations_enabled'" }}
|
||||
{{ if .Context.User.ID }}
|
||||
<div class="ui segment">
|
||||
{{ .T "You're already logged in!" }}
|
||||
</div>
|
||||
{{ else if not ($regEnabled.value_int.Bool) }}
|
||||
<div class="ui error message">
|
||||
{{ .T "Sorry, it's not possible to register at the moment. Please try again later." }}
|
||||
</div>
|
||||
{{ else }}
|
||||
{{ if eq (.Gin.Query "stopsign") "1" }}
|
||||
<div class="ui warning message">
|
||||
{{ .T "Remember: this seems like it's your second account! Do not multiaccount, or you're likely to get restricted!" }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="tiny container">
|
||||
<div class="ui raised segments">
|
||||
<div class="ui segment">
|
||||
<form id="register-form" class="ui form" method="post" action="/register">
|
||||
<div class="field">
|
||||
<label>{{ .T "Username (2 to 15 characters, alphanumeric, spaces, <code>_[]-</code>)" | html }}</label>
|
||||
<input tabindex="1" type="text" name="username" placeholder="{{ .T "Username" }}" value="{{ .FormData.username }}" required pattern="^[A-Za-z0-9 _\[\]-]{2,15}$">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>{{ .T "Password (at least 8 characters)" }}</label>
|
||||
<input tabindex="2" type="password" name="password" placeholder="{{ .T "Password" }}" value="{{ .FormData.password }}" required pattern="^.{8,}$">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>{{ .T "Email" }}</label>
|
||||
<input tabindex="3" type="email" name="email" placeholder="{{ .T "Email" }}" value="{{ .FormData.email }}" required>
|
||||
</div>
|
||||
{{ with config "RecaptchaSite" }}
|
||||
<div class="field">
|
||||
<div class="g-recaptcha" data-sitekey="{{ . }}"></div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ ieForm .Gin }}
|
||||
</form>
|
||||
</div>
|
||||
<div class="ui right aligned segment">
|
||||
<button tabindex="4" class="ui primary button" type="submit" form="register-form">{{ .T "Submit" }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
27
templates/register/verify.html
Normal file
27
templates/register/verify.html
Normal file
@@ -0,0 +1,27 @@
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui segment">
|
||||
{{ .T "Your account has been created, however it still <b>needs to be verified!</b> Please log in into <b><u>osu! (the game)</u></b> using your account. <b>There is <u>no email confirmation</u> at the moment. All you need to do is connect to Ripple from the osu! client!</b> If you're having trouble, <a href='/doc/1'>follow this guide</a>." | html }}
|
||||
</div>
|
||||
<div class="ui centered error message">
|
||||
{{ .T "<b class='big text'>Do not let anyone except yourself log into your Ripple account!</b><br> Get on our <a href='%s'>Discord server's</a> #help channel instead (after following the steps on this page) so that we can help you out if you have trouble connecting." (config "DiscordServer") | html }}
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<h1 class="ui heading">{{ .T "The Guide (<a href='/doc/connection_guide' target='_blank'>Windows</a>, <a href='/doc/linux' target='_blank'>Linux</a>). TL;DR version below." | html }}</h1>
|
||||
<ol class="ui list">
|
||||
<li><a href="https://mu.nyodev.xyz/upd.php?id=18"><b>{{ .T "Download the server switcher" }}</b></a></li>
|
||||
<li>{{ .T "Extract it, disable your antivirus, execute <i>RippleServerSwitcher.exe</i> <b>as administrator</b>" | html }}</li>
|
||||
<li>{{ .T "Click on <b>Connect to Ripple</b>, then <b>Ok/Yes</b>" | html }}</li>
|
||||
<li>{{ .T "Make sure the switcher says you're connected to <b>Ripple</b>" | html }}</li>
|
||||
<li>{{ .T "If it says something about read-only mode, go to <code>C:\\Windows\\System32\\Drivers\\etc</code>, open the hosts' file Properties and make sure it's not set to \"Read only\"." | html }}</li>
|
||||
</ol>
|
||||
<p>
|
||||
{{ .T "If you're still having trouble, then again, get on our <a href='%s'>Discord server's</a> #help channel. To have a better chance to be answered, say \"strawberry\" anywhere in your messages so that we know you have actually read this." (config "DiscordServer") | html }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="ui center aligned segment">
|
||||
<h1 class="ui heading">{{ .T "Waiting for verification" }}</h1>
|
||||
<i class="circle notched huge loading icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
34
templates/register/welcome.html
Normal file
34
templates/register/welcome.html
Normal file
@@ -0,0 +1,34 @@
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui segments">
|
||||
{{/* Dirty hack to detect if it's a multi */}}
|
||||
{{ if eq .TitleBar (.T "Welcome back!") }}
|
||||
<div class="ui segment">
|
||||
{{ .T "Congratulations for not reading things!" }}
|
||||
</div>
|
||||
<div class="ui center aligned segment">
|
||||
<h1 class="ui heading">{{ .T "Multiaccounts are not allowed on Ripple" }}</h1>
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
{{ .T "Your new account has been <b>banned</b> and your main account has been <b>restricted</b>. You can appeal in a month by sending an email to <b><a href='mailto:support@ripple.moe'>support@ripple.moe</a></b>. You better read the rules next time." | html }}
|
||||
</div>
|
||||
{{ else }}
|
||||
<div class="ui segment">
|
||||
<h1 class="ui heading">{{ .T "Welcome to Ripple" }}</h1>
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<p>{{ .T "We're glad to have you here. <b>Your account is now active.</b> You can now play on Ripple and <a href='/login'>log in</a> on the website!" | html }}</p>
|
||||
<p>{{ .T "Here's a few things you might want to check out:" }}</p>
|
||||
<ul class="ui list">
|
||||
<li><b><a href="/login">{{ .T "Login" }}</a></b>{{ .T " - in case you don't know where to start" }}</li>
|
||||
<li><b><a href="/doc/rules">{{ .T "Rules" }}</a></b>{{ .T " - in case you haven't already read them" }}</li>
|
||||
<li><b><a href="/doc">{{ .T "Documentation" }}</a></b>{{ .T " - in case, well, you need help doing stuff" }}</li>
|
||||
<li><b><a href="https://status.ripple.moe">{{ .T "Status" }}</a></b>{{ .T " - in case you believe Ripple is down" }}</li>
|
||||
<li><b><a href="{{ .Conf.DiscordServer }}">{{ .T "Discord" }}</a></b>{{ .T " - in case you want to talk with people about Ripple" }}</li>
|
||||
<li><b><a href="https://reddit.com/r/osuripple">{{ .T "Subreddit" }}</a></b>{{ .T " - just in case" }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
91
templates/settings/2fa.html
Normal file
91
templates/settings/2fa.html
Normal file
@@ -0,0 +1,91 @@
|
||||
{{/*###
|
||||
Handler=/settings/2fa
|
||||
TitleBar=Two Factor Authentication
|
||||
KyutGrill=settings2.jpg
|
||||
Include=menu.html
|
||||
MinPrivileges=2
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui stackable grid">
|
||||
{{ template "settingsSidebar" . }}
|
||||
<div class="twelve wide column">
|
||||
{{ $e := is2faEnabled .Context.User.ID }}
|
||||
{{ if $e }}
|
||||
<div class="ui success message">
|
||||
{{ .T "Two factor authentication is enabled on your account." }}
|
||||
</div>
|
||||
{{ else }}
|
||||
<div class="ui warning message">
|
||||
{{ .T "Two factor authentication is not enabled on your account." }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="ui segments">
|
||||
{{ if eq $e 0 }}
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header">
|
||||
{{ .T "Google Authenticator (TOTP) based 2FA" }}
|
||||
</h1>
|
||||
{{ $k := generateKey .Context }}
|
||||
<div class="ui compact centered segment" style="margin: 0 auto; display: table">
|
||||
<img src="https://chart.googleapis.com/chart?chs=256x256&cht=qr&chl=otpauth://totp/{{ $k.AccountName }}%3Fsecret={{ $k.Secret }}%26issuer={{ $k.Issuer }}">
|
||||
</div>
|
||||
<p class="little top margin">
|
||||
{{ .T "Scan this from <a href=\"https://support.google.com/accounts/answer/1066447?hl=en\">Google Authenticator</a>, or if you're not able to, provide to Google Authenticator this key: <code>%s</code>. Once you've done, fill out the following form with the code you get on Google Authenticator and click on enter to enable TOTP-based two factor authentication." $k.Secret | html }}
|
||||
</p>
|
||||
<form class="ui form" action="/settings/2fa/totp" method="POST">
|
||||
{{ csrfGenerate .Context.User.ID }}
|
||||
{{ ieForm .Gin }}
|
||||
<div class="ui fluid action input">
|
||||
<input tabindex="1" type="text" placeholder="612 116" name="passcode">
|
||||
<button tabindex="2" class="ui right labeled icon blue button">
|
||||
<i class="right arrow icon"></i>
|
||||
{{ .T "Submit" }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{ else }}
|
||||
<div class="ui segment">
|
||||
<p>
|
||||
{{ if eq $e 1 }}
|
||||
{{ .T "At the moment you currently have set up Telegram Two Factor Authentication. Should you wish to disable it, please fill out the following form:" }}
|
||||
{{ else }}
|
||||
{{ .T "At the moment you currently have set up TOTP-based (Google Authenticator) Two Factor Authentication. Should you wish to disable it, please fill out the following form:" }}
|
||||
{{ end }}
|
||||
</p>
|
||||
<form action="/settings/2fa/disable" method="POST" class="centered">
|
||||
{{ csrfGenerate .Context.User.ID }}
|
||||
{{ ieForm .Gin }}
|
||||
<div class="ui fluid action input">
|
||||
<input tabindex="1" name="password" type="password" placeholder="Password">
|
||||
<button tabindex="2" type="submit" class="ui red right labeled icon button">
|
||||
<i class="ban icon"></i>
|
||||
{{ if eq $e 1 }}{{ .T "Disable Telegram 2FA" }}{{ else }}{{ .T "Disable TOTP-based 2FA" }}{{ end }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{ if eq $e 2 }}
|
||||
<div class="ui segment">
|
||||
<h1 class="ui header">
|
||||
{{ .T "Google Authenticator recovery keys" }}
|
||||
</h1>
|
||||
<p>
|
||||
{{ .T "These are the only thing that will let you get back into your Ripple account if you lose your device. Our suggestion is to paste them inside a document in your word processor (Microsoft Word, LibreOffice Writer), print them and store them in a safe place." }}
|
||||
</p>
|
||||
<div class="ui four column grid">
|
||||
{{ range getKeys .Context.User.ID }}
|
||||
<div class="ui column">
|
||||
{{ . }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
51
templates/settings/authorized_applications.html
Normal file
51
templates/settings/authorized_applications.html
Normal file
@@ -0,0 +1,51 @@
|
||||
{{/*###
|
||||
TitleBar=Authorized applications
|
||||
KyutGrill=settings2.jpg
|
||||
Include=menu.html
|
||||
MinPrivileges=2
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
{{ $ := . }}
|
||||
<div class="ui container">
|
||||
<div class="ui stackable grid">
|
||||
{{ template "settingsSidebar" . }}
|
||||
<div class="twelve wide column">
|
||||
<div class="ui segment">
|
||||
{{ .T "From here you can check all the applications you granted authorization to your account, and revoke their permissions if necessary." }}
|
||||
<div class="ui divider"></div>
|
||||
{{ $csrf := csrfGenerate .Context.User.ID }}
|
||||
{{ with .RequestInfo.apps }}
|
||||
<table class="ui very basic fixed table">
|
||||
{{ range . }}
|
||||
<tr>
|
||||
<td class="avatar-cell">
|
||||
{{ if .Avatar }}
|
||||
<img src="/static/oauth-apps/{{ .Avatar }}" class="ui tiny rounded image">
|
||||
{{ end }}
|
||||
</td>
|
||||
<td>
|
||||
<b>{{ .Name }}</b><br>{{ .Scopes $.Gin }}
|
||||
<div class="subtitle">{{ $.T "Authorization created %s" (timeFromTime .CreatedAt) | html }}</div>
|
||||
</td>
|
||||
<td class="right aligned">
|
||||
<div class="ui vertical buttons">
|
||||
<form method="POST" action="/settings/authorized_applications/revoke">
|
||||
<a class="ui labeled icon blue button" href="/u/{{ .Owner }}"><i class="user icon"></i>{{ $.T "Owner" }}</a>
|
||||
<input type="hidden" name="client_id" value="{{ .Client }}">
|
||||
{{ $csrf }}
|
||||
{{ ieForm $.Gin }}
|
||||
<button type="submit" class="ui labeled icon red button"><i class="remove icon"></i>{{ $.T "Revoke" }}</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</table>
|
||||
{{ else }}
|
||||
{{ $.T "... but it looks like you have none!" }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
35
templates/settings/avatar.html
Normal file
35
templates/settings/avatar.html
Normal file
@@ -0,0 +1,35 @@
|
||||
{{/*###
|
||||
Handler=/settings/avatar
|
||||
TitleBar=Avatar
|
||||
KyutGrill=settings2.jpg
|
||||
Include=menu.html
|
||||
MinPrivileges=2
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui stackable grid">
|
||||
{{ template "settingsSidebar" . }}
|
||||
<div class="twelve wide column">
|
||||
<div class="ui center aligned segment">
|
||||
<div class="ui compact segment" style="margin: 0 auto;">
|
||||
<img src="{{ config "AvatarURL" }}/{{ .Context.User.ID }}" alt="Avatar" id="avatar-img" style="max-width: 400px;">
|
||||
</div>
|
||||
<form action="/settings/avatar" method="post" enctype="multipart/form-data" class="little top margin">
|
||||
{{ ieForm .Gin }}
|
||||
<div class="ui buttons">
|
||||
<label tabindex="1" for="file" class="ui green labeled icon button">
|
||||
<i class="file icon"></i>
|
||||
{{ .T "Open File" }}
|
||||
</label>
|
||||
<button tabindex="2" type="submit" class="ui right labeled blue icon button">
|
||||
<i class="save icon"></i>
|
||||
{{ .T "Save" }}
|
||||
</button>
|
||||
</div>
|
||||
<input type="file" id="file" style="display:none" required accept="image/*" name="avatar">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
41
templates/settings/discord.html
Normal file
41
templates/settings/discord.html
Normal file
@@ -0,0 +1,41 @@
|
||||
{{/*###
|
||||
Handler=/settings/discord
|
||||
TitleBar=Discord donor
|
||||
KyutGrill=settings2.jpg
|
||||
Include=menu.html
|
||||
MinPrivileges=6
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui stackable grid">
|
||||
{{ template "settingsSidebar" . }}
|
||||
<div class="twelve wide column">
|
||||
<div class="ui segment">
|
||||
{{ $q := qb "SELECT discordid FROM discord_roles WHERE userid = ? LIMIT 1" .Context.User.ID }}
|
||||
{{ if $q.discordid }}
|
||||
<p>
|
||||
{{ .T "Your discord account has been linked to this Ripple account. <b>Welcome to the donors club and thank you for supporting us!</b> You have now access to the #donators text and voice channels on our official Discord server! You can also set a custom role name and username colour and change your nickname on Discord. If you want to change your nickname, you can use the <code>/nick</code> command. To set or edit your <b>custom role</b> name and colour, use the command <code>!role HEX_COLOUR ROLE_NAME</code>. You can pick your HEX colour <a href=\"http://www.colorpicker.com/\" target=\"_blank\">here</a>, it's the one that starts with '#'. You can change your role name and colour <b>whenever you want!</b>" | html }}
|
||||
</p>
|
||||
<h2 class="ui centered header">{{ .T "Thank you for supporting us and have fun on Ripple!" }}</h2>
|
||||
{{ else }}
|
||||
<p><b>{{ .T "Donors get special privileges on our Discord server too!" }}</b></p>
|
||||
<p>
|
||||
{{ .T "Discord is a chatroom with text and voice channels, bots and lots of other cool features. You can <b>download Discord for free <a href=\"http://discord.gg/\" target=\"_blank\">here</a></b> and you can <b>join our official Discord server <a href=\"%s\" target=\"_blank\">here</a></b>." (config "DiscordServer") | html }}
|
||||
</p>
|
||||
<p>{{ .T "Here's what you get if you link your Discord account:" }}</p>
|
||||
<ul class="ui list">
|
||||
<li>{{ .T "Access to /nick command, to change your Discord nickname" }}</li>
|
||||
<li>{{ .T "Access to #donators text and voice channels" }}</li>
|
||||
<li>{{ .T "Username on donors list" }}</li>
|
||||
<li>{{ .T "Custom role with custom username" }}</li>
|
||||
</ul>
|
||||
<p>{{ .T "To get these perks, first of all <a href=\"%s\" target=\"_blank\">join our Discord server</a>, then click this fancy button:" (config "DiscordServer") | html }}</p>
|
||||
<p class="centered">
|
||||
<a tabindex="1" class="ui red labeled icon button" href="{{ authCodeURL .Context.User.ID }}"><i class="heart icon"></i> {{ .T "Get Discord donor privileges" }}</a>
|
||||
</p>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
28
templates/settings/menu.html
Normal file
28
templates/settings/menu.html
Normal file
@@ -0,0 +1,28 @@
|
||||
{{/*###
|
||||
NoCompile=true
|
||||
*/}}
|
||||
{{ define "settingsSidebar" }}
|
||||
<div class="four wide column">
|
||||
<div class="ui fluid vertical menu">
|
||||
{{ navbarItem .Path (.T "Profile") "/settings" }}
|
||||
|
||||
{{ navbarItem .Path (.T "Userpage") "/settings/userpage" }}
|
||||
|
||||
{{ navbarItem .Path (.T "Avatar") "/settings/avatar" }}
|
||||
|
||||
{{ navbarItem .Path (.T "Password") "/settings/password" }}
|
||||
|
||||
{{ navbarItem .Path (.T "Two Factor Authentication") "/settings/2fa" }}
|
||||
|
||||
{{ navbarItem .Path (.T "Authorized applications") "/settings/authorized_applications" }}
|
||||
|
||||
{{/* Stuff for donators */}}
|
||||
{{ if has .Context.User.Privileges 4 }}
|
||||
{{ navbarItem .Path (.T "Discord donor") "/settings/discord" }}
|
||||
|
||||
{{ navbarItem .Path (.T "Profile background") "/settings/profbackground" }}
|
||||
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
36
templates/settings/password.html
Normal file
36
templates/settings/password.html
Normal file
@@ -0,0 +1,36 @@
|
||||
{{/*###
|
||||
TitleBar=Password
|
||||
KyutGrill=settings2.jpg
|
||||
Include=menu.html
|
||||
MinPrivileges=2
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui stackable grid">
|
||||
{{ template "settingsSidebar" . }}
|
||||
<div class="twelve wide column">
|
||||
<div class="ui segment">
|
||||
<form class="ui form" method="post">
|
||||
<div class="field">
|
||||
<label>{{ .T "Email" }}</label>
|
||||
<input tabindex="1" type="email" name="email" value="{{ or .FormData.email .RequestInfo.email }}" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>{{ .T "New password (leave blank if you don't want to change it)" }}</label>
|
||||
<input tabindex="2" type="password" name="newpassword" value="{{ .FormData.newpassword }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>{{ .T "Current password" }}</label>
|
||||
<input tabindex="3" type="password" name="currentpassword" required>
|
||||
</div>
|
||||
{{ csrfGenerate .Context.User.ID }}
|
||||
{{ ieForm .Gin }}
|
||||
<div style="text-align: right">
|
||||
<button tabindex="4" type="submit" class="ui blue button">{{ .T "Save" }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
75
templates/settings/profbackground.html
Normal file
75
templates/settings/profbackground.html
Normal file
@@ -0,0 +1,75 @@
|
||||
{{/*###
|
||||
Handler=/settings/profbackground
|
||||
TitleBar=Profile background
|
||||
KyutGrill=settings2.jpg
|
||||
Include=menu.html
|
||||
MinPrivileges=6
|
||||
AdditionalJS=https://cdnjs.cloudflare.com/ajax/libs/jquery-minicolors/2.2.4/jquery.minicolors.min.js
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui stackable grid">
|
||||
{{ template "settingsSidebar" . }}
|
||||
<div class="twelve wide column">
|
||||
<div class="ui center aligned segment">
|
||||
{{ $d := qb "SELECT type, value FROM profile_backgrounds WHERE uid = ? LIMIT 1" .Context.User.ID }}
|
||||
{{ $type := or $d.type.Int -1 }}
|
||||
{{ $value := or $d.value.String "" }}
|
||||
<p>
|
||||
<select class="ui dropdown" id="background-type" name="type">
|
||||
<option value="">{{ .T "Background type" }}</option>
|
||||
<option value="0">{{ .T "None" }}</option>
|
||||
<option value="1"{{ if eq $type 1 }} selected{{ end }}>{{ .T "Image" }}</option>
|
||||
<option value="2"{{ if eq $type 2 }} selected{{ end }}>{{ .T "Solid colour" }}</option>
|
||||
</select>
|
||||
</p>
|
||||
<div class="ui compact segment" id="image-background" style="margin: 0 auto; max-width: 400px; max-height: 700px;" data-type="1"{{ if ne $type 1 }} hidden{{ end }}>
|
||||
{{ if and (eq $type 1) $value }}
|
||||
<img src="/static/profbackgrounds/{{ $value }}">
|
||||
{{ else }}
|
||||
No image selected
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ $csrf := csrfGenerate .Context.User.ID }}
|
||||
<form action="/settings/profbackground/0" method="post" class="little top margin ui form" data-type="0"{{ if and (ne $type 0) }} hidden{{ end }}>
|
||||
{{ $csrf }}
|
||||
{{ ieForm .Gin }}
|
||||
<button type="submit" class="ui right labeled blue icon button">
|
||||
<i class="save icon"></i>
|
||||
Save
|
||||
</button>
|
||||
</form>
|
||||
<form action="/settings/profbackground/1" method="post" enctype="multipart/form-data" class="little top margin ui form" data-type="1"{{ if ne $type 1 }} hidden{{ end }}>
|
||||
{{ $csrf }}
|
||||
<div class="ui buttons">
|
||||
<label for="file" class="ui green labeled icon button">
|
||||
<i class="file icon"></i>
|
||||
{{ .T "Open File" }}
|
||||
</label>
|
||||
{{ ieForm .Gin }}
|
||||
<button type="submit" class="ui right labeled blue icon button">
|
||||
<i class="save icon"></i>
|
||||
{{ .T "Save" }}
|
||||
</button>
|
||||
</div>
|
||||
<input type="file" id="file" style="display:none" required accept="image/*" name="value">
|
||||
</form>
|
||||
<form action="/settings/profbackground/2" method="post" class="little top margin ui form" data-type="2"{{ if ne $type 2 }} hidden{{ end }}>
|
||||
{{ $csrf }}
|
||||
<div class="ui compact segment" style="margin: 0 auto;">
|
||||
<input type="text"{{ if and (eq $type 2) $value }} value="{{ $value }}"{{ end }} id="colorpicker" name="value">
|
||||
</div>
|
||||
<p class="little top margin">
|
||||
{{ ieForm .Gin }}
|
||||
<button type="submit" class="ui right labeled blue icon button">
|
||||
<i class="save icon"></i>
|
||||
Save
|
||||
</button>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-minicolors/2.2.4/jquery.minicolors.min.css">
|
||||
{{ end }}
|
91
templates/settings/profile.html
Normal file
91
templates/settings/profile.html
Normal file
@@ -0,0 +1,91 @@
|
||||
{{/*###
|
||||
Handler=/settings
|
||||
TitleBar=Settings
|
||||
KyutGrill=settings2.jpg
|
||||
Include=menu.html
|
||||
MinPrivileges=2
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui stackable grid">
|
||||
{{ template "settingsSidebar" . }}
|
||||
<div class="twelve wide column">
|
||||
<div class="ui segment">
|
||||
<form class="ui form" method="post">
|
||||
{{ $d := .Get "users/self/settings" }}
|
||||
<h3 class="ui header">{{ .T "General" }}</h3>
|
||||
<div class="field">
|
||||
<label><a href="https://support.ripple.moe">{{ .T "Username" }}</a></label>
|
||||
<input type="text" value="{{ .Context.User.Username }}" disabled>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>
|
||||
<a href="/settings/password">{{ .T "Email address" }}</a>
|
||||
</label>
|
||||
<input type="email" value="{{ $d.email }}" placeholder="{{ .T "Email address" }}" required disabled>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>{{ .T "Alternative username (cannot be used for login)" }}</label>
|
||||
<input type="text" name="username_aka" value="{{ $d.username_aka }}" placeholder="{{ .T "Also known as..." }}">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>{{ .T "Favourite mode" }}</label>
|
||||
<select class="ui dropdown" name="favourite_mode" data-cast="int">
|
||||
{{ range $k, $v := modes }}
|
||||
<option value="{{ $k }}" {{ if eq (int $d.favourite_mode) $k }}selected{{ end }}>{{ $v }}</a>
|
||||
{{ end }}
|
||||
</select>
|
||||
</div>
|
||||
{{ if has .Context.User.Privileges 4 }}
|
||||
<h3 class="ui header">{{ .T "Custom badge" }}</h3>
|
||||
<div class="ui warning message">
|
||||
{{ .T "<b>Do not use offensive badges and do not pretend to be someone else with your badge.</b> If you abuse the badges system, you'll be silenced and you won't be able to edit your custom badge anymore." | html}}
|
||||
</div>
|
||||
<div class="ui toggle checkbox">
|
||||
<input type="checkbox" name="custom_badge.show" {{ if $d.custom_badge.show }}checked{{ end }}>
|
||||
<label>{{ .T "Enable" }}</label>
|
||||
</div>
|
||||
<div id="custom-badge-fields" {{ if not $d.custom_badge.show }}style="display: none"{{ end }} class="little top margin">
|
||||
<p><a href="http://semantic-ui.com/elements/icon.html">{{ .T "Icon reference" }}</a></p>
|
||||
<div class="ui two column center aligned grid" style="margin-top: 0">
|
||||
<div class="column">
|
||||
<i class="circular {{ faIcon $d.custom_badge.icon }} big icon" id="badge-icon"></i><br>
|
||||
<b id="badge-name">{{ $d.custom_badge.name }}</b>
|
||||
</div>
|
||||
<div class="column">
|
||||
<p><input type="text" name="custom_badge.icon" placeholder="plane, left chevron, hand spock..." value="{{ $d.custom_badge.icon }}"></p>
|
||||
<p><input type="text" name="custom_badge.name" placeholder="{{ .T "Dinosaur, oompa-loompa, cool guy..." }}" value="{{ $d.custom_badge.name }}"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
<h3 class="ui header">{{ .T "Playstyle" }}</h3>
|
||||
<div class="ui three column grid" id="checkbox-grid">
|
||||
{{ $ := . }}
|
||||
{{ range $k, $v := styles }}
|
||||
<div class="column">
|
||||
{{ $checked := band (int $d.play_style) (shift 1 $k) }}
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" data-sv="{{ shift 1 $k }}" {{ if $checked }}checked{{ end }}>
|
||||
<label>{{ $.T $v }}</label>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
<h3 class="ui header">{{ .T "Preferences" }}</h3>
|
||||
{{ $ds := band .ClientFlags 1 }}
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" {{ if $ds }}checked{{ end }} id="dark-site">
|
||||
<label>{{ .T "Dark site" }}</label>
|
||||
</div>
|
||||
<div class="ui divider"></div>
|
||||
<div style="text-align: right">
|
||||
<button type="submit" class="ui blue button">{{ .T "Save" }}</button>
|
||||
</div>
|
||||
{{ ieForm .Gin }}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
33
templates/settings/userpage.html
Normal file
33
templates/settings/userpage.html
Normal file
@@ -0,0 +1,33 @@
|
||||
{{/*###
|
||||
Handler=/settings/userpage
|
||||
TitleBar=Userpage
|
||||
KyutGrill=settings2.jpg
|
||||
Include=menu.html
|
||||
MinPrivileges=2
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
{{ $ := . }}
|
||||
<div class="ui container">
|
||||
<div class="ui stackable grid">
|
||||
{{ template "settingsSidebar" . }}
|
||||
<div class="twelve wide column">
|
||||
<div class="ui segment">
|
||||
{{ $f := ieForm .Gin }}
|
||||
{{ with .Get "users/userpage?id=%d" .Context.User.ID }}
|
||||
<form class="ui form" method="post">
|
||||
<textarea tabindex="1" class="monospace" name="data">{{ .userpage }}</textarea>
|
||||
<p><a href="https://docs.ripple.moe/docs/misc/hanayo_bbcode" target="_blank">{{ $.T "BBCode syntax reference" }}</a></p>
|
||||
<div class="ui divider"></div>
|
||||
<div class="ui segment twemoji" id="userpage-content">{{ parseUserpage .userpage | html }}</div>
|
||||
<div class="ui divider"></div>
|
||||
<div style="text-align: right">
|
||||
<button type="submit" class="ui blue button">{{ $.T "Save" }}</button>
|
||||
</div>
|
||||
{{ $f }}
|
||||
</form>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
18
templates/simplepag.html
Normal file
18
templates/simplepag.html
Normal file
@@ -0,0 +1,18 @@
|
||||
{{ define "simplepag" }}
|
||||
<tr>
|
||||
<th colspan="{{ . }}">
|
||||
<div class="simplepag">
|
||||
<div class="ui left floated pagination menu">
|
||||
<a class="icon item">
|
||||
<i class="left chevron icon"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="ui right floated pagination menu">
|
||||
<a class="icon item">
|
||||
<i class="right chevron icon"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
{{ end }}
|
171
templates/support.html
Normal file
171
templates/support.html
Normal file
@@ -0,0 +1,171 @@
|
||||
{{/*###
|
||||
Handler=/donate
|
||||
TitleBar=Support Ripple
|
||||
KyutGrill=donate2.png
|
||||
AdditionalJS=https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/9.0.0/nouislider.min.js
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
{{ $global := .Context }}
|
||||
{{ $ := $ }}
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/noUiSlider/9.0.0/nouislider.min.css" rel="stylesheet" type="text/css">
|
||||
<div class="ui container">
|
||||
{{ $ief := ieForm .Gin }}
|
||||
{{ with .Get "users/self/donor_info" }}
|
||||
{{ if .has_donor }}
|
||||
<div class="ui segment">
|
||||
<h1 class="ui center aligned header no bottom margin" style="margin: 0 auto; display: table;">
|
||||
<i class="red heart icon" style="font-size: 90%;"></i> <div class="content">{{ $.T "You are a donor!" }}</div>
|
||||
</h1>
|
||||
<div class="ui centered subtitle" style="font-size:1.2rem;">
|
||||
{{ $.T "Your donor expires <b>%s</b>. No need to feel guilty for not having donated!" (time .expiration) | html }} <3
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
<div class="ui segments">
|
||||
<div class="ui segment">
|
||||
<h2 class="ui header">
|
||||
{{ $.T "Did you know?" }}
|
||||
<div class="sub header">
|
||||
{{ if .has_donor }}{{ $.T "(Probably.)" }}{{ else }}{{ $.T "(Probably not.)" }}{{ end }}
|
||||
</div>
|
||||
</h2>
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<h3 class="ui header no top margin">
|
||||
<i class="money icon"></i><div class="content">{{ $.T "Ripple is not cheap to run." }}</div>
|
||||
</h3>
|
||||
<blockquote>
|
||||
{{ $.T "While we provide this service for free, we still have to pay for it, and if we always took the money out of our own pockets, 1. we would be broke, 2. we wouldn't be able to upgrade our hardware to accomodate our users. While we do have loads of software optimisations that allow us to have Ripple run crazy fast while still being on not so high-end hardware, the more users we have, the higher-end our hardware needs to be. So we are asking you for help on this :)." }}
|
||||
</blockquote>
|
||||
<h3 class="ui header">
|
||||
<i class="book icon"></i><div class="content">{{ $.T "We are still students." }}</div>
|
||||
</h3>
|
||||
<blockquote>
|
||||
{{ $.T "Ripple developers, and most of the Ripple staff, do not have a day job. This means that we get most of our income as students from doing small jobs as \"freelancers\" every so often, or, you know, allowance." }}
|
||||
</blockquote>
|
||||
<h3 class="ui header">
|
||||
<i class="mouse pointer icon"></i><div class="content">{{ $.T "We do not have ads. And never will." }}</div>
|
||||
</h3>
|
||||
<blockquote>
|
||||
{{ $.T "You may have adblock enabled and have not noticed, but we don't have ads anywhere on our website. We believe ads are bad, as they can be very annoying to you and that you would rather spend a few bucks to help us rather than watch annoying ads all the time." }}
|
||||
</blockquote>
|
||||
<h3 class="ui header">
|
||||
<i class="wizard icon"></i><div class="content">{{ $.T "We love picking random icons from our icon library." }}</div>
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<h1 class="ui center aligned header">
|
||||
{{ $.T "So what can you do?" }}
|
||||
<div class="sub header">
|
||||
{{ if .has_donor }}{{ $.T "Well, you can give us even more money." }}{{ else }}{{ $.T "Well, you can give us money." }}{{ end }}
|
||||
</div>
|
||||
</h1>
|
||||
<h4 class="ui horizontal divider header">
|
||||
{{ $.T "Here's what you get:" }}
|
||||
</h4>
|
||||
<div class="ui internally celled stackable grid">
|
||||
<div class="row">
|
||||
<div class="four wide column">
|
||||
<h3 class="ui header">{{ $.T "Yellow username" }}</h3>
|
||||
{{ $.T "Just like in osu!, you get a <b>shiny yellow username</b> in the in-game chat to show everyone you're a really cool dude who has helped us pay the server bills." | html }}
|
||||
</div>
|
||||
<div class="four wide column">
|
||||
<h3 class="ui header">{{ $.T "Donor badge" }}</h3>
|
||||
{{ $.T "Again, just like in osu!, you will get a <b>donor badge</b> on your profile, to show everyone you're supporting us." | html }}
|
||||
</div>
|
||||
<div class="four wide column">
|
||||
<h3 class="ui header">{{ $.T "Custom badge editor" }}</h3>
|
||||
{{ $.T "You get to be able to create your <b>own personal badge</b>, with custom text and icon, to show off on your profile! Let the world know you're an anchor. Or prank people showing a spinnin' wheel with \"Loading...\"! Up to you." | html }}
|
||||
</div>
|
||||
<div class="four wide column">
|
||||
<h3 class="ui header">{{ $.T "Friends ranking" }}</h3>
|
||||
{{ $.T "<b>Competing with friends</b> is really cool, you can play on the leaderboard with someone more or less on your level, without getting crippling depression and RSI for not beating that pro!" | html }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="four wide column">
|
||||
<h3 class="ui header">{{ $.T "Discord privileges" }}</h3>
|
||||
{{ $.T "You'll get exclusive access to the <b>\"#donators\"</b> text and voice channels, you'll be able to change your discord nickname and you'll get a custom role with custom username colour!" | html }}
|
||||
</div>
|
||||
<div class="four wide column">
|
||||
<h3 class="ui header">{{ $.T "Profile background" }}</h3>
|
||||
{{ $.T "Think about <b>spicing your profile up with some eggplants</b>? Got you covered! Having donor privileges, you get to be able to change your profile background." | html }}
|
||||
</div>
|
||||
<div class="four wide column">
|
||||
<h3 class="ui header">{{ $.T "Account wipe" }}</h3>
|
||||
{{ $.T "Want to start over one more time? With donor you can! Normally you can only <a href='https://support.ripple.moe' target='_blank'>request an account wipe</a> once, but having donated you'll be able to do it once again." | html }}
|
||||
</div>
|
||||
<div class="four wide column">
|
||||
<h3 class="ui header">{{ $.T "More to come!" }}</h3>
|
||||
{{ $.T "<b>Who knows</b> what we could implement next? You could be able to do even <i>more</i> stuff for donors once we implement it." | html }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{ if $global.User.ID }}
|
||||
<h4 class="ui horizontal divider header">
|
||||
{{ $.T "And this is how you pay" }}
|
||||
</h4>
|
||||
<p>
|
||||
{{ $.T "You may donate through either <b>PayPal</b> (or credit/debit card linked to PayPal) or <b>Bitcoin</b>. Use the slider below to choose the amount of months you'd like to have the donor benefits, and the cost will be instantly calculated. Remember that if, for instance, you choose to donate € 4 instead of € 3.51, you will only be given one donor month." | html }}
|
||||
</p>
|
||||
<div id="months-slider" style="margin: 0 auto; max-width: 500px"></div>
|
||||
<br>
|
||||
<div id="cost" class="centered"><b>{{ $.T "Loading..." }}</b></div>
|
||||
<br>
|
||||
<div class="ui internally celled two column center aligned stackable grid">
|
||||
<div class="column">
|
||||
<h2 class="ui header">
|
||||
<i class="paypal icon"></i>
|
||||
{{ $.T "PayPal" }}
|
||||
</h2>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_self">
|
||||
<input type="hidden" name="on0" value="Period">
|
||||
<input type="hidden" name="os0" value="1 month">
|
||||
{{ range _range 24 }}
|
||||
{{ $months := plus (float .) 1 }}
|
||||
<input type="hidden" name="option_select{{ . }}" value="{{ $months }} month{{ if . }}s{{ end }}">
|
||||
<input type="hidden" name="option_amount{{ . }}" value="{{ calculateDonorPrice $months }}">
|
||||
{{ end }}
|
||||
<input type="hidden" name="on1" value="Ripple user to give donor">
|
||||
<input type="hidden" name="custom" value="username={{ $global.User.Username }}" id="ipn-username">
|
||||
<input type="hidden" name="amount" value="{{ calculateDonorPrice 1 }}" id="paypal-amt">
|
||||
<div class="ui fluid labeled action input">
|
||||
<div class="ui label">
|
||||
{{ $.T "User:" }}
|
||||
</div>
|
||||
<input name="os1" type="text" placeholder="{{ $.T "User" }}" value="{{ $global.User.Username }}" id="username-input">
|
||||
<button type="submit" class="ui blue button">{{ $.T "Submit" }}</button>
|
||||
</div>
|
||||
{{ $ief }}
|
||||
<input type="hidden"
|
||||
name="business" value="me@nyodev.xyz">
|
||||
<input type="hidden" name="cmd" value="_xclick">
|
||||
<input type="hidden" name="lc" value="GB">
|
||||
<input type="hidden" name="no_note" value="0">
|
||||
<input type="hidden" name="currency_code" value="EUR">
|
||||
<img alt="" border="0" src="https://www.paypalobjects.com/it_IT/i/scr/pixel.gif" width="1" height="1">
|
||||
</form>
|
||||
</div>
|
||||
<div class="column">
|
||||
<h2 class="ui header">
|
||||
<i class="bitcoin icon"></i>
|
||||
{{ $.T "Bitcoin" }}
|
||||
</h2>
|
||||
<p><b>{{ $.T "Send %s BTC to this Bitcoin address:" "<span id=\"bitcoin-amt\"></span>" | html }}</b></p>
|
||||
<p><code>{{ getBitcoinAddress }}</code></p>
|
||||
<p>{{ $.T "Afterwards, <b>please send an email to <a href=\"mailto:howl@ripple.moe\">howl@ripple.moe</a></b> containing the transaction hash!" | html }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="ui horizontal divider header">
|
||||
{{ $.T "I've donated, now what?" }}
|
||||
</h4>
|
||||
{{ $.T "You'll have to wait until we verify and process your payment. It can take up to <b>12 hours</b>. If 12 hours have passed and you still haven't received your Donor tag, contact a <b>Dev/Community Manager</b> in our Discord server or send an email to <b><a href=\"mailto:support@ripple.moe\">support@ripple.moe</a></b>. Once we have processed your payment, you'll receive an <b>email</b> to the address you've used to sign up and you'll get <b>all the donor privileges, except the Discord ones</b>. To get the Discord donor privileges, go <a href=\"/settings/discord\">here</a>." | html }}
|
||||
{{ else }}
|
||||
<div class="ui divider"></div>
|
||||
<h1 class="ui center aligned header">{{ $.T "Please log in to get supporter" }}</h1>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
103
templates/team.html
Normal file
103
templates/team.html
Normal file
@@ -0,0 +1,103 @@
|
||||
{{/*###
|
||||
Handler=/team
|
||||
TitleBar=Team
|
||||
Include=user_group.html
|
||||
KyutGrill=team2.jpg
|
||||
*/}}
|
||||
{{ define "tpl" }}
|
||||
<div class="ui container">
|
||||
<div class="ui segments">
|
||||
<div class="ui center aligned segment">
|
||||
<h3>{{ .T "This is a list of the wonderful people who keep Ripple up and running and deal with its community." }}</h3>
|
||||
</div>
|
||||
<div class="ui center aligned segment">
|
||||
<h1 class="ui heading">{{ .T "Community Managers" }}</h1>
|
||||
<p>
|
||||
{{ .T "Community Managers deal with bans, silences, name changes and pretty much everything that has to do with the community." }}<br>
|
||||
{{ .T "They take care of our Discord server and reply to emails sent to the support services (email and support.ripple.moe). Community Managers have a red name in the in-game chat." | html }}
|
||||
</p>
|
||||
{{ template "userGroup" (.Get "badges/members?id=%d" 4) }}
|
||||
</div>
|
||||
<div class="ui center aligned segment">
|
||||
<h1 class="ui heading">{{ .T "Developers" }}</h1>
|
||||
<p>
|
||||
{{ .T "Developers add new features to the server, squash bugs, keep the server up and running and take care of its maintenance." }}<br>
|
||||
{{ .T "They don't do anything related to the community. Developers have a blue name in the in-game chat." }}
|
||||
</p>
|
||||
{{ template "userGroup" (.Get "badges/members?id=%d" 2) }}
|
||||
</div>
|
||||
<div class="ui center aligned segment">
|
||||
<h1 class="ui heading">{{ .T "Chat Moderators" }}</h1>
|
||||
<p>
|
||||
{{ .T "Chat moderators manage the chat to make sure The Law™ (the rules) is respected." | html }}
|
||||
</p>
|
||||
{{ template "userGroup" (.Get "badges/members?id=%d" 30) }}
|
||||
</div>
|
||||
<div class="ui center aligned segment">
|
||||
<h1 class="ui heading">{{ .T "BATs" }}</h1>
|
||||
<p>
|
||||
{{ .T "BATs play beatmaps in the ranking queue and decide whether they are good enough to be ranked or not." }}
|
||||
</p>
|
||||
{{ template "userGroup" (.Get "badges/members?id=%d" 5) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui segments">
|
||||
<div class="ui center aligned segment">
|
||||
<h1 class="ui heading">{{ .T "Special thanks" }}</h1>
|
||||
<p>{{ .T "Here's a list of people who helped with Ripple." }}</p>
|
||||
</div>
|
||||
<div class="ui segment">
|
||||
<ul class="ui list">
|
||||
<li>
|
||||
{{ .T "<b>Franc[e]sco/lolisamurai</b>, for <a href='https://github.com/Francesco149/oppai'>oppai</a>, used as standard pp calculator." | html }}<br>
|
||||
oppai is licensed under GPL v3. Our implementation can be found <a href="https://zxq.co/ripple/lets/src/master/pp/rippoppai.py">here</a>.
|
||||
</li>
|
||||
<li>
|
||||
{{ .T "<b>Tom94</b>, for <a href='https://github.com/ppy/osu-performance'>osu-performance</a>, used as a reference for our mania pp calculator." | html }}<br>
|
||||
osu-performance is licensed under AGPL v3. Our implementation can be found <a href="https://zxq.co/ripple/lets/src/master/pp/wifipiano2.py">here</a>.
|
||||
</li>
|
||||
<li>
|
||||
{{ .T "<b>Sunpy</b>, for <a href='https://github.com/osufx/catch-the-pp'>catch-the-pp</a>, used as catch the beat pp calculator." | html }}<br>
|
||||
catch-the-pp is licensed under GPL v3. Our implementation can be found <a href="https://github.com/osuripple/catch-the-pp">here</a>.
|
||||
</li>
|
||||
<li>
|
||||
{{ .T "<b>jrosdahl</b>, for <a href='https://github.com/jrosdahl/miniircd'>miniircd</a>, used as a base for our IRC server." | html }}<br>
|
||||
miniircd is licensed under GPL v2. Our implementation can be found <a href="https://zxq.co/ripple/pep.py/src/master/irc/ircserver.py">here</a>.
|
||||
</li>
|
||||
<li>{{ .T "<b>Avail</b>, for having hosted Ripple on his server." | html }}</li>
|
||||
<li>{{ .T "<b>Angela Guerra</b>, for designing the Ripple logo." | html }}</li>
|
||||
<li>{{ .T "<b><a id='everyone' class='clickable'>Everyone</a></b> who has supported the Ripple project by donating or inviting other people." | html }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{{ $ := . }}
|
||||
{{ .T "Looking for how you should contact our team? Check out <a href='https://support.ripple.moe'>this page</a>." | html }}
|
||||
<div class="ui modal">
|
||||
<div class="header"><h2 class="ui header">{{ .T "They told me these are very cool people." }}</h2></div>
|
||||
{{ with .Get "users?sort=donor_expire,desc&l=52" }}
|
||||
<div class="content">
|
||||
<div class="ui four column grid">
|
||||
{{ range .users }}
|
||||
<div class="column">
|
||||
<h4 class="ui image header">
|
||||
<img src="{{ config "AvatarURL" }}/{{ .id }}" class="ui micro rounded image">
|
||||
<div class="content">
|
||||
<a href="/u/{{ .id }}">{{ .username }}</a>
|
||||
</div>
|
||||
</h4>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
<!-- Probably most shit coded part of Hanayo -->
|
||||
<br>
|
||||
<div class="centered">
|
||||
<b>{{ $.T "And more..." }}</b><br><br>
|
||||
<b>{{ $.T "Do you want to be in this list?" }}</b><br>
|
||||
<a href="/donate"><b>{{ $.T "Support us with a donation!" }}</b></a><br>
|
||||
<i>{{ $.T "(You get other cool perks too)" }}</i>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
59
templates/user_group.html
Normal file
59
templates/user_group.html
Normal file
@@ -0,0 +1,59 @@
|
||||
{{/*###
|
||||
NoCompile=true
|
||||
*/}}
|
||||
{{ define "userGroup" }}
|
||||
{{ with . }}
|
||||
<div class="ui five column center aligned stackable grid">
|
||||
{{ $teamJSON := teamJSON }}
|
||||
{{ range .members }}
|
||||
{{/* ignore fokabot */}}
|
||||
{{ if ne (int .id) 999 }}
|
||||
{{ $tj := index $teamJSON (print .id)}}
|
||||
<div class="column">
|
||||
<div class="ui left aligned fluid card">
|
||||
<div class="image">
|
||||
<img src="{{ config "AvatarURL" }}/{{ .id }}" alt="Avatar">
|
||||
</div>
|
||||
<div class="content">
|
||||
<a class="header" href="/u/{{ .id }}">{{ country .country false }}{{ .username }}</a>
|
||||
{{ with $tj.real_name }}
|
||||
<div class="meta">
|
||||
<a>{{ . }}</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ with $tj.role }}
|
||||
<div class="description">
|
||||
{{ . }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="extra content">
|
||||
<div title="Registered">
|
||||
<i class="sign in icon"></i>
|
||||
{{ time .registered_on }}
|
||||
</div>
|
||||
<div title="Latest activity">
|
||||
<i class="sign out icon"></i>
|
||||
{{ time .latest_activity }}
|
||||
</div>
|
||||
</div>
|
||||
{{ if or $tj.twitter $tj.mail $tj.github }}
|
||||
<div class="extra content">
|
||||
<div class="center aligned">
|
||||
{{ range $k, $v := $tj }}
|
||||
{{ if and $v (in $k "github" "twitter" "mail") }}
|
||||
<a href="{{ servicePrefix $k }}{{ $v }}" title="{{ capitalise $k }}">
|
||||
<i class="{{ $k }} icon"></i>
|
||||
</a>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
Reference in New Issue
Block a user