mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[chore] Refactor HTML templates and CSS (#2480)
* [chore] Refactor HTML templates and CSS * eslint * ignore "Local" * rss tests * fiddle with OG just a tiny bit * dick around with polls a bit more so SR stops saying "clickable" * remove break * oh lord * don't lazy load avatar * fix ogmeta tests * clean up some cruft * catch remaining calls to c.HTML * fix error rendering + stack overflow in tag * allow templating attributes * fix indent * set aria-hidden on status complementary content, since it's already present in the label anyway * tidy up templating calls a little * try to make styling a bit more consistent + readable * fix up some remaining CSS issues * fix up reports
This commit is contained in:
@@ -17,23 +17,27 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{ template "header.tmpl" .}}
|
||||
{{- with . }}
|
||||
<main>
|
||||
<section>
|
||||
<h1>404: Page Not Found</h1>
|
||||
<p>
|
||||
GoToSocial only serves Public statuses via the web.
|
||||
If you reached this page by clicking on a status link,
|
||||
it's possible that the status is not Public, has been
|
||||
deleted by the author, you don't have permission to see
|
||||
it, or it just doesn't exist at all.
|
||||
</p>
|
||||
<p>
|
||||
If you believe this 404 was an error, you can contact
|
||||
the instance admin. Provide them with the following request
|
||||
Request ID: <code>{{.requestID}}</code>.
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h1>404: Not Found</h1>
|
||||
<p>
|
||||
GoToSocial only serves Public statuses via the web.
|
||||
</p>
|
||||
<p>
|
||||
If you reached this page by clicking on a status link,
|
||||
it's likely that the status is not Public. You can try
|
||||
entering the status URL in your client's search bar,
|
||||
to view the status from your account. If that doesn't
|
||||
work, it's possible that the status has been deleted by
|
||||
the author, you don't have permission to view it, or it
|
||||
doesn't exist at all.
|
||||
</p>
|
||||
<p>
|
||||
If you believe this 404 was an error, you can contact
|
||||
the instance admin. Provide them with the following
|
||||
request ID: <code>{{- .requestID -}}</code>.
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
{{ template "footer.tmpl" .}}
|
||||
{{- end }}
|
@@ -17,105 +17,133 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{ template "header.tmpl" .}}
|
||||
<main>
|
||||
<section class="about">
|
||||
<h1>About</h1>
|
||||
<div>
|
||||
{{.instance.Description |noescape}}
|
||||
</div>
|
||||
{{- define "description" -}}
|
||||
{{- if .instance.Description }}
|
||||
{{ .instance.Description | noescape }}
|
||||
{{- else }}
|
||||
<p>No description has yet been set for this instance.<p>
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
<div>
|
||||
<h2 id="languages">Languages</h2>
|
||||
<p>
|
||||
{{ if .languages }}
|
||||
This instance prefers the following languages:
|
||||
<ol>
|
||||
{{range .languages}}
|
||||
<li>{{.}}</li>
|
||||
{{end}}
|
||||
</ol>
|
||||
{{ else }}
|
||||
This instance does not have any preferred languages.
|
||||
{{ end }}
|
||||
</p>
|
||||
</div>
|
||||
{{- define "registrationLimits" -}}
|
||||
{{- if .instance.Registrations -}}
|
||||
Registration is enabled; new signups can be submitted to this instance.<br/>
|
||||
{{- if .instance.ApprovalRequired -}}
|
||||
Admin approval is required for new registrations.
|
||||
{{- else -}}
|
||||
Admin approval is not required for registrations; new signups will be automatically approved (pending email confirmation).
|
||||
{{- end -}}
|
||||
{{- else -}}
|
||||
Registration is disabled; new signups are currently closed for this instance.
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
<div>
|
||||
<h2 id="contact">Admin Contact</h2>
|
||||
{{if .instance.ContactAccount}}
|
||||
<a href="{{.instance.ContactAccount.URL}}" class="account-card">
|
||||
<img class="avatar" src="{{.instance.ContactAccount.Avatar}}" alt="" />
|
||||
<h3>
|
||||
{{if .instance.ContactAccount.DisplayName}}{{emojify .instance.ContactAccount.Emojis (escape .instance.ContactAccount.DisplayName)}}{{else}}{{.instance.ContactAccount.Username}}{{end}}
|
||||
</h3>
|
||||
<span>@{{.instance.ContactAccount.Username}}</span>
|
||||
</a><br />
|
||||
{{end}}
|
||||
{{if .instance.Email}}
|
||||
Email: <a href="mailto:{{.instance.Email}}">{{.instance.Email}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
{{- define "customCSSLimits" -}}
|
||||
{{- if .instance.Configuration.Accounts.AllowCustomCSS -}}
|
||||
Users are allowed to set <a href="https://docs.gotosocial.org/en/latest/user_guide/custom_css/" target="_blank" rel="noopener noreferrer">Custom CSS</a> for their profiles.
|
||||
{{- else -}}
|
||||
<a href="https://docs.gotosocial.org/en/latest/user_guide/custom_css/" target="_blank" rel="noopener noreferrer">Custom CSS</a> is not enabled for user profiles.
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
<div>
|
||||
<h2 id="rules">Rules</h2>
|
||||
<ol>
|
||||
{{range .instance.Rules}}
|
||||
<li>{{.Text}}</li>
|
||||
{{end}}
|
||||
</ol>
|
||||
</div>
|
||||
{{- define "statusLimits" -}}
|
||||
Statuses can contain up to
|
||||
{{- .instance.Configuration.Statuses.MaxCharacters }} characters, and
|
||||
{{- .instance.Configuration.Statuses.MaxMediaAttachments }} media attachments.
|
||||
{{- end -}}
|
||||
|
||||
<div>
|
||||
<h2 id="features">Features</h2>
|
||||
<ul>
|
||||
<li>
|
||||
Registration is
|
||||
{{if .instance.Registrations}}
|
||||
enabled{{if .instance.ApprovalRequired}}, but requires admin approval{{end}}.
|
||||
{{else}}
|
||||
disabled.
|
||||
{{end}}
|
||||
</li>
|
||||
{{if .instance.Configuration.Accounts.AllowCustomCSS}}
|
||||
<li>
|
||||
Users are allowed to set <a href="https://docs.gotosocial.org/en/latest/user_guide/custom_css/"
|
||||
target="_blank" rel="noopener noreferrer">Custom CSS</a> for their profiles.
|
||||
</li>
|
||||
{{end}}
|
||||
<li>
|
||||
Toots can contain up to {{.instance.Configuration.Statuses.MaxCharacters}} characters and
|
||||
{{.instance.Configuration.Statuses.MaxMediaAttachments}} media attachments.
|
||||
</li>
|
||||
<li>
|
||||
Polls can have up to {{.instance.Configuration.Polls.MaxOptions}} options, with
|
||||
{{.instance.Configuration.Polls.MaxCharactersPerOption}} characters each.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{{- define "pollLimits" -}}
|
||||
Polls can have up to
|
||||
{{- .instance.Configuration.Polls.MaxOptions }} options, with
|
||||
{{- .instance.Configuration.Polls.MaxCharactersPerOption }} characters per option.
|
||||
{{- end -}}
|
||||
|
||||
<div>
|
||||
<h2 id="moderated-servers">Moderated servers</h2>
|
||||
<p>
|
||||
ActivityPub instances exchange (federate) data with other instances, including accounts and toots.
|
||||
This can be prevented for specific domains by suspending them. None of their content is stored,
|
||||
and interaction with their users is blocked both ways.</br>
|
||||
{{if .blocklistExposed}}
|
||||
<a href="/about/suspended">View the list of suspended domains</a>
|
||||
{{else}}
|
||||
This instance does not publically share this list.
|
||||
{{end}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2 id="stats">Instance Statistics</h2>
|
||||
<ul>
|
||||
<li>Users: <span class="count">{{.instance.Stats.user_count}}</span></li>
|
||||
<li>Posts: <span class="count">{{.instance.Stats.status_count}}</span></li>
|
||||
<li>Federates with: <span class="count">{{.instance.Stats.domain_count}}</span> instances</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
{{- with . }}
|
||||
<main class="about">
|
||||
<section class="about-section" role="region" aria-labelledby="about">
|
||||
<h3 id="about">About {{ .instance.Title -}}</h3>
|
||||
{{- with . }}
|
||||
{{- include "description" . | indent 2 }}
|
||||
{{- end }}
|
||||
</section>
|
||||
<section class="about-section" role="region" aria-labelledby="contact">
|
||||
<h3 id="contact">Admin Contact</h3>
|
||||
{{- if .instance.ContactAccount }}
|
||||
<a href="{{- .instance.ContactAccount.URL -}}" class="account-card">
|
||||
<img class="avatar" src="{{- .instance.ContactAccount.Avatar -}}" alt=""/>
|
||||
<h3>
|
||||
{{- if .instance.ContactAccount.DisplayName -}}
|
||||
{{- emojify .instance.ContactAccount.Emojis (escape .instance.ContactAccount.DisplayName) -}}
|
||||
{{- else -}}
|
||||
{{- .instance.ContactAccount.Username -}}
|
||||
{{- end -}}
|
||||
</h3>
|
||||
<span>@{{- .instance.ContactAccount.Username -}}</span>
|
||||
</a>
|
||||
{{- else }}
|
||||
<p>This instance has not yet set a contact account.</p>
|
||||
{{- end }}
|
||||
{{- if .instance.Email }}
|
||||
<p>Email: <a href="mailto:{{- .instance.Email -}}">{{- .instance.Email -}}</a></p>
|
||||
{{- else }}
|
||||
<p>This instance has not yet set a contact email address.</p>
|
||||
{{- end }}
|
||||
</section>
|
||||
<section class="about-section" role="region" aria-labelledby="languages">
|
||||
<h3 id="languages">Languages</h3>
|
||||
{{- if .languages }}
|
||||
<p>This instance prefers the following languages:</p>
|
||||
<ol>
|
||||
{{- range .languages }}
|
||||
<li>{{- . -}}</li>
|
||||
{{- end }}
|
||||
</ol>
|
||||
{{- else }}
|
||||
<p>This instance does not have any preferred languages.</p>
|
||||
{{- end }}
|
||||
</section>
|
||||
<section class="about-section" role="region" aria-labelledby="rules">
|
||||
<h3 id="rules">Instance Rules</h3>
|
||||
<p>This instance has the following rules:</p>
|
||||
{{- if .instance.Rules }}
|
||||
<ol>
|
||||
{{- range .instance.Rules }}
|
||||
<li>{{- .Text -}}</li>
|
||||
{{- end }}
|
||||
</ol>
|
||||
{{- else }}
|
||||
<p>This instance has not yet set any rules.</p>
|
||||
{{- end }}
|
||||
</section>
|
||||
<section class="about-section" role="region" aria-labelledby="features">
|
||||
<h3 id="features">Instance Features</h3>
|
||||
<ul>
|
||||
<li>{{- template "registrationLimits" . -}}</li>
|
||||
<li>{{- template "customCSSLimits" . -}}</li>
|
||||
<li>{{- template "statusLimits" . -}}</li>
|
||||
<li>{{- template "pollLimits" . -}}</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="about-section" role="region" aria-labelledby="moderated-servers">
|
||||
<h3 id="moderated-servers">Moderated servers</h3>
|
||||
<p>
|
||||
ActivityPub instances federate with other instances by exchanging data with them over the network.
|
||||
Exchanged data includes things like accounts, statuses, likes, boosts, and media attachments.
|
||||
This exchange of data can prevented for instances on specific domains via a domain block created
|
||||
by an instance admin. When an instance is domain blocked by another instance:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Any existing data from the blocked instance is deleted from the storage of the instance doing the blocking.</li>
|
||||
<li>Interaction between the two instances is cut off in both directions; neither instance can interact with the other.</li>
|
||||
<li>No new data from the blocked instance will be created on the instance that blocks it.</li>
|
||||
</ul>
|
||||
<p>
|
||||
{{- if .blocklistExposed }}
|
||||
<a href="/about/suspended">View the list of domains blocked by this instance</a>
|
||||
{{- else }}
|
||||
This instance does not publically share their list of blocked domains.
|
||||
{{- end }}
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
{{ template "footer.tmpl" .}}
|
||||
{{- end }}
|
@@ -17,26 +17,24 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{ template "header.tmpl" .}}
|
||||
<main>
|
||||
<form action="/oauth/authorize" method="POST">
|
||||
<h1>Hi {{.user}}!</h1>
|
||||
<p>
|
||||
Application <b>{{.appname}}</b>
|
||||
{{if len .appwebsite | eq 0 | not}}
|
||||
({{.appwebsite}})
|
||||
{{end}}
|
||||
would like to perform actions on your behalf, with scope <em>{{.scope}}</em>.
|
||||
</p>
|
||||
<p>The application will redirect to {{.redirect}} to continue.</p>
|
||||
<p>
|
||||
<button
|
||||
type="submit"
|
||||
style="width:200px;"
|
||||
>
|
||||
Allow
|
||||
</button>
|
||||
</p>
|
||||
</form>
|
||||
</main>
|
||||
{{ template "footer.tmpl" .}}
|
||||
{{- with . }}
|
||||
<main>
|
||||
<form action="/oauth/authorize" method="POST">
|
||||
<h1>Hi {{ .user -}}!</h1>
|
||||
<p>
|
||||
Application
|
||||
{{- if .appwebsite }}
|
||||
<a href="{{- .appwebsite -}}" rel="nofollow noreferrer noopener" target="_blank">{{- .appname -}}</a>
|
||||
{{- else }}
|
||||
<b>{{- .appname -}}</b>
|
||||
{{- end }}
|
||||
would like to perform actions on your behalf, with scope
|
||||
<em>{{- .scope -}}</em>.
|
||||
</p>
|
||||
<p>
|
||||
To continue, the application will redirect to: <code>{{- .redirect -}}</code>
|
||||
</p>
|
||||
<button type="submit" style="width:200px;">Allow</button>
|
||||
</form>
|
||||
</main>
|
||||
{{- end }}
|
@@ -17,12 +17,11 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{ template "header.tmpl" .}}
|
||||
{{- with . }}
|
||||
<main>
|
||||
<section>
|
||||
<h1>Email Address Confirmed</h1>
|
||||
<p>Thanks {{.username}}! Your email address <b>{{.email}}</b> has been confirmed.<p>
|
||||
</section>
|
||||
<section>
|
||||
<h1>Email Address Confirmed</h1>
|
||||
<p>Thanks {{ .username -}}! Your email address <b>{{- .email -}}</b> has been confirmed.<p>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
{{ template "footer.tmpl" .}}
|
||||
{{- end }}
|
@@ -17,36 +17,36 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{ template "header.tmpl" .}}
|
||||
{{- with . }}
|
||||
<main>
|
||||
<section>
|
||||
<h1>Suspended Instances</h1>
|
||||
<p>
|
||||
The following list of domains have been suspended by the administrator(s) of this server.
|
||||
</p>
|
||||
<p>
|
||||
All current and future accounts on these instances are blocked, and no more data is federated to the remote
|
||||
servers.
|
||||
This extends to subdomains, so an entry for 'example.com' includes 'social.example.com' as well.
|
||||
</p>
|
||||
<div class="list domain-blocklist">
|
||||
<div class="header entry">
|
||||
<div class="domain">Domain</div>
|
||||
<div class="public_comment">Public comment</div>
|
||||
</div>
|
||||
{{range .blocklist}}
|
||||
<div class="entry" id="{{.Domain}}">
|
||||
<div class="domain">
|
||||
<a class="text-cutoff" href="#{{.Domain}}" title="{{.Domain}}">{{.Domain}}</a>
|
||||
</div>
|
||||
<div class="public_comment">
|
||||
<p>
|
||||
{{.PublicComment}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h1>Suspended Instances</h1>
|
||||
<p>
|
||||
The following list of domains have been suspended
|
||||
by the administrator(s) of this server.
|
||||
</p>
|
||||
<p>
|
||||
All current and future accounts on these instances are
|
||||
blocked, and no more data is federated to the remote servers.
|
||||
This extends to subdomains, so an entry for 'example.com'
|
||||
includes 'social.example.com' as well.
|
||||
</p>
|
||||
<div class="list domain-blocklist">
|
||||
<div class="header entry">
|
||||
<div class="domain">Domain</div>
|
||||
<div class="public_comment">Public comment</div>
|
||||
</div>
|
||||
{{- range .blocklist }}
|
||||
<div class="entry" id="{{- .Domain -}}">
|
||||
<div class="domain">
|
||||
<a class="text-cutoff" href="#{{- .Domain -}}" title="{{- .Domain -}}">{{- .Domain -}}</a>
|
||||
</div>
|
||||
<div class="public_comment">
|
||||
<p>{{- .PublicComment -}}</p>
|
||||
</div>
|
||||
</div>
|
||||
{{- end }}
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
{{ template "footer.tmpl" .}}
|
||||
{{- end }}
|
@@ -17,16 +17,16 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{ template "header.tmpl" .}}
|
||||
{{- with . }}
|
||||
<main>
|
||||
<section class="error">
|
||||
<h1>An error occured:</h1>
|
||||
<pre>{{.error}}</pre>
|
||||
{{if .requestID}}
|
||||
<div>
|
||||
<span>Request ID:</span> <code>{{.requestID}}</code>
|
||||
</div>
|
||||
{{end}}
|
||||
</section>
|
||||
<section class="error">
|
||||
<h1>An error occured:</h1>
|
||||
<pre>{{- .error -}}</pre>
|
||||
{{- if .requestID }}
|
||||
<div>
|
||||
<span>Request ID:</span> <code>{{- .requestID -}}</code>
|
||||
</div>
|
||||
{{- end }}
|
||||
</section>
|
||||
</main>
|
||||
{{ template "footer.tmpl" .}}
|
||||
{{- end }}
|
@@ -17,34 +17,31 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{ template "header.tmpl" .}}
|
||||
<main>
|
||||
<form action="/oauth/finalize" method="POST">
|
||||
<h1>Hi {{.name}}!</h1>
|
||||
<p>
|
||||
You are about to sign-up to {{ .instance.Title }} (<code>{{ .instance.URI }}</code>)
|
||||
<br>
|
||||
To ensure the best experience for you, we need you to provide some additional details.
|
||||
</p>
|
||||
{{if .error}}
|
||||
<section class="error">
|
||||
<span>❌</span> <pre>{{.error}}</pre>
|
||||
</section>
|
||||
{{end}}
|
||||
<div class="callout">
|
||||
<p class="callout-title">Important</p>
|
||||
<p>Due to the way the ActivityPub standard works, you <strong>cannot</strong> change your username after it has been set.</p>
|
||||
</div>
|
||||
<div class="labelinput">
|
||||
<label for="username">Username <small>(must contain only lowercase letters, numbers, and underscores)</small></label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
name="username"
|
||||
required
|
||||
placeholder="Please enter your desired username" value="{{ .preferredUsername }}">
|
||||
</div>
|
||||
<input type="hidden" name="name" value="{{ .name }}">
|
||||
<button type="submit" style="width: 100%; margin-top: 1rem;" class="btn btn-success">Submit</button>
|
||||
</form>
|
||||
</main>
|
||||
{{ template "footer.tmpl" .}}
|
||||
{{- with . }}
|
||||
<main>
|
||||
<form action="/oauth/finalize" method="POST">
|
||||
<h1>Hi {{ .name -}}!</h1>
|
||||
<p>
|
||||
You are about to sign-up to {{ .instance.Title -}}.
|
||||
To ensure the best experience for you, we need you to provide some additional details.
|
||||
</p>
|
||||
<div class="callout">
|
||||
<p class="callout-title">Important</p>
|
||||
<p>Due to the way the ActivityPub standard works, you <strong>cannot</strong> change your username after it has been set.</p>
|
||||
</div>
|
||||
<div class="labelinput">
|
||||
<label for="username">Username <small>(must contain only lowercase letters, numbers, and underscores)</small></label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
name="username"
|
||||
required
|
||||
placeholder="Please enter your desired username"
|
||||
value="{{- .preferredUsername -}}"
|
||||
>
|
||||
</div>
|
||||
<input type="hidden" name="name" value="{{- .name -}}">
|
||||
<button type="submit" style="width: 100%; margin-top: 1rem;" class="btn btn-success">Submit</button>
|
||||
</form>
|
||||
</main>
|
||||
{{- end }}
|
@@ -17,9 +17,8 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{ template "header.tmpl" .}}
|
||||
{{- with . }}
|
||||
<main class="lightgray">
|
||||
<div id="root">
|
||||
</div>
|
||||
<div id="root"></div>
|
||||
</main>
|
||||
{{ template "footer.tmpl" .}}
|
||||
{{- end }}
|
@@ -1,122 +0,0 @@
|
||||
{{- /*
|
||||
// GoToSocial
|
||||
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
|
||||
{{- /*
|
||||
NESTED TEMPLATE DECLARATIONS
|
||||
If some if/else macro is used multiple times, declare it once here instead.
|
||||
When invoking these nested templates, remember to pass in the values passed
|
||||
to the executing template, ie., use '{{ template "example" . }}' not
|
||||
'{{ template "example" }}', otherwise you'll end up with empty variables.
|
||||
*/ -}}
|
||||
{{ define "thumbnailType" }}{{ if .instance.ThumbnailType }}{{ .instance.ThumbnailType }}{{ else }}image/png{{ end }}{{ end }}
|
||||
{{ define "instanceTitle" }}{{ if .ogMeta }}{{ .ogMeta.Title }}{{ else }}{{ .instance.Title }} - GoToSocial{{ end }}{{ end }}
|
||||
|
||||
{{- /*
|
||||
BOILERPLATE GOES HERE
|
||||
*/ -}}
|
||||
<!DOCTYPE html>
|
||||
<!-- header.tmpl -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
{{- /*
|
||||
ROBOTS META TAGS
|
||||
If this template was provided with a specific robots meta policy, use that.
|
||||
Otherwise, fall back to a default restrictive policy.
|
||||
See: https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag
|
||||
*/ -}}
|
||||
<meta name="robots" content="{{ if .robotsMeta }}{{ .robotsMeta }}{{ else }}noindex, nofollow{{ end }}">
|
||||
|
||||
{{- /*
|
||||
OPEN GRAPH META TAGS
|
||||
To enable fancy previews of links to GtS posts/profiles shared via instant
|
||||
messaging, or other social media, parse out provided Open Graph meta tags.
|
||||
*/ -}}
|
||||
{{ if .ogMeta -}}
|
||||
{{ if .ogMeta.Locale }}<meta name="og:locale" content="{{ .ogMeta.Locale }}">{{ end }}
|
||||
<meta property="og:type" content="{{ .ogMeta.Type }}">
|
||||
<meta property="og:title" content="{{ .ogMeta.Title }}">
|
||||
<meta property="og:url" content="{{ .ogMeta.URL }}">
|
||||
<meta property="og:site_name" content="{{ .ogMeta.SiteName }}">
|
||||
<meta property="og:description" {{ .ogMeta.Description | noescapeAttr }}>
|
||||
{{ if .ogMeta.ArticlePublisher }}
|
||||
<meta property="og:article:publisher" content="{{ .ogMeta.ArticlePublisher }}">
|
||||
<meta property="og:article:author" content="{{ .ogMeta.ArticleAuthor }}">
|
||||
<meta property="og:article:modified_time" content="{{ .ogMeta.ArticleModifiedTime }}">
|
||||
<meta property="og:article:published_time" content="{{ .ogMeta.ArticlePublishedTime }}">
|
||||
{{ end }}
|
||||
{{ if .ogMeta.ProfileUsername }}<meta property="og:profile:username" content="{{ .ogMeta.ProfileUsername }}">{{ end }}
|
||||
<meta property="og:image" content="{{ .ogMeta.Image }}">
|
||||
{{ if .ogMeta.ImageAlt }}<meta property="og:image:alt" content="{{ .ogMeta.ImageAlt }}">{{ end }}
|
||||
{{ if .ogMeta.ImageWidth }}
|
||||
<meta property="og:image:width" content="{{ .ogMeta.ImageWidth }}">
|
||||
<meta property="og:image:height" content="{{ .ogMeta.ImageHeight }}">
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
|
||||
{{- /*
|
||||
ICON
|
||||
For icon, provide a link to the instance thumbnail. If the instance admin has
|
||||
set a custom thumbnail, use the type they uploaded, else assume image/png.
|
||||
See: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel#icon
|
||||
*/ -}}
|
||||
<link rel="icon" href="{{ .instance.Thumbnail }}" type="{{ template "thumbnailType" . }}">
|
||||
<link rel="apple-touch-icon" href="{{ .instance.Thumbnail }}" type="{{ template "thumbnailType" . }}">
|
||||
<link rel="apple-touch-startup-image" href="{{ .instance.Thumbnail }}" type="{{ template "thumbnailType" . }}">
|
||||
|
||||
{{- /*
|
||||
RSS FEED
|
||||
To enable automatic rss feed discovery for feed readers, provide the 'alternate'
|
||||
link only if rss is enabled.
|
||||
See: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel#alternate
|
||||
*/ -}}
|
||||
{{ if .rssFeed -}}
|
||||
<link rel="alternate" type="application/rss+xml" href="{{ .rssFeed }}" title="{{ template "instanceTitle" . }}">
|
||||
{{- end }}
|
||||
|
||||
{{- /*
|
||||
STYLESHEET STUFF
|
||||
To try to speed up rendering a little bit, offer a preload for each stylesheet.
|
||||
See: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preload.
|
||||
*/ -}}
|
||||
<link rel="preload" href="/assets/dist/_colors.css" as="style">
|
||||
<link rel="preload" href="/assets/dist/base.css" as="style">
|
||||
{{ range .stylesheets }}<link rel="preload" href="{{ . }}" as="style">{{ end }}
|
||||
<link rel="stylesheet" href="/assets/dist/_colors.css">
|
||||
<link rel="stylesheet" href="/assets/dist/base.css">
|
||||
{{ range .stylesheets }}<link rel="stylesheet" href="{{ . }}">{{ end }}
|
||||
<title>{{ template "instanceTitle" . }}</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="page">
|
||||
<header>
|
||||
<a aria-label="{{ .instance.Title }}. Go to instance homepage" href="/" class="nounderline header">
|
||||
<img src="{{ .instance.Thumbnail }}"
|
||||
alt="{{ if .instance.ThumbnailDescription }}{{ .instance.ThumbnailDescription }}{{ else }}Instance Logo{{ end }}" />
|
||||
<h1>
|
||||
{{ .instance.Title }}
|
||||
</h1>
|
||||
</a>
|
||||
</header>
|
||||
<div class="content">
|
@@ -17,61 +17,21 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{ template "header.tmpl" .}}
|
||||
<section class="excerpt-top">
|
||||
home to <span class="count">{{.instance.Stats.user_count}}</span> users
|
||||
who posted <span class="count">{{.instance.Stats.status_count}}</span> statuses,
|
||||
federating with <span class="count">{{.instance.Stats.domain_count}}</span> other instances.
|
||||
</section>
|
||||
<main class="lightgray">
|
||||
<section>
|
||||
<div className="short-description">
|
||||
{{.instance.ShortDescription |noescape}}
|
||||
</div>
|
||||
</section>
|
||||
<section class="apps">
|
||||
<p>
|
||||
GoToSocial does not provide its own webclient, but implements the Mastodon client API.
|
||||
You can use this server through a variety of other clients:
|
||||
</p>
|
||||
<div class="applist">
|
||||
<div class="entry">
|
||||
<svg role="img" aria-labelledby="semaphoreTitle semaphoreDesc" class="logo redraw" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 146 120">
|
||||
<title id="semaphoreTitle">The Semaphore logo</title>
|
||||
<desc id="semaphoreDesc">A waving flag</desc>
|
||||
<path d="M68.13 0C53.94 0 42.81 20 13.9 27.1l-2.23-5.29a6.5 6.5 0 0 0-5.17-10.4 6.5 6.5 0 0 0-.81 12.95L46.2 120l5.99-2.5-14.42-33.33c22.8-6.86 32.51-22.16 49.83-20.58 9.9.9 4.87 19.56 8.11 17.93 16.22-8.15 32.44-11.41 50.29-11.41-7.96-9.78-17.38-20.55-22.71-31.74L120.8 32c-2.32-7.33-2.56-14.75.87-22.22-9.74-3.26-21.1 0-32.45 4.9C82.2 9.77 79.5 0 68.13 0zM15.26 30.42c8.95 6.63 13.63 13.86 16.07 20.94l1.62 6.32c1.24 6.58 1.07 12.8 1.27 18.03z"></path>
|
||||
</svg>
|
||||
<div>
|
||||
<h2>Semaphore</h2>
|
||||
<p>Semaphore is a web client designed for speed and simplicity.</p>
|
||||
<a href="https://semaphore.social/" target="_blank" rel="noopener">Use Semaphore</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<img class="logo" src="/assets/tusky.svg" alt="The Tusky mascot, a cartoon elephant tooting happily"/>
|
||||
<div>
|
||||
<h2>Tusky</h2>
|
||||
<p>Tusky is a lightweight mobile client for Android.</p>
|
||||
<a href="https://tusky.app" target="_blank" rel="noopener">Get Tusky</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<img class="logo" src="/assets/feditext.svg" alt="The Feditext logo, the characters ft at a slight angle">
|
||||
<div>
|
||||
<h2>Feditext</h2>
|
||||
<p>Feditext (beta) is a beautiful client for iOS, iPadOS and macOS.</p>
|
||||
<a href="https://fedi.software/@Feditext" target="_blank" rel="noopener">Get Feditext</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="entry">
|
||||
<img class="logo" src="/assets/mastodon.svg" alt="The Mastodon logo, the character M in a speech bubble">
|
||||
<div>
|
||||
<h2>More clients</h2>
|
||||
<p>Or try one of the clients listed on the official Mastodon page.</p>
|
||||
<a href="https://joinmastodon.org/apps" target="_blank" rel="noopener">Get Mastodon apps</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{{- define "shortDescription" -}}
|
||||
{{- if .instance.ShortDescription }}
|
||||
{{ .instance.ShortDescription | noescape }}
|
||||
{{- else }}
|
||||
<p>No short description has yet been set for this instance.<p>
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- with . }}
|
||||
<main class="about">
|
||||
<section class="about-section" role="region" aria-labelledby="about">
|
||||
<h3 id="about">About this instance</h3>
|
||||
{{- include "shortDescription" . | indent 2 }}
|
||||
<a href="/about">See more details</a>
|
||||
</section>
|
||||
{{- include "index_apps.tmpl" . | indent 1 }}
|
||||
</main>
|
||||
{{ template "footer.tmpl" .}}
|
||||
{{- end }}
|
115
web/template/index_apps.tmpl
Normal file
115
web/template/index_apps.tmpl
Normal file
@@ -0,0 +1,115 @@
|
||||
{{- /*
|
||||
// GoToSocial
|
||||
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{- with . }}
|
||||
<section role="region" class="about-section apps" aria-labelledby="apps">
|
||||
<h3 id="apps">Client applications</h3>
|
||||
<p>
|
||||
GoToSocial does not provide its own webclient, but implements the Mastodon client API.
|
||||
You can use this server through a variety of other clients:
|
||||
</p>
|
||||
<ul class="applist nodot" role="group">
|
||||
<li class="applist-entry">
|
||||
<div class="applist-text">
|
||||
<p><strong>Semaphore</strong> is a web client designed for speed and simplicity.</p>
|
||||
<a
|
||||
href="https://semaphore.social/"
|
||||
rel="nofollow noreferrer noopener"
|
||||
target="_blank"
|
||||
>
|
||||
Use Semaphore
|
||||
</a>
|
||||
</div>
|
||||
<svg
|
||||
role="img"
|
||||
aria-labelledby="semaphore-title semaphore-desc"
|
||||
class="applist-logo redraw"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 146 120"
|
||||
width="100"
|
||||
height="100"
|
||||
>
|
||||
<title id="semaphore-title">The Semaphore logo</title>
|
||||
<desc id="semaphore-desc">A waving flag</desc>
|
||||
<path d="M68.13 0C53.94 0 42.81 20 13.9 27.1l-2.23-5.29a6.5 6.5 0 0 0-5.17-10.4 6.5 6.5 0 0 0-.81 12.95L46.2 120l5.99-2.5-14.42-33.33c22.8-6.86 32.51-22.16 49.83-20.58 9.9.9 4.87 19.56 8.11 17.93 16.22-8.15 32.44-11.41 50.29-11.41-7.96-9.78-17.38-20.55-22.71-31.74L120.8 32c-2.32-7.33-2.56-14.75.87-22.22-9.74-3.26-21.1 0-32.45 4.9C82.2 9.77 79.5 0 68.13 0zM15.26 30.42c8.95 6.63 13.63 13.86 16.07 20.94l1.62 6.32c1.24 6.58 1.07 12.8 1.27 18.03z"></path>
|
||||
</svg>
|
||||
</li>
|
||||
<li class="applist-entry">
|
||||
<div class="applist-text">
|
||||
<p><strong>Tusky</strong> is a lightweight mobile client for Android.</p>
|
||||
<a
|
||||
href="https://tusky.app"
|
||||
rel="nofollow noreferrer noopener"
|
||||
target="_blank"
|
||||
>
|
||||
Get Tusky
|
||||
</a>
|
||||
</div>
|
||||
<img
|
||||
class="applist-logo"
|
||||
src="/assets/tusky.svg"
|
||||
alt="The Tusky mascot, a cartoon elephant tooting happily"
|
||||
title="The Tusky mascot, a cartoon elephant tooting happily"
|
||||
width="100"
|
||||
height="100"
|
||||
/>
|
||||
</li>
|
||||
<li class="applist-entry">
|
||||
<div class="applist-text">
|
||||
<p><strong>Feditext</strong> (beta) is a beautiful client for iOS, iPadOS and macOS.</p>
|
||||
<a
|
||||
href="https://fedi.software/@Feditext"
|
||||
rel="nofollow noreferrer noopener"
|
||||
target="_blank"
|
||||
>
|
||||
Get Feditext
|
||||
</a>
|
||||
</div>
|
||||
<img
|
||||
class="applist-logo"
|
||||
src="/assets/feditext.svg"
|
||||
alt="The Feditext logo, the characters 'ft' at a slight angle"
|
||||
title="The Feditext logo, the characters 'ft' at a slight angle"
|
||||
width="100"
|
||||
height="100"
|
||||
/>
|
||||
</li>
|
||||
<li class="applist-entry">
|
||||
<div class="applist-text">
|
||||
<p>Or try one of the <strong>Mastodon clients</strong> listed on the official Mastodon page.</p>
|
||||
<a
|
||||
href="https://joinmastodon.org/apps"
|
||||
rel="nofollow noreferrer noopener"
|
||||
target="_blank"
|
||||
>
|
||||
Get Mastodon apps
|
||||
</a>
|
||||
</div>
|
||||
<img
|
||||
class="applist-logo"
|
||||
src="/assets/mastodon.svg"
|
||||
alt="The Mastodon logo, the character 'M' in a speech bubble"
|
||||
title="The Mastodon logo, the character 'M' in a speech bubble"
|
||||
width="100"
|
||||
height="100"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
{{- end }}
|
@@ -17,12 +17,12 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{ template "header.tmpl" .}}
|
||||
{{- with . }}
|
||||
<main>
|
||||
<section class="oob-token">
|
||||
<h1>Hi {{ .user }}!</h1>
|
||||
<p>Here's your out-of-band token with scope "<em>{{.scope}}</em>", use it wisely:</p>
|
||||
<code>{{ .oobToken }}</code>
|
||||
</section>
|
||||
<section class="oob-token">
|
||||
<h1>Hi {{ .user -}}!</h1>
|
||||
<p>Here's your out-of-band token with scope "<em>{{- .scope -}}</em>", use it wisely:</p>
|
||||
<code>{{- .oobToken -}}</code>
|
||||
</section>
|
||||
</main>
|
||||
{{ template "footer.tmpl" .}}
|
||||
{{- end }}
|
85
web/template/page.tmpl
Normal file
85
web/template/page.tmpl
Normal file
@@ -0,0 +1,85 @@
|
||||
{{- /*
|
||||
// GoToSocial
|
||||
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{- /*
|
||||
NESTED TEMPLATE DECLARATIONS
|
||||
If some if/else macro is used multiple times, declare it once here instead.
|
||||
When invoking these nested templates, remember to pass in the values passed
|
||||
to the executing template, ie., use '{{ template "example" . }}' not
|
||||
'{{ template "example" }}', otherwise you'll end up with empty variables.
|
||||
*/ -}}
|
||||
|
||||
{{- define "thumbnailType" -}}
|
||||
{{- if .instance.ThumbnailType -}}
|
||||
{{- .instance.ThumbnailType -}}
|
||||
{{- else -}}
|
||||
image/png
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "instanceTitle" -}}
|
||||
{{- if .ogMeta -}}
|
||||
{{- demojify .ogMeta.Title | noescape -}}
|
||||
{{- else -}}
|
||||
{{- .instance.Title }} - GoToSocial
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="robots" content="{{- if .robotsMeta -}}{{- .robotsMeta -}}{{- else -}}noindex, nofollow{{- end -}}">
|
||||
{{- if .ogMeta }}
|
||||
{{- include "page_ogmeta.tmpl" . | indent 2 }}
|
||||
{{- else }}
|
||||
{{- end }}
|
||||
{{- if .rssFeed }}
|
||||
<link rel="alternate" type="application/rss+xml" href="{{- .rssFeed -}}" title="{{- template "instanceTitle" . -}}">
|
||||
{{- else }}
|
||||
{{- end }}
|
||||
{{- if .account }}
|
||||
<link rel="alternate" type="application/activity+json" href="/users/{{- .account.Username -}}">
|
||||
{{- else if .status }}
|
||||
<link rel="alternate" type="application/activity+json" href="/users/{{- .status.Account.Username -}}/statuses/{{- .status.ID -}}">
|
||||
{{- else }}
|
||||
{{- end }}
|
||||
<link rel="icon" href="{{- .instance.Thumbnail -}}" type="{{- template "thumbnailType" . -}}">
|
||||
<link rel="apple-touch-icon" href="{{- .instance.Thumbnail -}}" type="{{- template "thumbnailType" . -}}">
|
||||
<link rel="apple-touch-startup-image" href="{{- .instance.Thumbnail -}}" type="{{- template "thumbnailType" . -}}">
|
||||
{{- include "page_stylesheets.tmpl" . | indent 2 }}
|
||||
{{- range .javascript }}
|
||||
<script type="text/javascript" src="{{- . -}}" async="" defer=""></script>
|
||||
{{- end }}
|
||||
<title>{{- template "instanceTitle" . -}}</title>
|
||||
</head>
|
||||
<body class="page">
|
||||
<header class="page-header">
|
||||
{{- include "page_header.tmpl" . | indent 3 }}
|
||||
</header>
|
||||
<div class="page-content">
|
||||
{{- include .pageContent . | indent 3 | outdentPre }}
|
||||
</div>
|
||||
<footer class="page-footer">
|
||||
{{- include "page_footer.tmpl" . | indent 3 }}
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
67
web/template/page_footer.tmpl
Normal file
67
web/template/page_footer.tmpl
Normal file
@@ -0,0 +1,67 @@
|
||||
{{- /*
|
||||
// GoToSocial
|
||||
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{- with . }}
|
||||
<nav>
|
||||
<ul class="nodot">
|
||||
<li id="about">
|
||||
<a
|
||||
href="/about"
|
||||
class="nounderline"
|
||||
>
|
||||
About {{ .instance.Title }}
|
||||
</a>
|
||||
</li>
|
||||
<li id="version">
|
||||
<a
|
||||
href="https://github.com/superseriousbusiness/gotosocial"
|
||||
class="nounderline"
|
||||
rel="nofollow noreferrer noopener"
|
||||
target="_blank"
|
||||
>
|
||||
<span aria-hidden="true">🦥</span>
|
||||
Source - GoToSocial {{ .instance.Version }}
|
||||
<span aria-hidden="true">🦥</span>
|
||||
</a>
|
||||
</li>
|
||||
{{- if .instance.ContactAccount }}
|
||||
<li id="contact">
|
||||
<a
|
||||
href="/@{{- .instance.ContactAccount.Username -}}"
|
||||
class="nounderline"
|
||||
>
|
||||
Contact account - {{ .instance.ContactAccount.Username }}
|
||||
</a>
|
||||
</li>
|
||||
{{- end }}
|
||||
{{- if .instance.Email }}
|
||||
<li id="email">
|
||||
<a
|
||||
href="mailto:{{- .instance.Email -}}"
|
||||
class="nounderline"
|
||||
rel="nofollow noreferrer noopener"
|
||||
target="_blank"
|
||||
>
|
||||
Email - {{ .instance.Email }}
|
||||
</a>
|
||||
</li>
|
||||
{{- end }}
|
||||
</ul>
|
||||
</nav>
|
||||
{{- end }}
|
72
web/template/page_header.tmpl
Normal file
72
web/template/page_header.tmpl
Normal file
@@ -0,0 +1,72 @@
|
||||
{{- /*
|
||||
// GoToSocial
|
||||
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{- define "thumbnailDescription" -}}
|
||||
{{- if .instance.ThumbnailDescription -}}
|
||||
{{- .instance.ThumbnailDescription -}}
|
||||
{{- else -}}
|
||||
Instance Logo
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "strapUsers" -}}
|
||||
{{- with .instance.Stats.user_count -}}
|
||||
{{- if eq . 1 -}}
|
||||
<span class="count">{{- . -}}</span> user
|
||||
{{- else -}}
|
||||
<span class="count">{{- . -}}</span> users
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "strapPosts" -}}
|
||||
{{- with .instance.Stats.status_count -}}
|
||||
{{- if eq . 1 -}}
|
||||
<span class="count">{{- . -}}</span> post
|
||||
{{- else -}}
|
||||
<span class="count">{{- . -}}</span> posts
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "strapInstances" -}}
|
||||
{{- with .instance.Stats.domain_count -}}
|
||||
{{- if eq . 1 -}}
|
||||
<span class="count">{{- . -}}</span> other instance
|
||||
{{- else -}}
|
||||
<span class="count">{{- . -}}</span> other instances
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- with . }}
|
||||
<a aria-label="{{- .instance.Title -}}. Go to instance homepage" href="/" class="nounderline">
|
||||
<img
|
||||
src="{{- .instance.Thumbnail -}}"
|
||||
alt="{{- template "thumbnailDescription" . -}}"
|
||||
title="{{- template "thumbnailDescription" . -}}"
|
||||
width="100"
|
||||
height="100"
|
||||
/>
|
||||
<h1>{{- .instance.Title -}}</h1>
|
||||
</a>
|
||||
{{- if .showStrap }}
|
||||
<aside>home to {{ template "strapUsers" . }} who wrote {{ template "strapPosts" . }}, federating with {{ template "strapInstances" . }}</aside>
|
||||
{{- end }}
|
||||
{{- end }}
|
57
web/template/page_ogmeta.tmpl
Normal file
57
web/template/page_ogmeta.tmpl
Normal file
@@ -0,0 +1,57 @@
|
||||
{{- /*
|
||||
// GoToSocial
|
||||
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{- /*
|
||||
OPEN GRAPH META TAGS
|
||||
To enable fancy previews of links to GtS posts/profiles shared via instant
|
||||
messaging, or other social media, parse out provided Open Graph meta tags.
|
||||
*/ -}}
|
||||
|
||||
{{- with .ogMeta }}
|
||||
{{- if .Locale }}
|
||||
<meta name="og:locale" content="{{- .Locale -}}">
|
||||
{{- else }}
|
||||
{{- end }}
|
||||
<meta property="og:type" content="{{- .Type -}}">
|
||||
<meta property="og:title" content="{{- demojify .Title | noescape -}}">
|
||||
<meta property="og:url" content="{{- .URL -}}">
|
||||
<meta property="og:site_name" content="{{- .SiteName -}}">
|
||||
<meta property="og:description" {{ demojify .Description | noescapeAttr -}}>
|
||||
{{- if .ArticlePublisher }}
|
||||
<meta property="og:article:publisher" content="{{ .ArticlePublisher }}">
|
||||
<meta property="og:article:author" content="{{ .ArticleAuthor }}">
|
||||
<meta property="og:article:modified_time" content="{{ .ArticleModifiedTime }}">
|
||||
<meta property="og:article:published_time" content="{{ .ArticlePublishedTime }}">
|
||||
{{- else }}
|
||||
{{- end }}
|
||||
{{- if .ProfileUsername }}
|
||||
<meta property="og:profile:username" content="{{- .ProfileUsername -}}">
|
||||
{{- else }}
|
||||
{{- end }}
|
||||
<meta property="og:image" content="{{- .Image -}}">
|
||||
{{- if .ImageAlt }}
|
||||
<meta property="og:image:alt" content="{{- .ImageAlt -}}">
|
||||
{{- else }}
|
||||
{{- end }}
|
||||
{{- if .ImageWidth }}
|
||||
<meta property="og:image:width" content="{{ .ImageWidth }}">
|
||||
<meta property="og:image:height" content="{{ .ImageHeight }}">
|
||||
{{- else }}
|
||||
{{- end }}
|
||||
{{- end }}
|
41
web/template/page_stylesheets.tmpl
Normal file
41
web/template/page_stylesheets.tmpl
Normal file
@@ -0,0 +1,41 @@
|
||||
{{- /*
|
||||
// GoToSocial
|
||||
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{- /*
|
||||
Order of stylesheet loading is important: _colors and base should always be loaded
|
||||
before any other provided sheets, since the latter cascade from the former.
|
||||
|
||||
To try to speed up rendering a little bit, offer a preload for each stylesheet.
|
||||
See: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preload.
|
||||
*/ -}}
|
||||
|
||||
{{- with . }}
|
||||
<link rel="preload" href="/assets/dist/_colors.css" as="style">
|
||||
<link rel="preload" href="/assets/dist/base.css" as="style">
|
||||
<link rel="preload" href="/assets/dist/page.css" as="style">
|
||||
{{- range .stylesheets }}
|
||||
<link rel="preload" href="{{- . -}}" as="style">
|
||||
{{- end }}
|
||||
<link rel="stylesheet" href="/assets/dist/_colors.css">
|
||||
<link rel="stylesheet" href="/assets/dist/base.css">
|
||||
<link rel="stylesheet" href="/assets/dist/page.css">
|
||||
{{- range .stylesheets }}
|
||||
<link rel="stylesheet" href="{{- . -}}">
|
||||
{{- end }}
|
||||
{{- end }}
|
@@ -17,129 +17,123 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{ template "header.tmpl" .}}
|
||||
|
||||
{{- with . }}
|
||||
<main class="profile">
|
||||
<div class="header">
|
||||
<div class="header-image">
|
||||
{{ if .account.Header }}
|
||||
<img src="{{.account.Header}}" alt="" />
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="basic-info" aria-hidden="true">
|
||||
<a class="avatar" href="{{.account.Avatar}}">
|
||||
<img src="{{.account.Avatar}}" alt="">
|
||||
</a>
|
||||
<span class="displayname text-cutoff">
|
||||
{{if .account.DisplayName}}
|
||||
{{emojify .account.Emojis (escape .account.DisplayName)}}
|
||||
{{else}}
|
||||
{{.account.Username}}
|
||||
{{end}}
|
||||
</span>
|
||||
<span class="username text-cutoff">@{{.account.Username}}@{{.instance.AccountDomain}}</span>
|
||||
{{- /* Only render account role if 1. it's present and 2. it's not equal to the standard 'user' role */ -}}
|
||||
{{ if and (.account.Role) (ne .account.Role.Name "user") }}
|
||||
<div class="role {{ .account.Role.Name }}">
|
||||
{{ .account.Role.Name }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class="sr-only">
|
||||
Profile for
|
||||
{{if .account.DisplayName}}{{.account.DisplayName}}{{else}}{{.account.Username}}{{end}}.
|
||||
Username @{{.account.Username}}, {{.instance.AccountDomain}}.
|
||||
{{ if and (.account.Role) (ne .account.Role.Name "user") }}
|
||||
Role: {{ .account.Role.Name }}
|
||||
{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column-split">
|
||||
|
||||
<section class="about-user">
|
||||
<div class="col-header">
|
||||
<h1>About</h1>
|
||||
</div>
|
||||
|
||||
<div class="fields">
|
||||
{{ range .account.Fields }}
|
||||
<div class="field">
|
||||
<b>{{emojify $.account.Emojis (noescape .Name)}}</b>
|
||||
<span>{{emojify $.account.Emojis (noescape .Value)}}</span>
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<div class="bio">
|
||||
{{ if .account.Note }}
|
||||
{{emojify .account.Emojis (noescape .account.Note)}}
|
||||
{{else}}
|
||||
This GoToSocial user hasn't written a bio yet!
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
<div class="sr-only" role="group">
|
||||
<span>Joined on {{.account.CreatedAt | timestampVague}}.</span>
|
||||
<span>{{.account.StatusesCount}} post{{if .account.StatusesCount | eq 1 | not}}s{{end}}.</span>
|
||||
<span>Followed by {{.account.FollowersCount}}.</span>
|
||||
<span>Following {{.account.FollowingCount}}.</span>
|
||||
</div>
|
||||
|
||||
<div class="accountstats" aria-hidden="true">
|
||||
<b>Joined</b><time datetime="{{.account.CreatedAt}}">{{.account.CreatedAt | timestampVague}}</time>
|
||||
<b>Posts</b><span>{{.account.StatusesCount}}</span>
|
||||
<b>Followed by</b><span>{{.account.FollowersCount}}</span>
|
||||
<b>Following</b><span>{{.account.FollowingCount}}</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="toots">
|
||||
{{ if .pinned_statuses }}
|
||||
<div class="col-header">
|
||||
<h2>Pinned posts</h2>
|
||||
<a href="#recent">jump to recent</a>
|
||||
</div>
|
||||
<section class="thread">
|
||||
{{ range .pinned_statuses }}
|
||||
<article class="toot expanded" id="{{.ID}}">
|
||||
{{ template "status.tmpl" .}}
|
||||
</article>
|
||||
{{ end }}
|
||||
</section>
|
||||
{{ end }}
|
||||
|
||||
<div class="col-header">
|
||||
<h2 id="recent" tabindex="-1">Recent posts</h2>
|
||||
{{ if .rssFeed }}
|
||||
<a href="{{ .rssFeed }}" class="rss-icon" aria-label="RSS feed">
|
||||
<i class="fa fa-rss-square" aria-hidden="true"></i>
|
||||
</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
|
||||
<section class="thread">
|
||||
{{ if not .statuses }}
|
||||
<div data-nosnippet class="nothinghere">Nothing here!</div>
|
||||
{{ else }}
|
||||
{{ range .statuses }}
|
||||
<article class="toot expanded" id="{{.ID}}">
|
||||
{{ template "status.tmpl" .}}
|
||||
</article>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</section>
|
||||
|
||||
<div class="backnextlinks">
|
||||
{{ if .show_back_to_top }}
|
||||
<a href="/@{{ .account.Username }}">Back to top</a>
|
||||
{{ end }}
|
||||
{{ if .statuses_next }}
|
||||
<a href="{{ .statuses_next }}" class="next">Show older</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<h2 class="sr-only">Profile for {{ .account.Username -}}</h2>
|
||||
<section class="profile-header" role="region" aria-label="Basic info">
|
||||
<div class="header-image-wrapper">
|
||||
<img
|
||||
src="{{- .account.Header -}}"
|
||||
alt="Header for {{ .account.Username -}}"
|
||||
title="Header for {{ .account.Username -}}"
|
||||
/>
|
||||
</div>
|
||||
<div class="basic-info">
|
||||
<a class="avatar" href="{{- .account.Avatar -}}">
|
||||
<img
|
||||
src="{{- .account.Avatar -}}"
|
||||
alt="Avatar for {{ .account.Username -}}"
|
||||
title="Avatar for {{ .account.Username -}}"
|
||||
/>
|
||||
</a>
|
||||
<dl class="namerole">
|
||||
<dt class="sr-only">Display name</dt>
|
||||
<dd class="displayname text-cutoff">
|
||||
{{- if .account.DisplayName -}}
|
||||
{{- emojify .account.Emojis (escape .account.DisplayName) -}}
|
||||
{{- else -}}
|
||||
{{- .account.Username -}}
|
||||
{{- end -}}
|
||||
</dd>
|
||||
<dt class="sr-only">Username</dt>
|
||||
<dd class="username text-cutoff">@{{- .account.Username -}}@{{- .instance.AccountDomain -}}</dd>
|
||||
{{- if and (.account.Role) (ne .account.Role.Name "user") }}
|
||||
<dt class="sr-only">Role</dt>
|
||||
<dd class="role {{ .account.Role.Name -}}">{{- .account.Role.Name -}}</dd>
|
||||
{{- end }}
|
||||
</dl>
|
||||
</div>
|
||||
</section>
|
||||
<div class="column-split">
|
||||
<section class="about-user" role="region" aria-labelledby="about-header">
|
||||
<div class="col-header">
|
||||
<h3 id="about-header">About<span class="sr-only"> {{- .account.Username -}}</span></h3>
|
||||
</div>
|
||||
{{- if .account.Fields }}
|
||||
{{- include "profile_fields.tmpl" . | indent 3 }}
|
||||
{{- end }}
|
||||
<h4 class="sr-only">Bio</h4>
|
||||
<div class="bio">
|
||||
{{- if .account.Note }}
|
||||
{{ emojify .account.Emojis (noescape .account.Note) }}
|
||||
{{- else }}
|
||||
<p>This GoToSocial user hasn't written a bio yet!</p>
|
||||
{{- end }}
|
||||
</div>
|
||||
<h4 class="sr-only">Stats</h4>
|
||||
<dl class="accountstats">
|
||||
<dt>Joined</dt>
|
||||
<dd><time datetime="{{- .account.CreatedAt -}}">{{- .account.CreatedAt | timestampVague -}}</time></dd>
|
||||
<dt>Posts</dt>
|
||||
<dd>{{- .account.StatusesCount -}}</dd>
|
||||
<dt>Followed by</dt>
|
||||
<dd>{{- .account.FollowersCount -}}</dd>
|
||||
<dt>Following</dt>
|
||||
<dd>{{- .account.FollowingCount -}}</dd>
|
||||
</dl>
|
||||
</section>
|
||||
<div class="statuses-wrapper" role="region" aria-label="Posts by {{ .account.Username -}}">
|
||||
{{- if .pinned_statuses }}
|
||||
<section class="pinned statuses" aria-labelledby="pinned">
|
||||
<div class="col-header">
|
||||
<h3 id="pinned">Pinned posts</h3>
|
||||
<a href="#recent">jump to recent</a>
|
||||
</div>
|
||||
<div class="thread">
|
||||
{{- range .pinned_statuses }}
|
||||
<article
|
||||
class="status expanded"
|
||||
{{- includeAttr "status_attributes.tmpl" . | indentAttr 6 }}
|
||||
>
|
||||
{{- include "status.tmpl" . | indent 6 }}
|
||||
</article>
|
||||
{{- end }}
|
||||
</div>
|
||||
</section>
|
||||
{{- end }}
|
||||
<section class="recent statuses" aria-labelledby="recent">
|
||||
<div class="col-header">
|
||||
<h3 id="recent" tabindex="-1">Recent posts</h3>
|
||||
{{- if .rssFeed }}
|
||||
<a href="{{- .rssFeed -}}" class="rss-icon" aria-label="RSS feed">
|
||||
<i class="fa fa-rss-square" aria-hidden="true"></i>
|
||||
</a>
|
||||
{{- end }}
|
||||
</div>
|
||||
<div class="thread">
|
||||
{{- if not .statuses }}
|
||||
<div data-nosnippet class="nothinghere">Nothing here!</div>
|
||||
{{- else }}
|
||||
{{- range .statuses }}
|
||||
<article
|
||||
class="status expanded"
|
||||
{{- includeAttr "status_attributes.tmpl" . | indentAttr 6 }}
|
||||
>
|
||||
{{- include "status.tmpl" . | indent 6 }}
|
||||
</article>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
</div>
|
||||
<nav class="backnextlinks">
|
||||
{{- if .show_back_to_top }}
|
||||
<a href="/@{{- .account.Username -}}">Back to top</a>
|
||||
{{- end }}
|
||||
{{- if .statuses_next }}
|
||||
<a href="{{- .statuses_next -}}" class="next">Show older</a>
|
||||
{{- end }}
|
||||
</nav>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{{ template "footer.tmpl" .}}
|
||||
{{- end }}
|
@@ -17,30 +17,16 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
<!-- footer.tmpl -->
|
||||
</div>
|
||||
<footer>
|
||||
<div id="version">
|
||||
<a name="Source code" href="https://github.com/superseriousbusiness/gotosocial">
|
||||
GoToSocial <span class="accent">{{.instance.Version}}</span>
|
||||
</a>
|
||||
</div>
|
||||
{{ if .instance.ContactAccount }}
|
||||
<div id="contact">
|
||||
Contact: <a href="{{.instance.ContactAccount.URL}}" class="nounderline">{{.instance.ContactAccount.Username}}</a><br>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ if .instance.Email }}
|
||||
<div id="email">
|
||||
Email: <a href="mailto:{{.instance.Email}}" class="nounderline">{{.instance.Email}}</a><br>
|
||||
</div>
|
||||
{{ end }}
|
||||
</footer>
|
||||
</div>
|
||||
{{ if .javascript }}
|
||||
{{ range .javascript }}
|
||||
<script src="{{.}}"></script>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</body>
|
||||
</html>
|
||||
{{- with . }}
|
||||
<div class="fields">
|
||||
<h4 class="sr-only">Fields</h4>
|
||||
<dl>
|
||||
{{- range .account.Fields }}
|
||||
<div class="field">
|
||||
<dt>{{- emojify $.account.Emojis (noescape .Name) -}}</dt>
|
||||
<dd>{{- emojify $.account.Emojis (noescape .Value) -}}</dd>
|
||||
</div>
|
||||
{{- end }}
|
||||
</dl>
|
||||
</div>
|
||||
{{- end }}
|
@@ -17,10 +17,10 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{ template "header.tmpl" .}}
|
||||
{{- with . }}
|
||||
<main>
|
||||
<section class="login">
|
||||
<h1>Login</h1>
|
||||
<section class="sign-in" aria-labelledby="sign-in">
|
||||
<h2 id="sign-in">Sign in</h2>
|
||||
<form action="/auth/sign_in" method="POST">
|
||||
<div class="labelinput">
|
||||
<label for="email">Email</label>
|
||||
@@ -30,8 +30,8 @@
|
||||
<label for="password">Password</label>
|
||||
<input type="password" class="form-control" name="password" required placeholder="Please enter your password">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success">Login</button>
|
||||
<button type="submit" class="btn btn-success">Sign in</button>
|
||||
</form>
|
||||
</section>
|
||||
</main>
|
||||
{{ template "footer.tmpl" .}}
|
||||
{{- end }}
|
@@ -17,88 +17,74 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
<a data-nosnippet href="{{- .URL -}}" class="toot-link">Open thread</a>
|
||||
<section class="author">
|
||||
<a href="{{- .Account.URL -}}">
|
||||
<img class="avatar" src="{{- .Account.Avatar -}}" alt="">
|
||||
<span aria-hidden="true" class="displayname">
|
||||
{{- if .Account.DisplayName -}}
|
||||
{{- emojify .Account.Emojis (escape .Account.DisplayName) -}}
|
||||
{{- else -}}
|
||||
{{- .Account.Username -}}
|
||||
{{- end -}}
|
||||
</span>
|
||||
<span aria-hidden="true" class="username">@{{- .Account.Username -}}</span>
|
||||
<span class="sr-only">
|
||||
{{- if .Account.DisplayName -}}
|
||||
{{- emojify .Account.Emojis (escape .Account.DisplayName) -}}. Username: @{{ .Account.Acct -}}.
|
||||
{{- else -}}
|
||||
@{{- .Account.Acct -}}.
|
||||
{{- end -}}
|
||||
</span>
|
||||
</a>
|
||||
</section>
|
||||
<section class="body">
|
||||
{{- if .SpoilerText }}
|
||||
<details class="text-spoiler">
|
||||
<summary>
|
||||
<span class="spoiler-text" lang="{{- .LanguageTag.TagStr -}}">{{- emojify .Emojis (escape .SpoilerText) -}}</span>
|
||||
<span class="button" role="button" tabindex="0">Toggle visibility</span>
|
||||
</summary>
|
||||
<div class="text">
|
||||
<div class="content" lang="{{- .LanguageTag.TagStr -}}">
|
||||
{{ emojify .Emojis (noescape .Content) }}
|
||||
</div>
|
||||
{{- if .Poll }}
|
||||
{{ template "status_poll.tmpl" . }}
|
||||
{{- end }}
|
||||
</div>
|
||||
</details>
|
||||
{{- else }}
|
||||
<div class="text">
|
||||
<div class="content" lang="{{- .LanguageTag.TagStr -}}">
|
||||
{{ emojify .Emojis (noescape .Content) }}
|
||||
</div>
|
||||
{{- if .Poll }}
|
||||
{{ template "status_poll.tmpl" . }}
|
||||
{{- end }}
|
||||
</div>
|
||||
{{- end }}
|
||||
{{- if .MediaAttachments }}
|
||||
{{ template "status_attachments.tmpl" . }}
|
||||
{{- end }}
|
||||
</section>
|
||||
<aside class="info">
|
||||
<dl class="sr-only">
|
||||
<dt>Published<dt>
|
||||
<dd>{{- .CreatedAt | timestampPrecise -}}</dd>
|
||||
{{- if .LanguageTag.DisplayStr }}
|
||||
<dt>Language</dt>
|
||||
<dd>{{ .LanguageTag.DisplayStr }}</dd>
|
||||
{{- end }}
|
||||
</dl>
|
||||
<time aria-hidden="true" datetime="{{- .CreatedAt -}}">{{- .CreatedAt | timestampPrecise -}}</time>
|
||||
<div class="stats" role="group">
|
||||
<div class="stats-item">
|
||||
<span aria-hidden="true"><i class="fa fa-reply-all"></i> {{ .RepliesCount -}}</span>
|
||||
<span class="sr-only">{{- .RepliesCount }} {{ if .RepliesCount | eq 1 }}reply{{ else }}replies{{ end -}}</span>
|
||||
</div>
|
||||
<div class="stats-item">
|
||||
<span aria-hidden="true"><i class="fa fa-star"></i> {{ .FavouritesCount -}}</span>
|
||||
<span class="sr-only">{{- .FavouritesCount }} {{ if .FavouritesCount | eq 1 }}favourite{{ else }}favourites{{ end -}}</span>
|
||||
</div>
|
||||
<div class="stats-item">
|
||||
<span aria-hidden="true"><i class="fa fa-retweet"></i> {{ .ReblogsCount -}}</span>
|
||||
<span class="sr-only">{{- .ReblogsCount }} {{ if .ReblogsCount | eq 1 }}boost{{ else }}boosts{{ end -}}</span>
|
||||
</div>
|
||||
{{- if .Pinned }}
|
||||
<div class="stats-item">
|
||||
<i class="fa fa-thumb-tack" aria-hidden="true"></i>
|
||||
<span class="sr-only">pinned</span>
|
||||
</div>
|
||||
{{- end }}
|
||||
{{- if .LanguageTag.DisplayStr }}
|
||||
<div aria-hidden="true" class="stats-item language" title="Language: {{ .LanguageTag.DisplayStr }}">{{ .LanguageTag.TagStr }}</div>
|
||||
{{- end }}
|
||||
</div>
|
||||
{{- define "statusContent" -}}
|
||||
{{- with .Content }}
|
||||
<div class="content" lang="{{- $.LanguageTag.TagStr -}}">
|
||||
{{ noescape . | emojify $.Emojis }}
|
||||
</div>
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- /*
|
||||
When including this template, always wrap
|
||||
it in an appropriate <article></article>!
|
||||
*/ -}}
|
||||
|
||||
{{- with . }}
|
||||
<header class="status-header">
|
||||
{{- include "status_header.tmpl" . | indent 1 }}
|
||||
</header>
|
||||
<div class="status-body">
|
||||
{{- if .SpoilerText }}
|
||||
<details class="text-spoiler">
|
||||
<summary>
|
||||
<span class="spoiler-text" lang="{{- .LanguageTag.TagStr -}}">{{- emojify .Emojis (escape .SpoilerText) -}}</span>
|
||||
<span class="button" role="button" tabindex="0">Toggle visibility</span>
|
||||
</summary>
|
||||
<div class="text">
|
||||
{{- with . }}
|
||||
{{- include "statusContent" . | indent 3 }}
|
||||
{{- end }}
|
||||
{{- if .Poll }}
|
||||
{{- include "status_poll.tmpl" . | indent 3 }}
|
||||
{{- end }}
|
||||
</div>
|
||||
</details>
|
||||
{{- else }}
|
||||
<div class="text">
|
||||
{{- with . }}
|
||||
{{- include "statusContent" . | indent 2 }}
|
||||
{{- end }}
|
||||
{{- if .Poll }}
|
||||
{{- include "status_poll.tmpl" . | indent 2 }}
|
||||
{{- end }}
|
||||
</div>
|
||||
{{- end }}
|
||||
{{- if .MediaAttachments }}
|
||||
{{- include "status_attachments.tmpl" . | indent 1 }}
|
||||
{{- end }}
|
||||
</div>
|
||||
<aside class="status-info" aria-hidden="true">
|
||||
{{- include "status_info.tmpl" . | indent 1 }}
|
||||
</aside>
|
||||
{{- if .Local }}
|
||||
<a
|
||||
href="{{- .URL -}}"
|
||||
class="status-link"
|
||||
data-nosnippet
|
||||
title="Open thread at this post"
|
||||
>
|
||||
Open thread at this post
|
||||
</a>
|
||||
{{- else }}
|
||||
<a
|
||||
href="{{- .URL -}}"
|
||||
class="status-link"
|
||||
data-nosnippet
|
||||
rel="nofollow noreferrer noopener" target="_blank"
|
||||
title="Open remote post (opens in a new window)"
|
||||
>
|
||||
Open remote post (opens in a new window)
|
||||
</a>
|
||||
{{- end }}
|
||||
{{- end }}
|
@@ -18,77 +18,119 @@
|
||||
*/ -}}
|
||||
|
||||
{{- /*
|
||||
Template for rendering a gallery of status media attachments.
|
||||
To use this template, pass a web view status into it.
|
||||
Template for rendering a gallery of status media attachments.
|
||||
To use this template, pass a web view status into it.
|
||||
*/ -}}
|
||||
|
||||
{{ with .MediaAttachments }}
|
||||
<div class="media photoswipe-gallery {{ (len .) | oddOrEven }} {{ if eq (len .) 1 }}single{{ else if eq (len .) 2 }}double{{- end -}}">
|
||||
{{- range $index, $media := . }}
|
||||
<div class="media-wrapper">
|
||||
<details class="{{- $media.Type -}}-spoiler media-spoiler" {{- if not $media.Sensitive }} open{{ end -}}>
|
||||
<summary>
|
||||
<div class="show sensitive button" aria-hidden="true">Show sensitive media</div>
|
||||
<span class="eye button" role="button" tabindex="0" aria-label="Toggle media">
|
||||
<i class="hide fa fa-fw fa-eye-slash" aria-hidden="true"></i>
|
||||
<i class="show fa fa-fw fa-eye" aria-hidden="true"></i>
|
||||
</span>
|
||||
{{- if eq .Type "video" }}
|
||||
<video {{- if .Description }} title="{{- $media.Description -}}" {{- end -}}>
|
||||
<source type="video/mp4" src="{{- $media.URL -}}"/>
|
||||
</video>
|
||||
{{- else if eq .Type "image" }}
|
||||
<img src="{{- $media.PreviewURL -}}" {{- if .Description }} title="{{- $media.Description -}}" {{- end }}/>
|
||||
{{- end }}
|
||||
</summary>
|
||||
{{- if eq .Type "video" }}
|
||||
<video
|
||||
class="plyr-video photoswipe-slide"
|
||||
controls
|
||||
data-pswp-index="{{- $index -}}"
|
||||
data-pswp-width="{{- $media.Meta.Original.Width -}}px"
|
||||
data-pswp-height="{{- $media.Meta.Original.Height -}}px"
|
||||
{{- if .Description }}
|
||||
alt="{{- $media.Description -}}"
|
||||
title="{{- $media.Description -}}"
|
||||
{{- end }}
|
||||
>
|
||||
<source type="video/mp4" src="{{- $media.URL -}}"/>
|
||||
</video>
|
||||
{{- else if eq .Type "image" }}
|
||||
<a
|
||||
class="photoswipe-slide"
|
||||
href="{{- $media.URL -}}"
|
||||
target="_blank"
|
||||
data-pswp-width="{{- $media.Meta.Original.Width -}}px"
|
||||
data-pswp-height="{{- $media.Meta.Original.Height -}}px"
|
||||
data-cropped="true"
|
||||
{{- if .Description }}
|
||||
title="{{- $media.Description -}}"
|
||||
{{- end }}
|
||||
>
|
||||
<img src="{{$media.PreviewURL}}" {{if .Description}}alt="{{$media.Description}}" {{end}} />
|
||||
</a>
|
||||
{{- else }}
|
||||
<a
|
||||
class="unknown-attachment"
|
||||
href="{{- $media.RemoteURL -}}"
|
||||
target="_blank"
|
||||
{{- if .Description }}
|
||||
title="Link to external media: {{ $media.Description -}} {{- $media.RemoteURL -}}"
|
||||
{{- else }}
|
||||
title="Link to external media. {{- $media.RemoteURL -}}"
|
||||
{{- end }}
|
||||
>
|
||||
<div class="placeholder" aria-hidden="true">
|
||||
<i class="placeholder-external-link fa fa-external-link"></i>
|
||||
<i class="placeholder-icon fa fa-file-text"></i>
|
||||
<div class="placeholder-link-to">External media</div>
|
||||
</div>
|
||||
</a>
|
||||
{{- end }}
|
||||
</details>
|
||||
</div>
|
||||
{{- end }}
|
||||
</div>
|
||||
{{- define "imagePreview" }}
|
||||
<img
|
||||
src="{{- .PreviewURL -}}"
|
||||
loading="lazy"
|
||||
{{- if .Description }}
|
||||
alt="{{- .Description -}}"
|
||||
title="{{- .Description -}}"
|
||||
{{- end }}
|
||||
width="{{- .Meta.Original.Width -}}"
|
||||
height="{{- .Meta.Original.Height -}}"
|
||||
/>
|
||||
{{- end }}
|
||||
|
||||
{{- define "videoPreview" }}
|
||||
<video
|
||||
{{- if .Description }}
|
||||
alt="{{- .Description -}}"
|
||||
title="{{- .Description -}}"
|
||||
{{- end }}
|
||||
width="{{- .Meta.Original.Width -}}"
|
||||
height="{{- .Meta.Original.Height -}}"
|
||||
>
|
||||
<source type="video/mp4" src="{{- .URL -}}"/>
|
||||
</video>
|
||||
{{- end }}
|
||||
|
||||
{{- /* Produces something like "1 attachment", "2 attachments", etc */ -}}
|
||||
{{- define "attachmentsLength" -}}
|
||||
{{- (len .) }}{{- if eq (len .) 1 }} attachment{{- else }} attachments{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- /* Produces something like "media photoswipe-gallery odd single" */ -}}
|
||||
{{- define "galleryClass" -}}
|
||||
media photoswipe-gallery {{ (len .) | oddOrEven }} {{ if eq (len .) 1 }}single{{ else if eq (len .) 2 }}double{{ end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- with .MediaAttachments }}
|
||||
<div
|
||||
class="{{- template "galleryClass" . -}}"
|
||||
role="group"
|
||||
aria-label="{{- template "attachmentsLength" . -}}"
|
||||
>
|
||||
{{- range $index, $media := . }}
|
||||
<div class="media-wrapper">
|
||||
<details class="{{- $media.Type -}}-spoiler media-spoiler" {{- if not $media.Sensitive }} open{{- end -}}>
|
||||
<summary>
|
||||
<div class="show sensitive button" aria-hidden="true">Show sensitive media</div>
|
||||
<span class="eye button" role="button" tabindex="0" aria-label="Toggle media">
|
||||
<i class="hide fa fa-fw fa-eye-slash" aria-hidden="true"></i>
|
||||
<i class="show fa fa-fw fa-eye" aria-hidden="true"></i>
|
||||
</span>
|
||||
{{- if eq .Type "video" }}
|
||||
{{- include "videoPreview" $media | indent 4 }}
|
||||
{{- else if eq .Type "image" }}
|
||||
{{- include "imagePreview" $media | indent 4 }}
|
||||
{{- end }}
|
||||
</summary>
|
||||
{{- if eq .Type "video" }}
|
||||
<video
|
||||
class="plyr-video photoswipe-slide"
|
||||
controls
|
||||
data-pswp-index="{{- $index -}}"
|
||||
data-pswp-width="{{- $media.Meta.Original.Width -}}px"
|
||||
data-pswp-height="{{- $media.Meta.Original.Height -}}px"
|
||||
{{- if .Description }}
|
||||
alt="{{- $media.Description -}}"
|
||||
title="{{- $media.Description -}}"
|
||||
{{- end }}
|
||||
>
|
||||
<source type="video/mp4" src="{{- $media.URL -}}"/>
|
||||
</video>
|
||||
{{- else if eq .Type "image" }}
|
||||
<a
|
||||
class="photoswipe-slide"
|
||||
href="{{- $media.URL -}}"
|
||||
target="_blank"
|
||||
data-pswp-width="{{- $media.Meta.Original.Width -}}px"
|
||||
data-pswp-height="{{- $media.Meta.Original.Height -}}px"
|
||||
data-cropped="true"
|
||||
{{- if .Description }}
|
||||
alt="{{- $media.Description -}}"
|
||||
title="{{- $media.Description -}}"
|
||||
{{- end }}
|
||||
>
|
||||
{{- with $media }}
|
||||
{{- include "imagePreview" . | indent 4 }}
|
||||
{{- end }}
|
||||
</a>
|
||||
{{- else }}
|
||||
<a
|
||||
class="unknown-attachment"
|
||||
href="{{- $media.RemoteURL -}}"
|
||||
rel="nofollow noreferrer noopener"
|
||||
target="_blank"
|
||||
{{- if .Description }}
|
||||
title="Open external media: {{ $media.Description -}} {{- $media.RemoteURL -}}"
|
||||
{{- else }}
|
||||
title="Open external media. {{- $media.RemoteURL -}}"
|
||||
{{- end }}
|
||||
>
|
||||
<div class="placeholder" aria-hidden="true">
|
||||
<i class="placeholder-external-link fa fa-external-link"></i>
|
||||
<i class="placeholder-icon fa fa-file-text"></i>
|
||||
<div class="placeholder-link-to">External media</div>
|
||||
</div>
|
||||
</a>
|
||||
{{- end }}
|
||||
</details>
|
||||
</div>
|
||||
{{- end }}
|
||||
</div>
|
||||
{{- end }}
|
55
web/template/status_attributes.tmpl
Normal file
55
web/template/status_attributes.tmpl
Normal file
@@ -0,0 +1,55 @@
|
||||
{{- /*
|
||||
// GoToSocial
|
||||
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{- define "ariaLabel" -}}
|
||||
@{{ .Account.Acct -}}, {{ timestamp .CreatedAt -}}
|
||||
{{- if .LanguageTag -}}
|
||||
, language {{ .LanguageTag.DisplayStr -}}
|
||||
{{- end -}}
|
||||
{{- if .MediaAttachments -}}
|
||||
, has media
|
||||
{{- end -}}
|
||||
{{- if .RepliesCount -}}
|
||||
{{- if eq .RepliesCount 1 -}}
|
||||
, 1 reply
|
||||
{{- else -}}
|
||||
, {{ .RepliesCount }} replies
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if .FavouritesCount -}}
|
||||
{{- if eq .FavouritesCount 1 -}}
|
||||
, 1 favourite
|
||||
{{- else -}}
|
||||
, {{ .FavouritesCount }} favourites
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if .ReblogsCount -}}
|
||||
{{- if eq .ReblogsCount 1 -}}
|
||||
, 1 boost
|
||||
{{- else -}}
|
||||
, {{ .ReblogsCount }} boosts
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- with . }}
|
||||
id="{{- .ID -}}{{- if .Pinned -}}-pinned{{- end -}}"
|
||||
role="region"
|
||||
aria-label="{{- template "ariaLabel" . -}}"
|
||||
{{- end }}
|
56
web/template/status_header.tmpl
Normal file
56
web/template/status_header.tmpl
Normal file
@@ -0,0 +1,56 @@
|
||||
{{- /*
|
||||
// GoToSocial
|
||||
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{- with .Account }}
|
||||
<address>
|
||||
{{- if $.Local }}
|
||||
<a
|
||||
href="{{- .URL -}}"
|
||||
rel="author"
|
||||
title="Open profile"
|
||||
>
|
||||
{{- else }}
|
||||
<a
|
||||
href="{{- .URL -}}"
|
||||
rel="author nofollow noreferrer noopener" target="_blank"
|
||||
title="Open remote profile (opens in a new window)"
|
||||
>
|
||||
{{- end }}
|
||||
<img
|
||||
class="avatar"
|
||||
aria-hidden="true"
|
||||
src="{{- .Avatar -}}"
|
||||
alt="Avatar for {{ .Username -}}"
|
||||
title="Avatar for {{ .Username -}}"
|
||||
>
|
||||
<div class="author-strap">
|
||||
<span class="displayname text-cutoff">
|
||||
{{- if .DisplayName -}}
|
||||
{{- emojify .Emojis (escape .DisplayName) -}}
|
||||
{{- else -}}
|
||||
{{- .Username -}}
|
||||
{{- end -}}
|
||||
</span>
|
||||
<span class="sr-only">,</span>
|
||||
<span class="username text-cutoff">@{{- .Acct -}}</span>
|
||||
</div>
|
||||
<span class="sr-only">(open profile)</span>
|
||||
</a>
|
||||
</address>
|
||||
{{- end }}
|
74
web/template/status_info.tmpl
Normal file
74
web/template/status_info.tmpl
Normal file
@@ -0,0 +1,74 @@
|
||||
{{- /*
|
||||
// GoToSocial
|
||||
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{- with . }}
|
||||
<dl class="status-stats">
|
||||
<div class="stats-grouping">
|
||||
<div class="stats-item published-at text-cutoff">
|
||||
<dt class="sr-only">Published</dt>
|
||||
<dd>
|
||||
<time datetime="{{- .CreatedAt -}}">{{- .CreatedAt | timestampPrecise -}}</time>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="stats-grouping">
|
||||
<div class="stats-item" title="Replies">
|
||||
<dt>
|
||||
<span class="sr-only">Replies</span>
|
||||
<i class="fa fa-reply-all" aria-hidden="true"></i>
|
||||
</dt>
|
||||
<dd>{{- .RepliesCount -}}</dd>
|
||||
</div>
|
||||
<div class="stats-item" title="Faves">
|
||||
<dt>
|
||||
<span class="sr-only">Favourites</span>
|
||||
<i class="fa fa-star" aria-hidden="true"></i>
|
||||
</dt>
|
||||
<dd>{{- .FavouritesCount -}}</dd>
|
||||
</div>
|
||||
<div class="stats-item" title="Boosts">
|
||||
<dt>
|
||||
<span class="sr-only">Reblogs</span>
|
||||
<i class="fa fa-retweet" aria-hidden="true"></i>
|
||||
</dt>
|
||||
<dd>{{- .ReblogsCount -}}</dd>
|
||||
</div>
|
||||
{{- if .Pinned }}
|
||||
<div class="stats-item" title="Pinned">
|
||||
<dt>
|
||||
<span class="sr-only">Pinned</span>
|
||||
<i class="fa fa-thumb-tack" aria-hidden="true"></i>
|
||||
</dt>
|
||||
<dd class="sr-only">{{- .Pinned -}}</dd>
|
||||
</div>
|
||||
{{- else }}
|
||||
{{- end }}
|
||||
</div>
|
||||
</div>
|
||||
{{- if .LanguageTag.DisplayStr }}
|
||||
<div class="stats-item language" title="{{ .LanguageTag.DisplayStr }}">
|
||||
<dt class="sr-only">Language</dt>
|
||||
<dd>
|
||||
<span class="sr-only">{{ .LanguageTag.DisplayStr }}</span>
|
||||
<span aria-hidden="true">{{- .LanguageTag.TagStr -}}</span>
|
||||
</dd>
|
||||
</div>
|
||||
{{- else }}
|
||||
{{- end }}
|
||||
</dl>
|
||||
{{- end }}
|
@@ -18,51 +18,64 @@
|
||||
*/ -}}
|
||||
|
||||
{{- /*
|
||||
Template for rendering a web view of a poll.
|
||||
To use this template, pass a web view status into it.
|
||||
Template for rendering a web view of a poll.
|
||||
To use this template, pass a web view status into it.
|
||||
*/ -}}
|
||||
|
||||
<figure class="poll">
|
||||
<figcaption class="poll-info">
|
||||
<span class="poll-expiry">
|
||||
{{- if .Poll.Multiple -}}
|
||||
Multiple-choice poll
|
||||
{{- else -}}
|
||||
Poll
|
||||
{{- end -}}
|
||||
{{- if .Poll.Expired -}}
|
||||
closed {{ .Poll.ExpiresAt | timestampPrecise -}}
|
||||
{{- else if .Poll.ExpiresAt -}}
|
||||
open until {{ .Poll.ExpiresAt | timestampPrecise -}}
|
||||
{{- else -}}
|
||||
open forever
|
||||
{{- end -}}
|
||||
</span>
|
||||
<span class="total-votes">Total votes: {{ .Poll.VotesCount }}</span>
|
||||
</figcaption>
|
||||
<ul class="poll-options">
|
||||
{{- range $index, $pollOption := .WebPollOptions }}
|
||||
<li class="poll-option">
|
||||
<label aria-hidden="true" for="poll-{{- $pollOption.PollID -}}-option-{{- increment $index -}}" lang="{{- .LanguageTag.TagStr -}}">{{- emojify .Emojis (noescape $pollOption.Title) -}}</label>
|
||||
<meter aria-hidden="true" id="poll-{{- $pollOption.PollID -}}-option-{{- increment $index -}}" min="0" max="100" value="{{- $pollOption.VoteShare -}}">{{- $pollOption.VoteShare -}}%</meter>
|
||||
<div class="sr-only">Option {{ increment $index }}: <span lang="{{ .LanguageTag.TagStr }}">{{ emojify .Emojis (noescape $pollOption.Title) -}}</span></div>
|
||||
<div class="poll-vote-summary">
|
||||
{{- if isNil $pollOption.VotesCount }}
|
||||
Results not yet published.
|
||||
{{- else -}}
|
||||
{{- with deref $pollOption.VotesCount }}
|
||||
<span class="poll-vote-share">{{- $pollOption.VoteShareStr -}}%</span>
|
||||
<span class="poll-vote-count">
|
||||
{{- if eq . 1 -}}
|
||||
{{- . }} vote
|
||||
{{- else -}}
|
||||
{{- . }} votes
|
||||
{{- end -}}
|
||||
</span>
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
</div>
|
||||
</li>
|
||||
{{- end }}
|
||||
</ul>
|
||||
</figure>
|
||||
{{- define "votes" -}}
|
||||
{{- if eq . 1 -}}
|
||||
{{- . -}} vote
|
||||
{{- else -}}
|
||||
{{- . }} votes
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- with . }}
|
||||
<figure class="poll">
|
||||
<figcaption class="poll-info">
|
||||
<span class="poll-expiry">
|
||||
{{- if .Poll.Multiple -}}
|
||||
Multiple-choice poll
|
||||
{{- else -}}
|
||||
Poll
|
||||
{{- end -}}
|
||||
{{- if .Poll.Expired -}}
|
||||
closed <time datetime="{{- .Poll.ExpiresAt -}}">{{- .Poll.ExpiresAt | timestampPrecise -}}</time>
|
||||
{{- else if .Poll.ExpiresAt -}}
|
||||
open until <time datetime="{{- .Poll.ExpiresAt -}}">{{- .Poll.ExpiresAt | timestampPrecise -}}</time>
|
||||
{{- else -}}
|
||||
open forever
|
||||
{{- end -}}
|
||||
</span>
|
||||
<span class="sr-only">,</span>
|
||||
<span class="total-votes">
|
||||
{{- template "votes" .Poll.VotesCount -}}
|
||||
{{- if .Poll.Expired -}}
|
||||
total
|
||||
{{- else -}}
|
||||
so far
|
||||
{{- end -}}
|
||||
</span>
|
||||
</figcaption>
|
||||
<ul class="poll-options nodot">
|
||||
{{- range $index, $pollOption := .WebPollOptions }}
|
||||
<li class="poll-option">
|
||||
<span class="sr-only">Option {{ increment $index }},</span>
|
||||
<span lang="{{- .LanguageTag.TagStr -}}">{{ emojify .Emojis (noescape $pollOption.Title) }}</span>
|
||||
<meter aria-hidden="true" min="0" max="100" value="{{- $pollOption.VoteShare -}}"></meter>
|
||||
<div class="poll-vote-summary">
|
||||
{{- if isNil $pollOption.VotesCount }}
|
||||
Results not yet published.
|
||||
{{- else }}
|
||||
{{- with deref $pollOption.VotesCount }}
|
||||
<span class="poll-vote-share">{{- $pollOption.VoteShareStr -}}%</span>
|
||||
<span class="sr-only">,</span>
|
||||
<span class="poll-vote-count">{{- template "votes" . -}}</span>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
</div>
|
||||
</li>
|
||||
{{- end }}
|
||||
</ul>
|
||||
</figure>
|
||||
{{- end }}
|
@@ -17,11 +17,13 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{ template "header.tmpl" .}}
|
||||
|
||||
<main class="thread">
|
||||
<h2 id="tag-name" tabindex="-1">#{{.tagName}}</h2>
|
||||
<p>There's nothing here yet!</p>
|
||||
{{- with . }}
|
||||
<main>
|
||||
<h2 id="tag-name" tabindex="-1">#{{- .tagName -}}</h2>
|
||||
<p>There's nothing here!</p>
|
||||
<p>
|
||||
For privacy reasons, GoToSocial doesn't (yet) implement public web views of tag timelines.
|
||||
To soften the blow, here's a tongue twister: "I squeeze the soft sloth often in the mothy loft" 🦥
|
||||
</p>
|
||||
</main>
|
||||
|
||||
{{ template "footer.tmpl" .}}
|
||||
{{- end }}
|
@@ -17,22 +17,45 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ -}}
|
||||
|
||||
{{ template "header.tmpl" .}}
|
||||
<main>
|
||||
<section data-nosnippet class="thread">
|
||||
{{range .context.Ancestors}}
|
||||
<article class="toot" id="{{.ID}}">
|
||||
{{ template "status.tmpl" .}}
|
||||
</article>
|
||||
{{end}}
|
||||
<article class="toot expanded" id="{{.status.ID}}">
|
||||
{{ template "status.tmpl" .status}}
|
||||
</article>
|
||||
{{range .context.Descendants}}
|
||||
<article class="toot" id="{{.ID}}">
|
||||
{{ template "status.tmpl" .}}
|
||||
</article>
|
||||
{{end}}
|
||||
</section>
|
||||
{{- define "threadLength" -}}
|
||||
{{- with $length := add (len $.context.Ancestors) (len $.context.Descendants) | increment -}}
|
||||
{{- if eq $length 1 -}}
|
||||
{{- $length }} post
|
||||
{{- else -}}
|
||||
{{- $length }} posts
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- with . }}
|
||||
<main data-nosnippet class="thread" aria-labelledby="thread-summary">
|
||||
<div class="col-header">
|
||||
<h2 id="thread-summary">Thread with {{ template "threadLength" . -}}</h2>
|
||||
<a href="#{{- .status.ID -}}">jump to expanded post</a>
|
||||
</div>
|
||||
{{- range .context.Ancestors }}
|
||||
<article
|
||||
class="status"
|
||||
{{- includeAttr "status_attributes.tmpl" . | indentAttr 2 }}
|
||||
>
|
||||
{{- include "status.tmpl" . | indent 2 }}
|
||||
</article>
|
||||
{{- end }}
|
||||
{{- with .status }}
|
||||
<article
|
||||
class="status expanded"
|
||||
{{- includeAttr "status_attributes.tmpl" . | indentAttr 2 }}
|
||||
>
|
||||
{{- include "status.tmpl" . | indent 2 }}
|
||||
</article>
|
||||
{{- end }}
|
||||
{{- range .context.Descendants }}
|
||||
<article
|
||||
class="status"
|
||||
{{- includeAttr "status_attributes.tmpl" . | indentAttr 2 }}
|
||||
>
|
||||
{{- include "status.tmpl" . | indent 2 }}
|
||||
</article>
|
||||
{{- end }}
|
||||
</main>
|
||||
{{ template "footer.tmpl" .}}
|
||||
{{- end }}
|
Reference in New Issue
Block a user