📕 yarn is a Self-Hosted, Twitter™-like Decentralised micro-Blogging platform. No ads, no tracking, your content, your data! https://yarn.social/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

374 lines
16 KiB

{{ define "navbar" }}
<div id="podNavigation"{{ if not .Authenticated }} class="mobNoAuth"{{end}}>
{{ if .Authenticated }}
<div id="timelineBtn">
<a href="/" title="Last updated {{ .TimelineUpdatedAt | time }}">
<i class="ti ti-message-circle"></i> {{ tr . "NavTimeline" }}
</a>
</div>
<div id="discoverBtn">
<a href="/discover" title="Last updated {{ .DiscoverUpdatedAt | time }}">
<i class="ti ti-compass"></i> {{ tr . "NavDiscover" }}
</a>
</div>
<div id="mentionsBtn">
<a href="/mentions" title="Last mentioned {{ .LastMentionedAt | time }}">
<i class="ti ti-bell-ringing"></i> {{ tr . "NavMentions" }}
</a>
</div>
<div id="feedsBtn">
<a href="/feeds">
<i class="ti ti-rss-nav"></i> {{ tr . "NavFeeds" }}
</a>
</div>
<div id="settingsBtn" >
<a class="secondary" href="/settings">
<i class="ti ti-settings-nav"></i> {{ tr . "NavSettings" }}
</a>
</div>
<div id="logoutBtn">
<a class="secondary" href="/logout" onclick="return confirm('{{ tr . "NavLogoutConfirm" }}')">
<i class="ti ti-door-exit"></i> {{ tr . "NavLogout" }}
</a>
</div>
{{ else }}
<div id="loginBtn">
<a href="/login">
<i class="ti ti-door-enter"></i> {{ tr . "NavLogin" }}
</a>
</div>
{{ if not .RegisterDisabled }}
<div id="registerBtn">
<a href="/register">
<i class="ti ti-user-plus"></i> {{ tr . "NavRegister" }}
</a>
</div>
{{ end }}
{{ end }}
</div>
<div id="podSearch"{{ if not .Authenticated }} class="mobNoAuth"{{end}}>
<form id="search" action="/search" method="GET">
<div class="search-grid">
<input type="search" name="tag" placeholder="Search Tags" aria-label="Search">
<button type="submit">Search</button>
</div>
</form>
</div>
{{ end }}
{{ define "post" }}
{{ if $.Authenticated }}
{{ if or (eq $.view "timeline") (eq $.view "bookmarks") }}
<details id="newPost">
<summary><span><i class="ti ti-message"></i>&nbsp;&nbsp;Create a New Post</span></summary>
{{ end }}
<div id="postbox" class="{{ if eq $.view "permalink" }}single-twt{{ end }}{{ if eq $.view "conv" }}yarn-post{{ end }}">
<nav id="toolbar" class="toolbar-nav">
<div class="toolbar-form-button"><a id="bBtn" href="#" title="{{ tr $.Ctx "ToolbarButtonBold" }}" role="button"><i class="ti ti-bold"></i></a></div>
<div class="toolbar-form-button"><a id="iBtn" href="#" title="{{ tr $.Ctx "ToolbarButtonItalic" }}" role="button"><i class="ti ti-italic"></i></a></div>
<div class="toolbar-form-button"><a id="sBtn" href="#" title="{{ tr $.Ctx "ToolbarButtonStrikethrough" }}" role="button"><i class="ti ti-strikethrough"></i></a></div>
<div class="toolbar-form-button"><a id="cBtn" href="#" title="{{ tr $.Ctx "ToolbarButtonCode" }}" role="button"><i class="ti ti-code"></i></a></div>
<div class="toolbar-form-button"><a id="usrBtn" href="#" title="{{ tr $.Ctx "ToolbarButtonMention" }}" role="button"><i class="ti ti-user-circle"></i></a></div>
<div class="toolbar-form-button"><a id="lnkBtn" href="#" title="{{ tr $.Ctx "ToolbarButtonLink" }}" role="button"><i class="ti ti-link"></i></a></div>
<div class="toolbar-form-button"><a id="imgBtn" href="#" title="{{ tr $.Ctx "ToolbarButtonImage" }}" role="button"><i class="ti ti-photo"></i></a></div>
{{ if not $.Ctx.DisableMedia }}
<div class="toolbar-form-button">
<form id="mediaUploadForm" action="/upload" enctype="multipart/form-data" method="POST" title="{{ tr $.Ctx "ToolbarButtonMedia" }}">
<input type="hidden" name="csrf_token" value="{{ $.CSRFToken }}">
<label for="uploadMedia" role="button"><i id="uploadMediaButton" class="ti ti-upload"></i></label>
<input id="uploadMedia" class="invisible width-none" type="file" accept="image/*{{ if not $.Ctx.DisableFfmpeg }},audio/*,video/*{{ end }}" name="media_file" />
</form>
</div>
{{ end }}
</nav>
<form id="form" class="{{ if eq $.view "conv" }}conv-post{{ end }}" action="/post" method="POST">
<input type="hidden" name="csrf_token" value="{{ $.CSRFToken }}">
<input type="hidden" id="replaceTwt" name="hash" value="" />
<input type="hidden" id="replyTo" name="reply" value="{{ $.Reply }}" />
<input type="hidden" id="title" name="title" placeholder="{{ tr $.Ctx "TwtFormTitle" }}" value="" />
<div class="textarea-container">
<textarea id="text" name="text" placeholder="{{ $.TwtPrompt }}" rows=4 maxlength={{ $.MaxTwtLength }} {{ if $.AutoFocus }}autofocus="true"{{ end }} required="true" aria-required="true">{{ $.PostText }}</textarea>
<div id="mentioned-list" class="users-list">
<div id="mentioned-list-content" class="mentioned-list-content">
</div>
</div>
</div>
<div class="submit-bar">
{{ if gt (len $.User.Feeds) 0 }}
<div>
<select id="postas" class="postas" name="postas">
<option value="{{ $.User.Username }}" selected>{{ tr $.Ctx "TwtFormPostAs" (dict "Username" $.User.Username) }}</option>
{{ range $index, $feed := $.User.Feeds }}
<option value="{{ $feed }}">{{ $feed }}</option>
{{ end }}
</select>
</div>
{{ end }}
<div>
<button id="post" type="submit">
<i class="ti ti-send"></i> {{ tr $.Ctx "TwtFormPost" }}
</button>
</div>
</div>
</form>
</div>
{{ if or (eq $.view "timeline") (eq $.view "bookmarks") }}
</details>
{{ end }}
{{ end }}
{{ end }}
{{ define "twt" }}
<article id="{{ $.Twt.Hash }}" class="h-entry {{ if eq $.view "permalink" }}single-twt{{ end }}">
<div class="u-author h-card">
<div>
{{ if $.User.Is $.Twt.Twter.URI }}
<a href="{{ $.User.URL | trimSuffix "/twtxt.txt" }}" class="u-url">
<img class="avatar u-photo" src="/user/{{ $.User.Username }}/avatar" alt="" loading=lazy />
</a>
{{ else }}
{{ if isLocalURL $.Twt.Twter.URI }}
<a href="{{ $.Twt.Twter.URI | trimSuffix "/twtxt.txt" }}" class="u-url">
<img class="avatar u-photo" src="/user/{{ $.Twt.Twter.Nick }}/avatar" alt="" loading=lazy />
</a>
{{ else }}
<a href="/external?uri={{ $.Twt.Twter.URI }}&nick={{ $.Twt.Twter.Nick }}" class="u-url">
{{ if $.Twt.Twter.Avatar }}
<img class="avatar u-photo" src="/externalAvatar?uri={{ $.Twt.Twter.URI }}" alt="" loading=lazy />
{{ else }}
<i class="ti ti-rss" style="font-size:3em"></i>
{{ end }}
</a>
{{ end }}
{{ end }}
</div>
<div class="author">
<div class="p-name">
{{ if isLocalURL $.Twt.Twter.URI }}
<a href="{{ $.Twt.Twter.URI | trimSuffix "/twtxt.txt" }}">{{ $.Twt.Twter.Nick }}</a>
{{ else }}
<a href="/external?uri={{ $.Twt.Twter.URI }}&nick={{ $.Twt.Twter.Nick }}">{{ $.Twt.Twter.Nick }}</a>
{{ end }}
</div>
<div class="p-org">
<a target="_blank" href="{{ $.Twt.Twter.URI | baseFromURL }}">{{ $.Twt.Twter.URI | hostnameFromURL }}</a>
</div>
{{ if not $.User.VisibilityCompact }}
<div class="dt-publish">
<a class="u-url" href="/twt/{{ $.Twt.Hash }}">
<time class="dt-published" datetime="{{ $.Twt.Created | date "2006-01-02T15:04:05Z07:00" }}">
{{ dateInZone (formatForDateTime $.Twt.Created $.User.DisplayTimeFormat) $.Twt.Created $.User.DisplayDatesInTimezone }}
</time>
</a>
<span>&nbsp;({{ $.Twt.Created | time }})</span>
</div>
{{ end }}
</div>
{{ if $.User.VisibilityCompact }}
<div class="dt-compact">
<div><a class="u-url" href="/twt/{{ $.Twt.Hash }}">{{ dateInZone (formatForDateTime $.Twt.Created $.User.DisplayTimeFormat) $.Twt.Created $.User.DisplayDatesInTimezone }}</a></div>
<div><small>{{ $.Twt.Created | time }}</small></div>
</div>
{{ end }}
</div>
<div class="e-content">
{{ if not (eq $.view "conv") }}
{{ with urlForRootConv $.Twt }}
{{ $rootTwt := getRootTwt $.Twt $.User }}
<small class="twt-context">
&rdsh;
<a href="{{ urlForRootConv $.Twt }}#{{ $.Twt.Hash }}" title="{{ tr $.Ctx "ConversationOnTwtMessage" (dict "Hash" $rootTwt.Hash) }}">{{ tr $.Ctx "ConversationInReply" }}</a>
&raquo;
{{ if gt (formatTwtContext $.Twt $.User | len) 0 }}
{{ formatTwtContext $.Twt $.User }}
{{ else }}
<em>This twt is from a user you have muted.</em>
{{ end }}
</small>
{{ end }}
{{ end }}
{{ formatTwt $.Twt $.User }}
</div>
<span id="readtwt">{{ tr $.Ctx "TwtReadMore" }}</span>
<nav class="twt-nav">
{{ if $.Authenticated }}
<a class="replyBtn" href="#" data-reply="{{ $.User.Reply $.Twt }}">
<i class="ti ti-message-plus" data-reply="{{ $.User.Reply $.Twt }}"></i> {{ tr $.Ctx "TwtReplyLinkTitle" }}
</a>
{{ if and (eq $.view "conv") (not (eq $.Twt.Hash $.Ctx.Root.Hash)) (lt (getForkLength $.Twt $.User) 1) }}
<a class="forkBtn" href="#" data-fork="{{ $.User.Fork $.Twt }}">
<i class="ti ti-messages" data-fork="{{ $.User.Fork $.Twt }}"></i> {{ tr $.Ctx "TwtForkLinkTitle" }}
</a>
{{ end }}
{{ if eq $.LastTwt.Hash $.Twt.Hash }}
<a class="editBtn" href="#" data-hash="{{ $.Twt.Hash }}" data-text="{{ $.Twt | unparseTwt }}">
<i class="ti ti-edit" data-hash="{{ $.Twt.Hash }}" data-text="{{ $.Twt | unparseTwt }}"></i> {{ tr $.Ctx "TwtEditLinkTitle" }}
</a>
<a class="deleteBtn" href="#" data-hash="{{ $.Twt.Hash }}">
<i class="ti ti-trash" data-hash="{{ $.Twt.Hash }}"></i> {{ tr $.Ctx "TwtDeleteLinkTitle" }}
</a>
{{ end }}
{{ end }}
{{ if and (eq $.view "conv") (not (eq $.Twt.Hash $.Ctx.Root.Hash)) (gt (getForkLength $.Twt $.User) 0) }}
<a class="convBtn" href="{{ urlForFork $.Twt }}">
<i class="ti ti-messages"></i> {{ tr $.Ctx "TwtForkLinkTitle" }}
<span class="yarn-count-badge">{{ getForkLength $.Twt $.User }}</span>
</a>
{{ end }}
{{ if eq $.Twt.Hash $.Ctx.Root.Hash }}
{{ with urlForRootConv $.Twt }}
<a class="convBtn" href="{{ urlForRootConv $.Twt }}">
<i class="ti ti-message"></i> {{ tr $.Ctx "ConversationRoot" }}
</a>
{{ end }}
{{ else if not (eq $.view "conv") }}
{{ with urlForConv $.Twt }}
<a class="convBtn" href="{{ urlForConv $.Twt }}">
<i class="ti ti-message"></i> {{ tr $.Ctx "TwtConversationLinkTitle" }}
{{ if gt (getConvLength $.Twt $.User) 1 }}
<span class="yarn-count-badge">{{ getConvLength $.Twt $.User }}</span>
{{ end }}
</a>
{{ end }}
{{ end }}
{{ if $.Authenticated }}
<div id="twt-options">
<a class="muteTwtBtn" href="/mute/{{ $.Twt.Hash }}" title="{{ tr $.Ctx "TwtMute" }}">
<i class="ti ti-volume-3"></i>
</a>
<a class="bookmarkBtn" style="display: {{ if not ($.User.Bookmarked $.Twt.Hash) }}inline{{ else }}none{{ end }};" href="/bookmark/{{ $.Twt.Hash }}" title="{{ tr $.Ctx "BookmarkAddTwt" }}">
<i class="ti ti-bookmark"></i>
</a>
<a class="unbookmarkBtn" style="display: {{ if ($.User.Bookmarked $.Twt.Hash) }}inline{{ else }}none{{ end }};" href="/bookmark/{{ $.Twt.Hash }}" title="{{ tr $.Ctx "BookmarkRemoveTwt" }}">
<i class="ti ti-bookmark-off"></i>
</a>
</div>
{{ end }}
</nav>
</article>
{{ end }}
{{ define "feed" }}
{{ if gt (len $.Twts) 0 }}
<div class="grid h-feed{{ if eq $.view "bookmarks" }} bookmark-feed{{ end }}">
{{ template "pager" (dict "Pager" $.Pager "Ctx" $.Ctx) }}
{{ range $idx, $twt := $.Twts }}
{{ template "twt" (dict "Authenticated" $.Authenticated "User" $.User "Profile" $.Profile "LastTwt" $.LastTwt "Twt" $twt "Ctx" $.Ctx "view" $.view) }}
{{ else }}
{{ if eq $.view "timeline" }}
<p>{{ tr $.Ctx "NoTwts" }}</p>
<p>{{ tr $.Ctx "ProfileNoTwts" (dict ".InstanceName" $.Ctx.InstanceName ".NavDiscover" (tr $.Ctx "NavDiscover") ".NavFollow" (tr $.Ctx "NavFollow")) | html }}</p>
{{ else }}
<p>{{ .Profile.Nick }} {{ tr $.Ctx "ProfileLastPosted" }} {{ .Profile.LastPostedAt | time }}</p>
{{ end }}
{{ end }}
{{ template "pager" (dict "Pager" $.Pager "Ctx" $.Ctx) }}
</div>
{{ else }}
<div class="h-feed-empty"></div>
{{ end }}
{{ end }}
{{ define "pager" }}
{{ if $.Pager.HasPages }}
<nav class="{{ if $.Ctx.Root.IsZero }}timeline-nav{{ else }}yarn-nav{{ end }}">
<ul>
<li>
{{ if $.Pager.HasPrev }}
{{ with $.Ctx.Twter.URI }}
{{ if isLocalURL $.Ctx.Twter.URI }}
<a href="?p={{ $.Pager.PrevPage }}"><i class="ti ti-caret-left"></i> {{ tr $.Ctx "PagerPrevLinkTitle" }}</a>
{{ else }}
<a href="/external?uri={{ $.Ctx.Twter.URI }}&nick={{ $.Ctx.Twter.Nick }}&p={{ $.Pager.PrevPage }}"><i class="ti ti-caret-left"></i> {{ tr $.Ctx "PagerPrevLinkTitle" }}</a>
{{ end }}
{{ else }}
<a href="?p={{ $.Pager.PrevPage }}"><i class="ti ti-caret-left"></i> {{ tr $.Ctx "PagerPrevLinkTitle" }}</a>
{{ end }}
{{ else }}
{{ end }}
</li>
</ul>
<ul>
<li><small>{{ tr $.Ctx "PagerTwtsSummary" (dict "Page" $.Pager.Page "PageNums" $.Pager.PageNums "Nums" $.Pager.Nums) }}</small></li>
</ul>
<ul>
<li>
{{ if $.Pager.HasNext }}
{{ with $.Ctx.Twter.URI }}
{{ if isLocalURL $.Ctx.Twter.URI }}
<a href="?p={{ $.Pager.NextPage }}">{{ tr $.Ctx "PagerNextLinkTitle" }} <i class="ti ti-caret-right"></i></a>
{{ else }}
<a href="/external?uri={{ $.Ctx.Twter.URI }}&nick={{ $.Ctx.Twter.Nick }}&p={{ $.Pager.NextPage }}">{{ tr $.Ctx "PagerNextLinkTitle" }} <i class="ti ti-caret-right"></i></a>
{{ end }}
{{ else }}
<a href="?p={{ $.Pager.NextPage }}">{{ tr $.Ctx "PagerNextLinkTitle" }} <i class="ti ti-caret-right"></i></a>
{{ end }}
{{ else }}
{{ end }}
</li>
</ul>
</nav>
{{ end }}
{{ end }}
{{ define "followStats" }}
{{ if $.Profile.ShowFollowing }}
<span id="following">
{{ if eq $.Profile.Type "External" }}
{{ $.Profile.NFollowing }} <a href="/externalFollowing?uri={{ $.Profile.URI }}">{{ tr $.Ctx "ProfileFollowingLinkTitle" }}</a>
{{ else }}
{{ $.Profile.NFollowing }} <a href="/user/{{ $.Profile.Nick }}/following">{{ tr $.Ctx "ProfileFollowingLinkTitle" }}</a>
{{ end }}
</span>
{{ end }}
{{ if $.Profile.ShowFollowers }}
<span id="followers">
{{ if eq $.Profile.Type "External" }}
{{ $.Profile.NFollowers }} <a href="#" title="{{ tr $.Ctx "FollowExternal" }}">{{ tr $.Ctx "ProfileFollowersLinkTitle" }}</a>
{{ else }}
{{ $.Profile.NFollowers }} <a href="/user/{{ $.Profile.Nick }}/followers">{{ tr $.Ctx "ProfileFollowersLinkTitle" }}</a>
{{ end }}
</span>
{{ end }}
{{ end }}
{{ define "mutedStats" }}
<div id="muted">
{{ $.User.Muted | len }} <a href="/muted">{{ tr $.Ctx "MutedLinkTitle" }}</a>
</div>
{{ end }}
{{ define "profileLinks" }}
<li>
<a target="_blank" href="{{ $.Profile.URI }}">
<i class="ti ti-link-profile"></i> {{ tr $.Ctx "ProfileTwtxtLinkTitle" }}
</a>
</li>
{{ if ne $.Profile.Type "External" }}
<li>
<a href="{{ $.Profile.URI | trimSuffix "/twtxt.txt" }}/bookmarks">
<i class="ti ti-bookmarks"></i> {{ tr $.Ctx "ProfileBookmarksLinkTitle" | trimSuffix ":" }}
</a>
</li>
{{ end }}
{{ if $.Profile.Links }}
{{ range $link := $.Profile.Links }}
<li>
<div class="delLink">
<a href="{{ $link.URL }}">
<i class="ti ti-external-link"></i> {{ $link.Title }}
</a>
{{ if $.Authenticated }}
{{ if eq $.Profile.Nick $.User.Username }}
<form action="/settings/removelink" enctype="multipart/form-data" method="POST">
<input type="hidden" name="csrf_token" value="{{ $.CSRFToken }}">
<input type="hidden" name="link_title" value="{{ $link.Title }}">
<button type="submit"><i class="ti ti-circle-x"></i></button>
</form>
{{ end }}
{{ end }}
</div>
</li>
{{ end }}
{{ end }}
{{ end }}