-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
250 lines (234 loc) · 12.9 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<link rel="stylesheet" href="css/pico.min.css" />
<link rel="stylesheet" href="css/styles.css" />
<title>Mastodon Featured Profiles Lab</title>
<script src="lib/vue.global.prod.js" defer></script>
<script src="mastodon.js" defer></script>
<script src="script.js" defer></script>
</head>
<body>
<div id="app">
<div class="container root">
<main class="container">
<header class="container">
<nav>
<ul>
<li> </li>
</ul>
<ul>
<li><a href="./index.html">Home</a></li>
<li><a href="./about.html">About</a></li>
<li v-if="mastodon && mastodon.loggedIn()">
<a href="#" @click="logout()">Logout</a>
</li>
</ul>
</nav>
<div class="title">
<h1>Mastodon Featured Profiles</h1>
<span>
A streamlined tool for easier management of your featured
profiles.
</span>
</div>
</header>
<dialog v-if="this.$root.userPreferences.read_only && this.$root.userPreferences.read_only === true"
id="readOnlyModal">
<article>
<h2>You are logged in with read only access</h2>
<p>
To add or remove featured profiles, you'll need to do so directly on your Mastodon instance.
</p>
<p>
From a profile page, select the action from the secondary menu, then refresh this page to see the update.
</p>
<img src="/images/profile_example.png" alt="Profile Example"
style="width:100%; max-width:300px; margin: 0 auto; display:block;" />
<footer>
<button @click="hideModal()">Understood</button>
</footer>
</article>
</dialog>
<div v-if="mastodon && !mastodon.loggedIn()">
<div class="callout-main">
<p>
Mastodon's featured profiles is a way to highlight your most loved followed accounts, but was partially
removed in a previous upgrade.
</p>
<p>This application provides a way to view and manage your featured profiles in preparation for a possible
revival (see roadmap item <a href="https://joinmastodon.org/roadmap" target="_source">MAS-13</a>).</p>
<span>ℹ️</span> <a href="/about.html">Learn more</a>
</div>
<h2>Login with Mastodon</h2>
<form @submit.prevent="login">
<label id="mastodon-instance-label" for="mastodon-instance">
Enter your Mastodon instance (also known as a server or domain)
</label>
<input type="text" v-model="server" id="mastodon-instance" list="servers" autocomplete="on"
aria-label="Your Mastodon Instance" aria-describedby="mastodon-instance-label" placeholder=""
aria-placeholder="" required="" aria-required="true" />
<datalist id="servers">
<option v-for="server in servers">{{ server.domain }}</option>
</datalist>
<div class="read-only-scope" :class="{ active:read_only }">
<label>
<input id="mastodon-read-only-scope" v-model="read_only" type="checkbox" role="switch" />
Security conscious? Authorize read-only access.
</label>
<div>
<em>Prevents managing featured profiles, but allows viewing
existing selections.</em>
</div>
</div>
<button class="btn-login" type="submit">Login</button>
</form>
</div>
<div v-else>
<article>
<account v-if="this.loading_endorsements == false" :profile="this.my_account" :followed="this.my_followed"
:endorsements="this.my_endorsements"></account>
<endorsements :endorsements="this.my_endorsements" :loading_endorsements="this.loading_endorsements"
:total_endorsements_loaded="this.total_endorsements_loaded"></endorsements>
<followed :followed="this.my_followed" :loading_followed="this.loading_followed"
:total_followed_loaded="this.total_followed_loaded"></followed>
</article>
</div>
</main>
<footer class="container page-footer">
<div class="callout">
Want to support this work?<br />
Give a few dollars to your favorite instance or charity instead. If you feel like it, <a
href="https://mastodon.social/@box464">let me know</a>. ❤️ <br />
That would make me happy and provide incentive to keep tinkering.
</div>
<div>
Made by
<a href="https://box464.com" rel="me" target="_blank" rel="noopener">Jeff Sikes</a>
(<a href="https://mastodon.social/@box464" rel="me noopener" target="_blank">@box464</a>). Source on
<a class="underline text-green-800"
href="https://github.com/jeffsikes/mastodon-featured-profiles">GitHub</a>.<br />
</div>
</footer>
</div>
</div>
</body>
<script type="text/x-template" id="account-template">
<div class="account">
<article>
<header>
<div class="banner" :style="{backgroundImage: `url(${profile.header})`}" >
<div class="profile-account-info" >
<div>
<img class="avatar" :src="profile.avatar" alt="Avatar" loading="lazy"/>
</div>
<span v-if="profile.display_name" class="account-display-name">{{ profile.display_name }}</span>
<br/>
<a :href="profile.url" target="_blank" rel="me noopener">
<span v-if="profile.bot" data-tooltip="Automated Account" alt="Automated Account">🤖 </span>
<span v-if="profile.group" data-tooltip="Group Account" alt="Group Account">👥 </span>
<span v-if="profile.memorial" data-tooltip="Memorial Account" alt="Memorial Account">🌸 </span>@{{profile.acct }}
</a><br/>
<span v-if="profile.followers_count" class="account-followers">{{ profile.followers_count }} Followers</span><span class="account-followers" v-else>0 Followers</span>,
<span v-if="profile.following_count" class="account-following">{{ profile.following_count }} Following</span><span v-else class="account-following">0 Following</span>
<div class="profile-note">
<span v-if="profile.note" class="account-note" v-html="profile.note"></span>
</div>
</div>
</header>
</article>
</div>
</script>
<script type="text/x-template" id="endorsements-template">
<div class="endorsements">
<h2 style="padding-top:20px;">Featured Profiles</h2>
<div v-if="loading_endorsements == true">
<p>Loading {{ this.$root.total_endorsements_loaded }} of {{ this.$root.my_endorsements.length }} featured profiles...</p>
</div>
<div v-else>
<div v-if="this.$root.my_endorsements.length > this.$root.max_displayed_endorsements">
<p class="highlight">You have {{ this.$root.my_endorsements.length }} featured profiles. <mark><a class="small_action" href="#" @click="this.$root.refresh(this.$root.user_id, true)">Refresh</a></mark></p>
<p id="endorsed-descritpion">The first {{ this.filteredEndorsements.length }} are displayed. Search for a specific profile, or display them all.</p>
<input id="search-input-endorsed" type="search" v-model="searchValue" placeholder="Search your featured profiles" aria-label="Search Featured Profiles" aria-describedby="endorsed-description" />
<div class="endorsed-summary">
Found {{ filteredEndorsements.length }} accounts that match.</p>
</div>
</div>
<div v-if="this.endorsements.length == 0">
<hgroup>
<p><strong>You have no profiles currently selected.</strong> <mark><a href="#" class="small_action" @click="this.$root.refresh(this.$root.user_id, true)">Refresh</a></mark>
</p>
<p>Search your followed accounts for profiles to feature.</p>
</hgroup>
</div>
<div v-else>
<hgroup>
<p><strong>You have {{ this.$root.my_endorsements.length }} featured profile<span v-if="this.$root.my_endorsements.length > 1">s</span>.</strong> <mark><a class="small_action" href="#" @click="this.$root.refresh(this.$root.user_id, true)">Refresh</a></mark>
</p>
<p>Search your followed accounts for a profile to feature.</p>
</hgroup>
</div>
</div>
<div class="endorsed-container">
<article class="endorsed item" v-for="endorsement in filteredEndorsements" :id="endorsement.id" :key="endorsement.id" :style="{backgroundImage: `url(${endorsement.header})`}">
<div class="account-info">
<img class="avatar" :src="endorsement.avatar" alt="Avatar" loading="eager" />
<div style="text-align:center;">
<div v-if="endorsement.display_name" class="account-display-name" style="display:flex; align-items:center; justify-content:center;" v-html="this.$root.parse_emojis(endorsement.display_name, endorsement.emojis)"></div>
<p>
<span v-if="endorsement.group" alt="Group Account">👥 </span>
<span v-if="endorsement.bot" alt="Bot Account">🤖 </span>
<span v-if="endorsement.memorial" alt="Memorial Account">🌸 </span>
<a target="_followed" :href="'https://' + this.$root.userPreferences.server + '/@' + endorsement.acct" target="_blank" rel="me noopener">@{{ endorsement.acct }}</a>
</p>
</div>
<div class="endorsed-action">
<a v-if="this.$root.userPreferences.read_only == true" target="_followed" role="button" class="secondary unpin" :href="'https://' + this.$root.userPreferences.server + '/@' + endorsement.acct" :aria-label="`Remove featured profile for ${ endorsement.acct }`">Remove</a>
<button id="btnUnpin" v-else class="secondary unpin" @click="unpin(endorsement.id)" :aria-label="`Remove featured profile for ${ endorsement.acct }`">Remove</button>
</div>
</div>
</article>
<article class="account-placeholder"></article>
<article class="account-placeholder"></article>
<article class="account-placeholder"></article>
</div>
</div>
</div>
</script>
<script type="text/x-template" id="followed-template">
<h2>Followed Accounts</h2>
<div v-if="loading_followed == true">
<p>Loading {{ this.total_followed_loaded }} of {{ this.$root.my_account.following_count }} followed accounts...</p>
</div>
<div v-else>
<input v-if="this.$root.my_account.following_count < this.$root.followed_threshold" id="search-input" type="search" v-model="searchValue" aria-label="Search Followed Profiles" placeholder="Search for a profile to feature" />
<input v-else id="search-input" type="search" v-model="searchValue" @keyup="getFollowedAccounts" aria-label="Search with a minimum of two characters in the account name." placeholder="Search with a minimum of two characters in the account name."/>
<div class="followed-summary">
<p>Showing {{ filteredFollowed.length }} of {{ this.$root.my_account.following_count }} followed profiles <mark><a class="small_action" href="#" @click="this.$root.refresh(this.$root.user_id, true)">Refresh</a></mark></p>
</div>
<div class="followed-container" id="followed">
<article class="followed-account followed-item border-shadow" v-for="account in this.filteredFollowed" :key="account.id" :id="account.id" >
<img :src="account.avatar" alt="Avatar" loading="lazy" />
<div>
<span v-if="account.bot" data-tooltip="Automated Account" alt="This is an automated account">🤖 </span>
<span v-if="account.group" data-tooltip="Group Account" alt="This is a group account">👥 </span>
<span v-if="account.memorial" data-tooltip="Memorial Account" alt="This is a memorial account">🌸 </span>
<span>{{ account.display_name }}</span>
</div>
<div>
<a :href="account.url" target="_followed" rel="noopener">{{ account.acct }}</a>
</div>
<footer>
<div class="pin">
<a v-if="this.$root.userPreferences.read_only == true" target="_followed" role="button" :href="'https://' + this.$root.userPreferences.server + '/@' + account.acct" :aria-label="`Feature profile for ${ account.acct }`">Feature</a>
<button id="btnPin" v-else v-on:click="pin(account.id)">Feature</button>
</div>
</footer>
</article>
<article class="followed-placeholder"></article>
<article class="followed-placeholder"></article>
</div>
</script>
</html>