Implement LazyPage and refactor to support it
This commit is contained in:
parent
b0896a4e10
commit
5908ac6614
|
@ -11,7 +11,6 @@
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.accounts-page {
|
.accounts-page {
|
||||||
min-height: 60vh;
|
|
||||||
padding: 20px 20px;
|
padding: 20px 20px;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
15
routes/_components/LazyPage.html
Normal file
15
routes/_components/LazyPage.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{{#if revealed}}
|
||||||
|
<:Component {pageComponent} :params />
|
||||||
|
{{/if}}
|
||||||
|
<script>
|
||||||
|
import { scheduleIdleTask } from '../_utils/scheduleIdleTask'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
oncreate() {
|
||||||
|
scheduleIdleTask(() => this.set({revealed: true}))
|
||||||
|
},
|
||||||
|
data: () => ({
|
||||||
|
revealed: !process.browser
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -46,10 +46,12 @@
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
import Avatar from '../Avatar.html'
|
import Avatar from '../Avatar.html'
|
||||||
|
import { store } from '../../_store/store'
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Avatar
|
Avatar
|
||||||
},
|
},
|
||||||
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
verifyCredentials: ($currentVerifyCredentials) => $currentVerifyCredentials
|
verifyCredentials: ($currentVerifyCredentials) => $currentVerifyCredentials
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,7 @@
|
||||||
import NonAutoplayGifv from '../NonAutoplayGifv.html'
|
import NonAutoplayGifv from '../NonAutoplayGifv.html'
|
||||||
import PlayVideoIcon from '../PlayVideoIcon.html'
|
import PlayVideoIcon from '../PlayVideoIcon.html'
|
||||||
import { ONE_TRANSPARENT_PIXEL } from '../../_static/media'
|
import { ONE_TRANSPARENT_PIXEL } from '../../_static/media'
|
||||||
|
import { store } from '../../_store/store'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -140,6 +141,7 @@
|
||||||
data: () => ({
|
data: () => ({
|
||||||
oneTransparentPixel: ONE_TRANSPARENT_PIXEL
|
oneTransparentPixel: ONE_TRANSPARENT_PIXEL
|
||||||
}),
|
}),
|
||||||
|
store: () => store,
|
||||||
events: {
|
events: {
|
||||||
imgLoad,
|
imgLoad,
|
||||||
imgLoadError,
|
imgLoadError,
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
<style>
|
<style>
|
||||||
.lazy-timeline {
|
.lazy-timeline {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 60vh;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.timeline {
|
.timeline {
|
||||||
min-height: 60vh;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
56
routes/_pages/accounts/[accountId].html
Normal file
56
routes/_pages/accounts/[accountId].html
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
{{#if $isUserLoggedIn}}
|
||||||
|
<DynamicPageBanner title="" />
|
||||||
|
{{#if $currentAccountProfile}}
|
||||||
|
<AccountProfile profile="{{$currentAccountProfile}}"
|
||||||
|
relationship="{{$currentAccountRelationship}}"
|
||||||
|
verifyCredentials="{{$currentVerifyCredentials}}"
|
||||||
|
/>
|
||||||
|
{{/if}}
|
||||||
|
<PinnedStatuses accountId="{{params.accountId}}" />
|
||||||
|
<LazyTimeline timeline='account/{{params.accountId}}' />
|
||||||
|
{{else}}
|
||||||
|
<HiddenFromSSR>
|
||||||
|
<FreeTextLayout>
|
||||||
|
<h1>Profile</h1>
|
||||||
|
|
||||||
|
<p>A user timeline will appear here when logged in.</p>
|
||||||
|
</FreeTextLayout>
|
||||||
|
</HiddenFromSSR>
|
||||||
|
{{/if}}
|
||||||
|
<script>
|
||||||
|
import LazyTimeline from '../../_components/timeline/LazyTimeline.html'
|
||||||
|
import FreeTextLayout from '../../_components/FreeTextLayout.html'
|
||||||
|
import { store } from '../../_store/store.js'
|
||||||
|
import HiddenFromSSR from '../../_components/HiddenFromSSR'
|
||||||
|
import DynamicPageBanner from '../../_components/DynamicPageBanner.html'
|
||||||
|
import { updateProfileAndRelationship } from '../../_actions/accounts'
|
||||||
|
import AccountProfile from '../../_components/AccountProfile.html'
|
||||||
|
import { updateVerifyCredentialsForInstance } from '../../_actions/instances'
|
||||||
|
import PinnedStatuses from '../../_components/timeline/PinnedStatuses.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
oncreate() {
|
||||||
|
let accountId = this.get('params').accountId
|
||||||
|
let instanceName = this.store.get('currentInstance')
|
||||||
|
updateProfileAndRelationship(accountId)
|
||||||
|
updateVerifyCredentialsForInstance(instanceName)
|
||||||
|
},
|
||||||
|
store: () => store,
|
||||||
|
computed: {
|
||||||
|
profileName: ($currentAccountProfile) => {
|
||||||
|
return ($currentAccountProfile && ('@' + $currentAccountProfile.acct)) || ''
|
||||||
|
},
|
||||||
|
shortProfileName: ($currentAccountProfile) => {
|
||||||
|
return ($currentAccountProfile && ('@' + $currentAccountProfile.username)) || ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
LazyTimeline,
|
||||||
|
FreeTextLayout,
|
||||||
|
HiddenFromSSR,
|
||||||
|
DynamicPageBanner,
|
||||||
|
AccountProfile,
|
||||||
|
PinnedStatuses
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
20
routes/_pages/blocked.html
Normal file
20
routes/_pages/blocked.html
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<DynamicPageBanner title="Blocked users" icon="#fa-ban" />
|
||||||
|
<AccountsListPage :accountsFetcher />
|
||||||
|
<script>
|
||||||
|
import AccountsListPage from '.././_components/AccountsListPage.html'
|
||||||
|
import { store } from '.././_store/store'
|
||||||
|
import { getBlockedAccounts } from '.././_api/blockedAndMuted'
|
||||||
|
import DynamicPageBanner from '.././_components/DynamicPageBanner.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
statusId: params => params.statusId,
|
||||||
|
accountsFetcher: ($currentInstance, $accessToken, statusId) => () => getBlockedAccounts($currentInstance, $accessToken, statusId)
|
||||||
|
},
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
AccountsListPage,
|
||||||
|
DynamicPageBanner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
105
routes/_pages/community/index.html
Normal file
105
routes/_pages/community/index.html
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
{{#if $isUserLoggedIn}}
|
||||||
|
<div class="community-page">
|
||||||
|
|
||||||
|
<h2 class="community-header">
|
||||||
|
Timelines
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<PageList label="Timelines">
|
||||||
|
<PageListItem href="/local"
|
||||||
|
label="Local Timeline"
|
||||||
|
icon="#fa-users"
|
||||||
|
pinnable="true"
|
||||||
|
/>
|
||||||
|
<PageListItem href="/federated"
|
||||||
|
label="Federated Timeline"
|
||||||
|
icon="#fa-globe"
|
||||||
|
pinnable="true"
|
||||||
|
/>
|
||||||
|
<PageListItem href="/favorites"
|
||||||
|
label="Favorites"
|
||||||
|
icon="#fa-star"
|
||||||
|
pinnable="true"
|
||||||
|
/>
|
||||||
|
</PageList>
|
||||||
|
|
||||||
|
{{#if $lists.length}}
|
||||||
|
|
||||||
|
<h2 class="community-header">
|
||||||
|
Lists
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<PageList label="Lists">
|
||||||
|
{{#each $lists as list}}
|
||||||
|
<PageListItem href="/lists/{{list.id}}"
|
||||||
|
label="{{list.title}}"
|
||||||
|
icon="#fa-bars"
|
||||||
|
pinnable="true"
|
||||||
|
/>
|
||||||
|
{{/each}}
|
||||||
|
</PageList>
|
||||||
|
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<h2 class="community-header">
|
||||||
|
Instance settings
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<PageList label="Instance settings">
|
||||||
|
<PageListItem href="/muted"
|
||||||
|
label="Muted users"
|
||||||
|
icon="#fa-volume-off"
|
||||||
|
/>
|
||||||
|
<PageListItem href="/blocked"
|
||||||
|
label="Blocked users"
|
||||||
|
icon="#fa-ban"
|
||||||
|
/>
|
||||||
|
<PageListItem href="/pinned"
|
||||||
|
label="Pinned toots"
|
||||||
|
icon="#fa-thumb-tack"
|
||||||
|
/>
|
||||||
|
</PageList>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<HiddenFromSSR>
|
||||||
|
<FreeTextLayout>
|
||||||
|
<h1>Community</h1>
|
||||||
|
|
||||||
|
<p>Community options appear here when logged in.</p>
|
||||||
|
</FreeTextLayout>
|
||||||
|
</HiddenFromSSR>
|
||||||
|
{{/if}}
|
||||||
|
<style>
|
||||||
|
.community-page {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.community-page {
|
||||||
|
margin: 20px 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
import FreeTextLayout from '../../_components/FreeTextLayout.html'
|
||||||
|
import { store } from '../../_store/store.js'
|
||||||
|
import HiddenFromSSR from '../../_components/HiddenFromSSR'
|
||||||
|
import PageList from '../../_components/community/PageList.html'
|
||||||
|
import PageListItem from '../../_components/community/PageListItem.html'
|
||||||
|
import { updateLists } from '../../_actions/lists'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
async oncreate() {
|
||||||
|
if (this.store.get('currentInstance')) {
|
||||||
|
await updateLists()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
FreeTextLayout,
|
||||||
|
HiddenFromSSR,
|
||||||
|
PageList,
|
||||||
|
PageListItem
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
31
routes/_pages/favorites.html
Normal file
31
routes/_pages/favorites.html
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{{#if $isUserLoggedIn}}
|
||||||
|
{{#if $pinnedPage !== '/favorites'}}
|
||||||
|
<DynamicPageBanner title="Favorites" icon="#fa-star"/>
|
||||||
|
{{/if}}
|
||||||
|
<LazyTimeline timeline='favorites' />
|
||||||
|
{{else}}
|
||||||
|
<HiddenFromSSR>
|
||||||
|
<FreeTextLayout>
|
||||||
|
<h1>Favorites</h1>
|
||||||
|
|
||||||
|
<p>Your favorites will appear here when logged in.</p>
|
||||||
|
</FreeTextLayout>
|
||||||
|
</HiddenFromSSR>
|
||||||
|
{{/if}}
|
||||||
|
<script>
|
||||||
|
import LazyTimeline from '.././_components/timeline/LazyTimeline.html'
|
||||||
|
import FreeTextLayout from '.././_components/FreeTextLayout.html'
|
||||||
|
import { store } from '.././_store/store.js'
|
||||||
|
import HiddenFromSSR from '.././_components/HiddenFromSSR'
|
||||||
|
import DynamicPageBanner from '.././_components/DynamicPageBanner.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
LazyTimeline,
|
||||||
|
FreeTextLayout,
|
||||||
|
HiddenFromSSR,
|
||||||
|
DynamicPageBanner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
31
routes/_pages/federated.html
Normal file
31
routes/_pages/federated.html
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{{#if $isUserLoggedIn}}
|
||||||
|
{{#if $pinnedPage !== '/federated'}}
|
||||||
|
<DynamicPageBanner title="Federated Timeline" icon="#fa-globe"/>
|
||||||
|
{{/if}}
|
||||||
|
<LazyTimeline timeline='federated' />
|
||||||
|
{{else}}
|
||||||
|
<HiddenFromSSR>
|
||||||
|
<FreeTextLayout>
|
||||||
|
<h1>Federated</h1>
|
||||||
|
|
||||||
|
<p>Your federated timeline will appear here when logged in.</p>
|
||||||
|
</FreeTextLayout>
|
||||||
|
</HiddenFromSSR>
|
||||||
|
{{/if}}
|
||||||
|
<script>
|
||||||
|
import LazyTimeline from '.././_components/timeline/LazyTimeline.html'
|
||||||
|
import FreeTextLayout from '.././_components/FreeTextLayout.html'
|
||||||
|
import { store } from '.././_store/store.js'
|
||||||
|
import HiddenFromSSR from '.././_components/HiddenFromSSR'
|
||||||
|
import DynamicPageBanner from '.././_components/DynamicPageBanner.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
LazyTimeline,
|
||||||
|
FreeTextLayout,
|
||||||
|
HiddenFromSSR,
|
||||||
|
DynamicPageBanner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
25
routes/_pages/index.html
Normal file
25
routes/_pages/index.html
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{{#if $isUserLoggedIn}}
|
||||||
|
{{#if $currentVerifyCredentials}}
|
||||||
|
<ComposeBox realm="home" />
|
||||||
|
{{/if}}
|
||||||
|
<LazyTimeline timeline='home' />
|
||||||
|
{{else}}
|
||||||
|
<NotLoggedInHome/>
|
||||||
|
{{/if}}
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
import NotLoggedInHome from '.././_components/NotLoggedInHome.html'
|
||||||
|
import LazyTimeline from '.././_components/timeline/LazyTimeline.html'
|
||||||
|
import ComposeBox from '.././_components/compose/ComposeBox.html'
|
||||||
|
import { store } from '.././_store/store.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
LazyTimeline,
|
||||||
|
NotLoggedInHome,
|
||||||
|
ComposeBox
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
35
routes/_pages/lists/[listId].html
Normal file
35
routes/_pages/lists/[listId].html
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
{{#if $isUserLoggedIn}}
|
||||||
|
{{#if $pinnedPage !== `/lists/${params.listId}`}}
|
||||||
|
<DynamicPageBanner title="{{listTitle}}" icon="#fa-bars"/>
|
||||||
|
{{/if}}
|
||||||
|
<LazyTimeline timeline='list/{{params.listId}}' />
|
||||||
|
{{else}}
|
||||||
|
<HiddenFromSSR>
|
||||||
|
<FreeTextLayout>
|
||||||
|
<h1>List</h1>
|
||||||
|
|
||||||
|
<p>A list will appear here when logged in.</p>
|
||||||
|
</FreeTextLayout>
|
||||||
|
</HiddenFromSSR>
|
||||||
|
{{/if}}
|
||||||
|
<script>
|
||||||
|
import LazyTimeline from '../../_components/timeline/LazyTimeline.html'
|
||||||
|
import FreeTextLayout from '../../_components/FreeTextLayout.html'
|
||||||
|
import { store } from '../../_store/store.js'
|
||||||
|
import HiddenFromSSR from '../../_components/HiddenFromSSR'
|
||||||
|
import DynamicPageBanner from '../../_components/DynamicPageBanner.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
list: (params, $lists) => $lists && $lists.find(_ => _.id === params['listId']),
|
||||||
|
listTitle: (list) => list ? list.title : ''
|
||||||
|
},
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
LazyTimeline,
|
||||||
|
FreeTextLayout,
|
||||||
|
HiddenFromSSR,
|
||||||
|
DynamicPageBanner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
31
routes/_pages/local.html
Normal file
31
routes/_pages/local.html
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{{#if $isUserLoggedIn}}
|
||||||
|
{{#if $pinnedPage !== '/local'}}
|
||||||
|
<DynamicPageBanner title="Local Timeline" icon="#fa-users"/>
|
||||||
|
{{/if}}
|
||||||
|
<LazyTimeline timeline='local' />
|
||||||
|
{{else}}
|
||||||
|
<HiddenFromSSR>
|
||||||
|
<FreeTextLayout>
|
||||||
|
<h1>Local</h1>
|
||||||
|
|
||||||
|
<p>Your local timeline will appear here when logged in.</p>
|
||||||
|
</FreeTextLayout>
|
||||||
|
</HiddenFromSSR>
|
||||||
|
{{/if}}
|
||||||
|
<script>
|
||||||
|
import LazyTimeline from '.././_components/timeline/LazyTimeline.html'
|
||||||
|
import FreeTextLayout from '.././_components/FreeTextLayout.html'
|
||||||
|
import { store } from '.././_store/store.js'
|
||||||
|
import HiddenFromSSR from '.././_components/HiddenFromSSR'
|
||||||
|
import DynamicPageBanner from '.././_components/DynamicPageBanner.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
LazyTimeline,
|
||||||
|
FreeTextLayout,
|
||||||
|
HiddenFromSSR,
|
||||||
|
DynamicPageBanner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
20
routes/_pages/muted.html
Normal file
20
routes/_pages/muted.html
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<DynamicPageBanner title="Muted users" icon="#fa-volume-off" />
|
||||||
|
<AccountsListPage :accountsFetcher />
|
||||||
|
<script>
|
||||||
|
import AccountsListPage from '.././_components/AccountsListPage.html'
|
||||||
|
import { store } from '.././_store/store'
|
||||||
|
import { getMutedAccounts } from '.././_api/blockedAndMuted'
|
||||||
|
import DynamicPageBanner from '.././_components/DynamicPageBanner.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
statusId: params => params.statusId,
|
||||||
|
accountsFetcher: ($currentInstance, $accessToken, statusId) => () => getMutedAccounts($currentInstance, $accessToken, statusId)
|
||||||
|
},
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
AccountsListPage,
|
||||||
|
DynamicPageBanner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
26
routes/_pages/notifications.html
Normal file
26
routes/_pages/notifications.html
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{{#if $isUserLoggedIn}}
|
||||||
|
<LazyTimeline timeline='notifications' />
|
||||||
|
{{else}}
|
||||||
|
<HiddenFromSSR>
|
||||||
|
<FreeTextLayout>
|
||||||
|
<h1>Notifications</h1>
|
||||||
|
|
||||||
|
<p>Your notifications will appear here when logged in.</p>
|
||||||
|
</FreeTextLayout>
|
||||||
|
</HiddenFromSSR>
|
||||||
|
{{/if}}
|
||||||
|
<script>
|
||||||
|
import LazyTimeline from '.././_components/timeline/LazyTimeline.html'
|
||||||
|
import FreeTextLayout from '.././_components/FreeTextLayout.html'
|
||||||
|
import { store } from '.././_store/store.js'
|
||||||
|
import HiddenFromSSR from '.././_components/HiddenFromSSR'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
LazyTimeline,
|
||||||
|
FreeTextLayout,
|
||||||
|
HiddenFromSSR
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
66
routes/_pages/pinned.html
Normal file
66
routes/_pages/pinned.html
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
<DynamicPageBanner title="Pinned toots" icon="#fa-thumb-tack" />
|
||||||
|
<div class="pinned-toots-page">
|
||||||
|
{{#if loading}}
|
||||||
|
<LoadingPage />
|
||||||
|
{{elseif statuses && statuses.length}}
|
||||||
|
<ul class="pinned-toots-results">
|
||||||
|
{{#each statuses as status, index}}
|
||||||
|
<StatusSearchResult :status :index length="{{statuses.length}}" />
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
<style>
|
||||||
|
.pinned-toots-page {
|
||||||
|
padding: 20px 20px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.pinned-toots-results {
|
||||||
|
list-style: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid var(--main-border);
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.pinned-toots-page {
|
||||||
|
padding: 20px 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
import { store } from '.././_store/store'
|
||||||
|
import LoadingPage from '.././_components/LoadingPage.html'
|
||||||
|
import StatusSearchResult from '.././_components/search/StatusSearchResult.html'
|
||||||
|
import { toast } from '.././_utils/toast'
|
||||||
|
import DynamicPageBanner from '.././_components/DynamicPageBanner.html'
|
||||||
|
import { getPinnedStatuses } from '.././_api/pinnedStatuses'
|
||||||
|
import { updateVerifyCredentialsForInstance } from '.././_actions/instances'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
async oncreate() {
|
||||||
|
let accountsFetcher = this.get('accountsFetcher')
|
||||||
|
try {
|
||||||
|
let currentInstance = this.store.get('currentInstance')
|
||||||
|
await updateVerifyCredentialsForInstance(currentInstance)
|
||||||
|
let accessToken = this.store.get('accessToken')
|
||||||
|
let verifyCredentials = this.store.get('currentVerifyCredentials')
|
||||||
|
let statuses = await getPinnedStatuses(currentInstance, accessToken, verifyCredentials.id)
|
||||||
|
this.set({ statuses: statuses })
|
||||||
|
} catch (e) {
|
||||||
|
toast.say('Error: ' + (e.name || '') + ' ' + (e.message || ''))
|
||||||
|
} finally {
|
||||||
|
this.set({loading: false})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: () => ({
|
||||||
|
loading: true,
|
||||||
|
accounts: []
|
||||||
|
}),
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
LoadingPage,
|
||||||
|
StatusSearchResult,
|
||||||
|
DynamicPageBanner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
39
routes/_pages/search.html
Normal file
39
routes/_pages/search.html
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
{{#if $isUserLoggedIn}}
|
||||||
|
<div class="search-page">
|
||||||
|
<Search></Search>
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<HiddenFromSSR>
|
||||||
|
<FreeTextLayout>
|
||||||
|
<h1>Search</h1>
|
||||||
|
|
||||||
|
<p>You can search once logged in to an instance.</p>
|
||||||
|
</FreeTextLayout>
|
||||||
|
</HiddenFromSSR>
|
||||||
|
{{/if}}
|
||||||
|
<style>
|
||||||
|
.search-page {
|
||||||
|
padding: 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.search-page {
|
||||||
|
padding: 20px 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
import FreeTextLayout from '.././_components/FreeTextLayout.html'
|
||||||
|
import { store } from '.././_store/store.js'
|
||||||
|
import HiddenFromSSR from '.././_components/HiddenFromSSR'
|
||||||
|
import Search from '.././_components/search/Search.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
Search,
|
||||||
|
FreeTextLayout,
|
||||||
|
HiddenFromSSR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
24
routes/_pages/settings/about.html
Normal file
24
routes/_pages/settings/about.html
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<SettingsLayout page='settings/about' label="About Pinafore">
|
||||||
|
<h1>About Pinafore</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Pinafore is <ExternalLink href="https://github.com/nolanlawson/pinafore">free and open-source software</ExternalLink>
|
||||||
|
created by <ExternalLink href="https://nolanlawson.com">Nolan Lawson</ExternalLink> and distributed under the
|
||||||
|
<ExternalLink href="https://github.com/nolanlawson/pinafore/blob/master/LICENSE">GNU Affero General Public License</ExternalLink>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>Icons provided by <ExternalLink href="http://fontawesome.io/">Font Awesome</ExternalLink>.</p>
|
||||||
|
|
||||||
|
<p>Logo thanks to "sailboat" by Gregor Cresnar from <ExternalLink href="https://thenounproject.com/">the Noun Project</ExternalLink>.</p>
|
||||||
|
</SettingsLayout>
|
||||||
|
<script>
|
||||||
|
import SettingsLayout from '../../_components/settings/SettingsLayout.html'
|
||||||
|
import ExternalLink from '../../_components/ExternalLink.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
SettingsLayout,
|
||||||
|
ExternalLink
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
41
routes/_pages/settings/general.html
Normal file
41
routes/_pages/settings/general.html
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
<SettingsLayout page='settings/general' label="General">
|
||||||
|
<h1>General Settings</h1>
|
||||||
|
|
||||||
|
<h2>UI Settings</h2>
|
||||||
|
<form class="ui-settings" aria-label="UI settings">
|
||||||
|
<div class="setting-group">
|
||||||
|
<input type="checkbox" id="choice-autoplay-gif"
|
||||||
|
bind:checked="$autoplayGifs" on:change="store.save()">
|
||||||
|
<label for="choice-autoplay-gif">Autoplay GIFs</label>
|
||||||
|
</div>
|
||||||
|
<div class="setting-group">
|
||||||
|
<input type="checkbox" id="choice-mark-media-sensitive"
|
||||||
|
bind:checked="$markMediaAsSensitive" on:change="store.save()">
|
||||||
|
<label for="choice-mark-media-sensitive">Always mark media as sensitive</label>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</SettingsLayout>
|
||||||
|
<style>
|
||||||
|
.ui-settings {
|
||||||
|
background: var(--form-bg);
|
||||||
|
border: 1px solid var(--main-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 20px;
|
||||||
|
line-height: 2em;
|
||||||
|
}
|
||||||
|
.setting-group {
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
import SettingsLayout from '../../_components/settings/SettingsLayout.html'
|
||||||
|
import { store } from '../../_store/store'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
SettingsLayout
|
||||||
|
},
|
||||||
|
store: () => store
|
||||||
|
};
|
||||||
|
</script>
|
23
routes/_pages/settings/index.html
Normal file
23
routes/_pages/settings/index.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<SettingsLayout page='settings' label="Settings">
|
||||||
|
<h1>Settings</h1>
|
||||||
|
|
||||||
|
<SettingsList>
|
||||||
|
<SettingsListItem href="/settings/general" label="General"/>
|
||||||
|
<SettingsListItem href="/settings/instances" label="Instances"/>
|
||||||
|
<SettingsListItem href="/settings/about" label="About Pinafore"/>
|
||||||
|
</SettingsList>
|
||||||
|
|
||||||
|
</SettingsLayout>
|
||||||
|
<script>
|
||||||
|
import SettingsLayout from '../../_components/settings/SettingsLayout.html'
|
||||||
|
import SettingsList from '../../_components/settings/SettingsList.html'
|
||||||
|
import SettingsListItem from '../../_components/settings/SettingsListItem.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
SettingsLayout,
|
||||||
|
SettingsList,
|
||||||
|
SettingsListItem
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
151
routes/_pages/settings/instances/[instanceName].html
Normal file
151
routes/_pages/settings/instances/[instanceName].html
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
<SettingsLayout page='settings/instances/{{params.instanceName}}' label="{{params.instanceName}}">
|
||||||
|
<h1 class="instance-name-h1">{{params.instanceName}}</h1>
|
||||||
|
|
||||||
|
{{#if verifyCredentials}}
|
||||||
|
<h2>Logged in as:</h2>
|
||||||
|
<div class="acct-current-user">
|
||||||
|
<Avatar account="{{verifyCredentials}}" className="acct-avatar" size="big"/>
|
||||||
|
<ExternalLink class="acct-handle"
|
||||||
|
href="{{verifyCredentials.url}}">
|
||||||
|
{{'@' + verifyCredentials.acct}}
|
||||||
|
</ExternalLink>
|
||||||
|
<span class="acct-display-name">{{verifyCredentials.display_name || verifyCredentials.acct}}</span>
|
||||||
|
</div>
|
||||||
|
<h2>Theme:</h2>
|
||||||
|
<form class="theme-chooser" aria-label="Choose a theme">
|
||||||
|
{{#each themes as theme}}
|
||||||
|
<div class="theme-group">
|
||||||
|
<input type="radio" id="choice-theme-{{theme.name}}"
|
||||||
|
value="{{theme.name}}" checked="$currentTheme === theme.name"
|
||||||
|
bind:group="selectedTheme" on:change="onThemeChange()">
|
||||||
|
<label for="choice-theme-{{theme.name}}">{{theme.label}}</label>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form class="instance-actions" aria-label="Switch to or log out of this instance">
|
||||||
|
{{#if $loggedInInstancesInOrder.length > 1 && $currentInstance !== params.instanceName}}
|
||||||
|
<button class="primary"
|
||||||
|
on:click="onSwitchToThisInstance(event)">
|
||||||
|
Switch to this instance
|
||||||
|
</button>
|
||||||
|
{{/if}}
|
||||||
|
<button on:click="onLogOut(event)">Log out</button>
|
||||||
|
</form>
|
||||||
|
{{/if}}
|
||||||
|
</SettingsLayout>
|
||||||
|
<style>
|
||||||
|
.acct-current-user {
|
||||||
|
background: var(--form-bg);
|
||||||
|
border: 1px solid var(--main-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 20px;
|
||||||
|
display: grid;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 1.3em;
|
||||||
|
grid-template-areas:
|
||||||
|
"avatar handle"
|
||||||
|
"avatar display-name";
|
||||||
|
grid-template-columns: min-content 1fr;
|
||||||
|
grid-column-gap: 20px;
|
||||||
|
grid-row-gap: 10px;
|
||||||
|
}
|
||||||
|
:global(.acct-avatar) {
|
||||||
|
grid-area: avatar;
|
||||||
|
}
|
||||||
|
:global(.acct-handle) {
|
||||||
|
grid-area: handle;
|
||||||
|
}
|
||||||
|
.acct-display-name {
|
||||||
|
grid-area: display-name;
|
||||||
|
}
|
||||||
|
.theme-chooser {
|
||||||
|
background: var(--form-bg);
|
||||||
|
border: 1px solid var(--main-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
display: block;
|
||||||
|
padding: 20px;
|
||||||
|
line-height: 2em;
|
||||||
|
}
|
||||||
|
.theme-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.theme-chooser label {
|
||||||
|
margin: 2px 10px 0;
|
||||||
|
}
|
||||||
|
.instance-actions {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.instance-actions button {
|
||||||
|
margin: 0 5px;
|
||||||
|
flex-basis: 100%;
|
||||||
|
}
|
||||||
|
.instance-name-h1 {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
import { store } from '../../../_store/store'
|
||||||
|
import SettingsLayout from '../../../_components/settings/SettingsLayout.html'
|
||||||
|
import ExternalLink from '../../../_components/ExternalLink.html'
|
||||||
|
import Avatar from '../../../_components/Avatar.html'
|
||||||
|
import { importDialogs } from '../../../_utils/asyncModules'
|
||||||
|
import {
|
||||||
|
changeTheme,
|
||||||
|
switchToInstance,
|
||||||
|
logOutOfInstance,
|
||||||
|
updateVerifyCredentialsForInstance
|
||||||
|
} from '../../../_actions/instances'
|
||||||
|
import { themes } from '../../../_static/themes'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
SettingsLayout,
|
||||||
|
ExternalLink,
|
||||||
|
Avatar
|
||||||
|
},
|
||||||
|
store: () => store,
|
||||||
|
data: () => ({
|
||||||
|
themes: themes,
|
||||||
|
}),
|
||||||
|
async oncreate() {
|
||||||
|
let instanceName = this.get('instanceName')
|
||||||
|
await updateVerifyCredentialsForInstance(instanceName)
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
instanceName: (params) => params.instanceName,
|
||||||
|
selectedTheme: ($instanceThemes, instanceName) => $instanceThemes[instanceName],
|
||||||
|
verifyCredentials: ($verifyCredentials, instanceName) => $verifyCredentials && $verifyCredentials[instanceName]
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onThemeChange() {
|
||||||
|
let newTheme = this.get('selectedTheme')
|
||||||
|
let instanceName = this.get('instanceName')
|
||||||
|
changeTheme(instanceName, newTheme)
|
||||||
|
},
|
||||||
|
onSwitchToThisInstance(e) {
|
||||||
|
e.preventDefault()
|
||||||
|
let instanceName = this.get('instanceName')
|
||||||
|
switchToInstance(instanceName)
|
||||||
|
},
|
||||||
|
async onLogOut(e) {
|
||||||
|
e.preventDefault()
|
||||||
|
let instanceName = this.get('instanceName')
|
||||||
|
|
||||||
|
let dialogs = await importDialogs()
|
||||||
|
dialogs.showConfirmationDialog({
|
||||||
|
text: `Log out of ${instanceName}?`,
|
||||||
|
onPositive() {
|
||||||
|
logOutOfInstance(instanceName)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
90
routes/_pages/settings/instances/add.html
Normal file
90
routes/_pages/settings/instances/add.html
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
<SettingsLayout page='settings/instances/add' label="Add an Instance">
|
||||||
|
<h1 id="add-an-instance-h1">Add an Instance</h1>
|
||||||
|
|
||||||
|
{{#if $isUserLoggedIn}}
|
||||||
|
<p>Connect to an instance to log in.</p>
|
||||||
|
{{else}}
|
||||||
|
<p>Log in to an instance to use Pinafore.</p>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<form class="add-new-instance" on:submit='onSubmit(event)' aria-labelledby="add-an-instance-h1">
|
||||||
|
|
||||||
|
{{#if $logInToInstanceError && $logInToInstanceErrorForText === $instanceNameInSearch}}
|
||||||
|
<div class="form-error form-error-user-error" role="alert">
|
||||||
|
Error: {{$logInToInstanceError}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<noscript>
|
||||||
|
<div class="form-error" role="alert">
|
||||||
|
You must enable JavaScript to log in.
|
||||||
|
</div>
|
||||||
|
</noscript>
|
||||||
|
|
||||||
|
<label for="instanceInput">Instance:</label>
|
||||||
|
<input class="new-instance-input" type="text" id="instanceInput"
|
||||||
|
bind:value='$instanceNameInSearch' placeholder='' required
|
||||||
|
>
|
||||||
|
<button class="primary" type="submit" id="submitButton"
|
||||||
|
disabled="{{!$instanceNameInSearch || $logInToInstanceLoading}}">
|
||||||
|
Add instance
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{{#if !$isUserLoggedIn}}
|
||||||
|
<p>Don't have an instance? <ExternalLink href="https://joinmastodon.org">Join Mastodon!</ExternalLink></p>
|
||||||
|
{{/if}}
|
||||||
|
</SettingsLayout>
|
||||||
|
<style>
|
||||||
|
.form-error {
|
||||||
|
border: 2px solid red;
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 1.3em;
|
||||||
|
margin: 5px;
|
||||||
|
background-color: var(--main-bg);
|
||||||
|
}
|
||||||
|
input.new-instance-input {
|
||||||
|
min-width: 60%;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
form.add-new-instance {
|
||||||
|
background: var(--form-bg);
|
||||||
|
padding: 5px 10px 15px;
|
||||||
|
margin: 20px auto;
|
||||||
|
border: 1px solid var(--form-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form.add-new-instance label, form.add-new-instance input, form.add-new-instance button {
|
||||||
|
display: block;
|
||||||
|
margin: 20px 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
import SettingsLayout from '../../../_components/settings/SettingsLayout.html'
|
||||||
|
import { store } from '../../../_store/store'
|
||||||
|
import { logInToInstance, handleOauthCode } from '../../../_actions/addInstance'
|
||||||
|
import ExternalLink from '../../../_components/ExternalLink.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
async oncreate () {
|
||||||
|
let codeMatch = location.search.match(/code=([^&]+)/)
|
||||||
|
if (codeMatch) {
|
||||||
|
handleOauthCode(codeMatch[1])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
SettingsLayout,
|
||||||
|
ExternalLink
|
||||||
|
},
|
||||||
|
store: () => store,
|
||||||
|
methods: {
|
||||||
|
onSubmit(event) {
|
||||||
|
event.preventDefault()
|
||||||
|
logInToInstance()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
35
routes/_pages/settings/instances/index.html
Normal file
35
routes/_pages/settings/instances/index.html
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<SettingsLayout page='settings/instances' label="Instances">
|
||||||
|
<h1>Instances</h1>
|
||||||
|
|
||||||
|
{{#if $isUserLoggedIn}}
|
||||||
|
<p>Instances you've logged in to:</p>
|
||||||
|
<SettingsList label="Instances">
|
||||||
|
{{#each $loggedInInstancesAsList as instance}}
|
||||||
|
<SettingsListItem offsetForIcon="{{instance.name !== $currentInstance}}"
|
||||||
|
icon="{{instance.name === $currentInstance ? '#fa-star' : ''}}"
|
||||||
|
href="/settings/instances/{{instance.name}}"
|
||||||
|
label="{{instance.name}}"
|
||||||
|
ariaLabel="{{instance.name}} {{instance.name === $currentInstance ? '(current instance)' : ''}}" />
|
||||||
|
{{/each}}
|
||||||
|
</SettingsList>
|
||||||
|
<p><a href="/settings/instances/add">Add another instance</a></p>
|
||||||
|
{{else}}
|
||||||
|
<p>You're not logged in to any instances.</p>
|
||||||
|
<p><a href="/settings/instances/add">Log in to an instance</a> to start using Pinafore.</p>
|
||||||
|
{{/if}}
|
||||||
|
</SettingsLayout>
|
||||||
|
<script>
|
||||||
|
import { store } from '../../../_store/store'
|
||||||
|
import SettingsLayout from '../../../_components/settings/SettingsLayout.html'
|
||||||
|
import SettingsList from '../../../_components/settings/SettingsList.html'
|
||||||
|
import SettingsListItem from '../../../_components/settings/SettingsListItem.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
SettingsLayout,
|
||||||
|
SettingsList,
|
||||||
|
SettingsListItem
|
||||||
|
},
|
||||||
|
store: () => store
|
||||||
|
}
|
||||||
|
</script>
|
20
routes/_pages/statuses/[statusId]/favorites.html
Normal file
20
routes/_pages/statuses/[statusId]/favorites.html
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<DynamicPageBanner title="Favorites" icon="#fa-star" />
|
||||||
|
<AccountsListPage :accountsFetcher />
|
||||||
|
<script>
|
||||||
|
import { getFavorites } from '../../../_api/reblogsAndFavs'
|
||||||
|
import AccountsListPage from '../../../_components/AccountsListPage.html'
|
||||||
|
import { store } from '../../../_store/store'
|
||||||
|
import DynamicPageBanner from '../../../_components/DynamicPageBanner.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
statusId: params => params.statusId,
|
||||||
|
accountsFetcher: ($currentInstance, $accessToken, statusId) => () => getFavorites($currentInstance, $accessToken, statusId)
|
||||||
|
},
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
AccountsListPage,
|
||||||
|
DynamicPageBanner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
29
routes/_pages/statuses/[statusId]/index.html
Normal file
29
routes/_pages/statuses/[statusId]/index.html
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{{#if $isUserLoggedIn}}
|
||||||
|
<DynamicPageBanner title=""/>
|
||||||
|
<LazyTimeline timeline='status/{{params.statusId}}' />
|
||||||
|
{{else}}
|
||||||
|
<HiddenFromSSR>
|
||||||
|
<FreeTextLayout>
|
||||||
|
<h1>Status</h1>
|
||||||
|
|
||||||
|
<p>A status thread will appear here when logged in.</p>
|
||||||
|
</FreeTextLayout>
|
||||||
|
</HiddenFromSSR>
|
||||||
|
{{/if}}
|
||||||
|
<script>
|
||||||
|
import LazyTimeline from '../../../_components/timeline/LazyTimeline.html'
|
||||||
|
import FreeTextLayout from '../../../_components/FreeTextLayout.html'
|
||||||
|
import { store } from '../../../_store/store.js'
|
||||||
|
import HiddenFromSSR from '../../../_components/HiddenFromSSR'
|
||||||
|
import DynamicPageBanner from '../../../_components/DynamicPageBanner.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
LazyTimeline,
|
||||||
|
FreeTextLayout,
|
||||||
|
HiddenFromSSR,
|
||||||
|
DynamicPageBanner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
20
routes/_pages/statuses/[statusId]/reblogs.html
Normal file
20
routes/_pages/statuses/[statusId]/reblogs.html
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<DynamicPageBanner title="Boosts" icon="#fa-retweet" />
|
||||||
|
<AccountsListPage :accountsFetcher />
|
||||||
|
<script>
|
||||||
|
import { getReblogs } from '../../../_api/reblogsAndFavs'
|
||||||
|
import AccountsListPage from '../../../_components/AccountsListPage.html'
|
||||||
|
import { store } from '../../../_store/store'
|
||||||
|
import DynamicPageBanner from '../../../_components/DynamicPageBanner.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
statusId: params => params.statusId,
|
||||||
|
accountsFetcher: ($currentInstance, $accessToken, statusId) => () => getReblogs($currentInstance, $accessToken, statusId)
|
||||||
|
},
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
AccountsListPage,
|
||||||
|
DynamicPageBanner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
44
routes/_pages/statuses/[statusId]/reply.html
Normal file
44
routes/_pages/statuses/[statusId]/reply.html
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<DynamicPageBanner title=""/>
|
||||||
|
<div class="reply-container">
|
||||||
|
{{#if status}}
|
||||||
|
<Status index="0"
|
||||||
|
length="1"
|
||||||
|
timelineType="reply"
|
||||||
|
timelineValue="{{params.statusId}}"
|
||||||
|
:status
|
||||||
|
/>
|
||||||
|
<ComposeBox realm="{{params.statusId}}" />
|
||||||
|
{{else}}
|
||||||
|
<LoadingPage />
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
<style>
|
||||||
|
.reply-container {
|
||||||
|
position: relative;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
import { store } from '../../../_store/store.js'
|
||||||
|
import DynamicPageBanner from '../../../_components/DynamicPageBanner.html'
|
||||||
|
import LoadingPage from '../../../_components/LoadingPage.html'
|
||||||
|
import ComposeBox from '../../../_components/compose/ComposeBox.html'
|
||||||
|
import Status from '../../../_components/status/Status.html'
|
||||||
|
import { database } from '../../../_database/database'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
async oncreate() {
|
||||||
|
let statusId = this.get('params').statusId
|
||||||
|
let instanceName = this.store.get('currentInstance')
|
||||||
|
let status = await database.getStatus(instanceName, statusId)
|
||||||
|
this.set({status})
|
||||||
|
},
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
DynamicPageBanner,
|
||||||
|
LoadingPage,
|
||||||
|
ComposeBox,
|
||||||
|
Status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
29
routes/_pages/tags/[tagName].html
Normal file
29
routes/_pages/tags/[tagName].html
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{{#if $isUserLoggedIn}}
|
||||||
|
<DynamicPageBanner title="{{'#' + params.tagName}}"/>
|
||||||
|
<LazyTimeline timeline='tag/{{params.tagName}}' />
|
||||||
|
{{else}}
|
||||||
|
<HiddenFromSSR>
|
||||||
|
<FreeTextLayout>
|
||||||
|
<h1>#{{params.tagName}}</h1>
|
||||||
|
|
||||||
|
<p>A hashtag timeline will appear here when logged in.</p>
|
||||||
|
</FreeTextLayout>
|
||||||
|
</HiddenFromSSR>
|
||||||
|
{{/if}}
|
||||||
|
<script>
|
||||||
|
import LazyTimeline from '../../_components/timeline/LazyTimeline.html'
|
||||||
|
import FreeTextLayout from '../../_components/FreeTextLayout.html'
|
||||||
|
import { store } from '../../_store/store.js'
|
||||||
|
import HiddenFromSSR from '../../_components/HiddenFromSSR'
|
||||||
|
import DynamicPageBanner from '../../_components/DynamicPageBanner.html'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
store: () => store,
|
||||||
|
components: {
|
||||||
|
LazyTimeline,
|
||||||
|
FreeTextLayout,
|
||||||
|
HiddenFromSSR,
|
||||||
|
DynamicPageBanner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,64 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – {{profileName}}</title>
|
<title>Pinafore – {{profileName}}</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='tags'>
|
<Layout page='tags'>
|
||||||
{{#if $isUserLoggedIn}}
|
<LazyPage :pageComponent :params />
|
||||||
<DynamicPageBanner title="" />
|
|
||||||
{{#if $currentAccountProfile}}
|
|
||||||
<AccountProfile profile="{{$currentAccountProfile}}"
|
|
||||||
relationship="{{$currentAccountRelationship}}"
|
|
||||||
verifyCredentials="{{$currentVerifyCredentials}}"
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
<PinnedStatuses accountId="{{params.accountId}}" />
|
|
||||||
<LazyTimeline timeline='account/{{params.accountId}}' />
|
|
||||||
{{else}}
|
|
||||||
<HiddenFromSSR>
|
|
||||||
<FreeTextLayout>
|
|
||||||
<h1>Profile</h1>
|
|
||||||
|
|
||||||
<p>A user timeline will appear here when logged in.</p>
|
|
||||||
</FreeTextLayout>
|
|
||||||
</HiddenFromSSR>
|
|
||||||
{{/if}}
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<script>
|
<script>
|
||||||
import Layout from '../_components/Layout.html'
|
import Layout from '../_components/Layout.html'
|
||||||
import LazyTimeline from '../_components/timeline/LazyTimeline.html'
|
import LazyPage from '../_components/LazyPage.html'
|
||||||
import FreeTextLayout from '../_components/FreeTextLayout.html'
|
import pageComponent from '../_pages/accounts/[accountId].html'
|
||||||
import { store } from '../_store/store.js'
|
|
||||||
import HiddenFromSSR from '../_components/HiddenFromSSR'
|
|
||||||
import DynamicPageBanner from '../_components/DynamicPageBanner.html'
|
|
||||||
import { updateProfileAndRelationship } from '../_actions/accounts'
|
|
||||||
import AccountProfile from '../_components/AccountProfile.html'
|
|
||||||
import { updateVerifyCredentialsForInstance } from '../_actions/instances'
|
|
||||||
import PinnedStatuses from '../_components/timeline/PinnedStatuses.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
oncreate() {
|
|
||||||
let accountId = this.get('params').accountId
|
|
||||||
let instanceName = this.store.get('currentInstance')
|
|
||||||
updateProfileAndRelationship(accountId)
|
|
||||||
updateVerifyCredentialsForInstance(instanceName)
|
|
||||||
},
|
|
||||||
store: () => store,
|
|
||||||
computed: {
|
|
||||||
profileName: ($currentAccountProfile) => {
|
|
||||||
return ($currentAccountProfile && ('@' + $currentAccountProfile.acct)) || ''
|
|
||||||
},
|
|
||||||
shortProfileName: ($currentAccountProfile) => {
|
|
||||||
return ($currentAccountProfile && ('@' + $currentAccountProfile.username)) || ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
LazyTimeline,
|
LazyPage
|
||||||
FreeTextLayout,
|
},
|
||||||
HiddenFromSSR,
|
data: () => ({
|
||||||
DynamicPageBanner,
|
pageComponent
|
||||||
AccountProfile,
|
})
|
||||||
PinnedStatuses
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,28 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Blocked users</title>
|
<title>Pinafore – Blocked users</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='blocked'>
|
<Layout page='blocked'>
|
||||||
<DynamicPageBanner title="Blocked users" icon="#fa-ban" />
|
<LazyPage :pageComponent :params />
|
||||||
<AccountsListPage :accountsFetcher />
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<script>
|
<script>
|
||||||
import Layout from './_components/Layout.html'
|
import Layout from './_components/Layout.html'
|
||||||
import AccountsListPage from './_components/AccountsListPage.html'
|
import LazyPage from './_components/LazyPage.html'
|
||||||
import { store } from './_store/store'
|
import pageComponent from './_pages/blocked.html'
|
||||||
import { getBlockedAccounts } from './_api/blockedAndMuted'
|
|
||||||
import DynamicPageBanner from './_components/DynamicPageBanner.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
|
||||||
statusId: params => params.statusId,
|
|
||||||
accountsFetcher: ($currentInstance, $accessToken, statusId) => () => getBlockedAccounts($currentInstance, $accessToken, statusId)
|
|
||||||
},
|
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
AccountsListPage,
|
LazyPage
|
||||||
DynamicPageBanner
|
},
|
||||||
}
|
data: () => ({
|
||||||
|
pageComponent
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,111 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Community</title>
|
<title>Pinafore – Community</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='community'>
|
<Layout page='community'>
|
||||||
{{#if $isUserLoggedIn}}
|
<LazyPage :pageComponent :params />
|
||||||
<div class="community-page">
|
|
||||||
|
|
||||||
<h2 class="community-header">
|
|
||||||
Timelines
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<PageList label="Timelines">
|
|
||||||
<PageListItem href="/local"
|
|
||||||
label="Local Timeline"
|
|
||||||
icon="#fa-users"
|
|
||||||
pinnable="true"
|
|
||||||
/>
|
|
||||||
<PageListItem href="/federated"
|
|
||||||
label="Federated Timeline"
|
|
||||||
icon="#fa-globe"
|
|
||||||
pinnable="true"
|
|
||||||
/>
|
|
||||||
<PageListItem href="/favorites"
|
|
||||||
label="Favorites"
|
|
||||||
icon="#fa-star"
|
|
||||||
pinnable="true"
|
|
||||||
/>
|
|
||||||
</PageList>
|
|
||||||
|
|
||||||
{{#if $lists.length}}
|
|
||||||
|
|
||||||
<h2 class="community-header">
|
|
||||||
Lists
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<PageList label="Lists">
|
|
||||||
{{#each $lists as list}}
|
|
||||||
<PageListItem href="/lists/{{list.id}}"
|
|
||||||
label="{{list.title}}"
|
|
||||||
icon="#fa-bars"
|
|
||||||
pinnable="true"
|
|
||||||
/>
|
|
||||||
{{/each}}
|
|
||||||
</PageList>
|
|
||||||
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<h2 class="community-header">
|
|
||||||
Instance settings
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<PageList label="Instance settings">
|
|
||||||
<PageListItem href="/muted"
|
|
||||||
label="Muted users"
|
|
||||||
icon="#fa-volume-off"
|
|
||||||
/>
|
|
||||||
<PageListItem href="/blocked"
|
|
||||||
label="Blocked users"
|
|
||||||
icon="#fa-ban"
|
|
||||||
/>
|
|
||||||
<PageListItem href="/pinned"
|
|
||||||
label="Pinned toots"
|
|
||||||
icon="#fa-thumb-tack"
|
|
||||||
/>
|
|
||||||
</PageList>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
{{else}}
|
|
||||||
<HiddenFromSSR>
|
|
||||||
<FreeTextLayout>
|
|
||||||
<h1>Community</h1>
|
|
||||||
|
|
||||||
<p>Community options appear here when logged in.</p>
|
|
||||||
</FreeTextLayout>
|
|
||||||
</HiddenFromSSR>
|
|
||||||
{{/if}}
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<style>
|
|
||||||
.community-page {
|
|
||||||
margin: 20px;
|
|
||||||
}
|
|
||||||
@media (max-width: 767px) {
|
|
||||||
.community-page {
|
|
||||||
margin: 20px 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
<script>
|
||||||
import Layout from '../_components/Layout.html'
|
import Layout from '../_components/Layout.html'
|
||||||
import FreeTextLayout from '../_components/FreeTextLayout.html'
|
import LazyPage from '../_components/LazyPage.html'
|
||||||
import { store } from '../_store/store.js'
|
import pageComponent from '../_pages/community/index.html'
|
||||||
import HiddenFromSSR from '../_components/HiddenFromSSR'
|
|
||||||
import PageList from './_components/PageList.html'
|
|
||||||
import PageListItem from './_components/PageListItem.html'
|
|
||||||
import { updateLists } from '../_actions/lists'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
async oncreate() {
|
|
||||||
await updateLists()
|
|
||||||
},
|
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
FreeTextLayout,
|
LazyPage
|
||||||
HiddenFromSSR,
|
},
|
||||||
PageList,
|
data: () => ({
|
||||||
PageListItem
|
pageComponent
|
||||||
|
})
|
||||||
}
|
}
|
||||||
};
|
|
||||||
</script>
|
</script>
|
|
@ -1,40 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Favorites</title>
|
<title>Pinafore – Favorites</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='favorites'>
|
<Layout page='favorites'>
|
||||||
{{#if $isUserLoggedIn}}
|
<LazyPage :pageComponent :params />
|
||||||
{{#if $pinnedPage !== '/favorites'}}
|
|
||||||
<DynamicPageBanner title="Favorites" icon="#fa-star"/>
|
|
||||||
{{/if}}
|
|
||||||
<LazyTimeline timeline='favorites' />
|
|
||||||
{{else}}
|
|
||||||
<HiddenFromSSR>
|
|
||||||
<FreeTextLayout>
|
|
||||||
<h1>Favorites</h1>
|
|
||||||
|
|
||||||
<p>Your favorites will appear here when logged in.</p>
|
|
||||||
</FreeTextLayout>
|
|
||||||
</HiddenFromSSR>
|
|
||||||
{{/if}}
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Layout from './_components/Layout.html'
|
import Layout from './_components/Layout.html'
|
||||||
import LazyTimeline from './_components/timeline/LazyTimeline.html'
|
import LazyPage from './_components/LazyPage.html'
|
||||||
import FreeTextLayout from './_components/FreeTextLayout.html'
|
import pageComponent from './_pages/favorites.html'
|
||||||
import { store } from './_store/store.js'
|
|
||||||
import HiddenFromSSR from './_components/HiddenFromSSR'
|
|
||||||
import DynamicPageBanner from './_components/DynamicPageBanner.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
LazyTimeline,
|
LazyPage
|
||||||
FreeTextLayout,
|
},
|
||||||
HiddenFromSSR,
|
data: () => ({
|
||||||
DynamicPageBanner
|
pageComponent
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,40 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Federated</title>
|
<title>Pinafore – Federated</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='federated'>
|
<Layout page='federated'>
|
||||||
{{#if $isUserLoggedIn}}
|
<LazyPage :pageComponent :params />
|
||||||
{{#if $pinnedPage !== '/federated'}}
|
|
||||||
<DynamicPageBanner title="Federated Timeline" icon="#fa-globe"/>
|
|
||||||
{{/if}}
|
|
||||||
<LazyTimeline timeline='federated' />
|
|
||||||
{{else}}
|
|
||||||
<HiddenFromSSR>
|
|
||||||
<FreeTextLayout>
|
|
||||||
<h1>Federated</h1>
|
|
||||||
|
|
||||||
<p>Your federated timeline will appear here when logged in.</p>
|
|
||||||
</FreeTextLayout>
|
|
||||||
</HiddenFromSSR>
|
|
||||||
{{/if}}
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Layout from './_components/Layout.html'
|
import Layout from './_components/Layout.html'
|
||||||
import LazyTimeline from './_components/timeline/LazyTimeline.html'
|
import LazyPage from './_components/LazyPage.html'
|
||||||
import FreeTextLayout from './_components/FreeTextLayout.html'
|
import pageComponent from './_pages/federated.html'
|
||||||
import { store } from './_store/store.js'
|
|
||||||
import HiddenFromSSR from './_components/HiddenFromSSR'
|
|
||||||
import DynamicPageBanner from './_components/DynamicPageBanner.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
LazyTimeline,
|
LazyPage
|
||||||
FreeTextLayout,
|
},
|
||||||
HiddenFromSSR,
|
data: () => ({
|
||||||
DynamicPageBanner
|
pageComponent
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,35 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Home</title>
|
<title>Pinafore – Home</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='home'>
|
<Layout page='home'>
|
||||||
{{#if $isUserLoggedIn}}
|
<LazyPage :pageComponent :params />
|
||||||
{{#if $currentVerifyCredentials}}
|
|
||||||
<ComposeBox realm="home" />
|
|
||||||
{{/if}}
|
|
||||||
<LazyTimeline timeline='home' />
|
|
||||||
{{else}}
|
|
||||||
<NotLoggedInHome/>
|
|
||||||
{{/if}}
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Layout from './_components/Layout.html'
|
import Layout from './_components/Layout.html'
|
||||||
import NotLoggedInHome from './_components/NotLoggedInHome.html'
|
import LazyPage from './_components/LazyPage.html'
|
||||||
import LazyTimeline from './_components/timeline/LazyTimeline.html'
|
import pageComponent from './_pages/index.html'
|
||||||
import ComposeBox from './_components/compose/ComposeBox.html'
|
|
||||||
import { store } from './_store/store.js'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
LazyTimeline,
|
LazyPage
|
||||||
NotLoggedInHome,
|
},
|
||||||
ComposeBox
|
data: () => ({
|
||||||
}
|
pageComponent
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
|
||||||
</style>
|
|
|
@ -1,43 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – {{listTitle}}</title>
|
<title>Pinafore – {{listTitle}}</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='lists'>
|
<Layout page='lists'>
|
||||||
{{#if $isUserLoggedIn}}
|
<LazyPage :pageComponent :params />
|
||||||
{{#if $pinnedPage !== `/lists/${params.listId}`}}
|
|
||||||
<DynamicPageBanner title="{{listTitle}}" icon="#fa-bars"/>
|
|
||||||
{{/if}}
|
|
||||||
<LazyTimeline timeline='list/{{params.listId}}' />
|
|
||||||
{{else}}
|
|
||||||
<HiddenFromSSR>
|
|
||||||
<FreeTextLayout>
|
|
||||||
<h1>List</h1>
|
|
||||||
|
|
||||||
<p>A list will appear here when logged in.</p>
|
|
||||||
</FreeTextLayout>
|
|
||||||
</HiddenFromSSR>
|
|
||||||
{{/if}}
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<script>
|
<script>
|
||||||
import Layout from '../_components/Layout.html'
|
import Layout from '../_components/Layout.html'
|
||||||
import LazyTimeline from '../_components/timeline/LazyTimeline.html'
|
import LazyPage from '../_components/LazyPage.html'
|
||||||
import FreeTextLayout from '../_components/FreeTextLayout.html'
|
import pageComponent from '../_pages/lists/[listId].html'
|
||||||
import { store } from '../_store/store.js'
|
|
||||||
import HiddenFromSSR from '../_components/HiddenFromSSR'
|
|
||||||
import DynamicPageBanner from '../_components/DynamicPageBanner.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
|
||||||
list: (params, $lists) => $lists && $lists.find(_ => _.id === params['listId']),
|
|
||||||
listTitle: (list) => list ? list.title : ''
|
|
||||||
},
|
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
LazyTimeline,
|
LazyPage
|
||||||
FreeTextLayout,
|
},
|
||||||
HiddenFromSSR,
|
data: () => ({
|
||||||
DynamicPageBanner
|
pageComponent
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,40 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Local</title>
|
<title>Pinafore – Local</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='local'>
|
<Layout page='local'>
|
||||||
{{#if $isUserLoggedIn}}
|
<LazyPage :pageComponent :params />
|
||||||
{{#if $pinnedPage !== '/local'}}
|
|
||||||
<DynamicPageBanner title="Local Timeline" icon="#fa-users"/>
|
|
||||||
{{/if}}
|
|
||||||
<LazyTimeline timeline='local' />
|
|
||||||
{{else}}
|
|
||||||
<HiddenFromSSR>
|
|
||||||
<FreeTextLayout>
|
|
||||||
<h1>Local</h1>
|
|
||||||
|
|
||||||
<p>Your local timeline will appear here when logged in.</p>
|
|
||||||
</FreeTextLayout>
|
|
||||||
</HiddenFromSSR>
|
|
||||||
{{/if}}
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Layout from './_components/Layout.html'
|
import Layout from './_components/Layout.html'
|
||||||
import LazyTimeline from './_components/timeline/LazyTimeline.html'
|
import LazyPage from './_components/LazyPage.html'
|
||||||
import FreeTextLayout from './_components/FreeTextLayout.html'
|
import pageComponent from './_pages/local.html'
|
||||||
import { store } from './_store/store.js'
|
|
||||||
import HiddenFromSSR from './_components/HiddenFromSSR'
|
|
||||||
import DynamicPageBanner from './_components/DynamicPageBanner.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
LazyTimeline,
|
LazyPage
|
||||||
FreeTextLayout,
|
},
|
||||||
HiddenFromSSR,
|
data: () => ({
|
||||||
DynamicPageBanner
|
pageComponent
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,28 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Muted users</title>
|
<title>Pinafore – Muted users</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='muted'>
|
<Layout page='muted'>
|
||||||
<DynamicPageBanner title="Muted users" icon="#fa-volume-off" />
|
<LazyPage :pageComponent :params />
|
||||||
<AccountsListPage :accountsFetcher />
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<script>
|
<script>
|
||||||
import Layout from './_components/Layout.html'
|
import Layout from './_components/Layout.html'
|
||||||
import AccountsListPage from './_components/AccountsListPage.html'
|
import LazyPage from './_components/LazyPage.html'
|
||||||
import { store } from './_store/store'
|
import pageComponent from './_pages/muted.html'
|
||||||
import { getMutedAccounts } from './_api/blockedAndMuted'
|
|
||||||
import DynamicPageBanner from './_components/DynamicPageBanner.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
|
||||||
statusId: params => params.statusId,
|
|
||||||
accountsFetcher: ($currentInstance, $accessToken, statusId) => () => getMutedAccounts($currentInstance, $accessToken, statusId)
|
|
||||||
},
|
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
AccountsListPage,
|
LazyPage
|
||||||
DynamicPageBanner
|
},
|
||||||
}
|
data: () => ({
|
||||||
|
pageComponent
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,35 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Notifications</title>
|
<title>Pinafore – Notifications</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='notifications'>
|
<Layout page='notifications'>
|
||||||
{{#if $isUserLoggedIn}}
|
<LazyPage :pageComponent :params />
|
||||||
<LazyTimeline timeline='notifications' />
|
|
||||||
{{else}}
|
|
||||||
<HiddenFromSSR>
|
|
||||||
<FreeTextLayout>
|
|
||||||
<h1>Notifications</h1>
|
|
||||||
|
|
||||||
<p>Your notifications will appear here when logged in.</p>
|
|
||||||
</FreeTextLayout>
|
|
||||||
</HiddenFromSSR>
|
|
||||||
{{/if}}
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Layout from './_components/Layout.html'
|
import Layout from './_components/Layout.html'
|
||||||
import LazyTimeline from './_components/timeline/LazyTimeline.html'
|
import LazyPage from './_components/LazyPage.html'
|
||||||
import FreeTextLayout from './_components/FreeTextLayout.html'
|
import pageComponent from './_pages/notifications.html'
|
||||||
import { store } from './_store/store.js'
|
|
||||||
import HiddenFromSSR from './_components/HiddenFromSSR'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
LazyTimeline,
|
LazyPage
|
||||||
FreeTextLayout,
|
},
|
||||||
HiddenFromSSR
|
data: () => ({
|
||||||
|
pageComponent
|
||||||
|
})
|
||||||
}
|
}
|
||||||
};
|
|
||||||
</script>
|
</script>
|
|
@ -1,75 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Pinned toots</title>
|
<title>Pinafore – Pinned toots</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='pinned'>
|
<Layout page='pinned'>
|
||||||
<DynamicPageBanner title="Pinned toots" icon="#fa-thumb-tack" />
|
<LazyPage :pageComponent :params />
|
||||||
<div class="pinned-toots-page">
|
|
||||||
{{#if loading}}
|
|
||||||
<LoadingPage />
|
|
||||||
{{elseif statuses && statuses.length}}
|
|
||||||
<ul class="pinned-toots-results">
|
|
||||||
{{#each statuses as status, index}}
|
|
||||||
<StatusSearchResult :status :index length="{{statuses.length}}" />
|
|
||||||
{{/each}}
|
|
||||||
</ul>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<style>
|
|
||||||
.pinned-toots-page {
|
|
||||||
min-height: 60vh;
|
|
||||||
padding: 20px 20px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.pinned-toots-results {
|
|
||||||
list-style: none;
|
|
||||||
box-sizing: border-box;
|
|
||||||
border: 1px solid var(--main-border);
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
@media (max-width: 767px) {
|
|
||||||
.pinned-toots-page {
|
|
||||||
padding: 20px 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
<script>
|
||||||
import Layout from './_components/Layout.html'
|
import Layout from './_components/Layout.html'
|
||||||
import { store } from './_store/store'
|
import LazyPage from './_components/LazyPage.html'
|
||||||
import LoadingPage from './_components/LoadingPage.html'
|
import pageComponent from './_pages/pinned.html'
|
||||||
import StatusSearchResult from './_components/search/StatusSearchResult.html'
|
|
||||||
import { toast } from './_utils/toast'
|
|
||||||
import DynamicPageBanner from './_components/DynamicPageBanner.html'
|
|
||||||
import { getPinnedStatuses } from './_api/pinnedStatuses'
|
|
||||||
import { updateVerifyCredentialsForInstance } from './_actions/instances'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
async oncreate() {
|
|
||||||
let accountsFetcher = this.get('accountsFetcher')
|
|
||||||
try {
|
|
||||||
let currentInstance = this.store.get('currentInstance')
|
|
||||||
await updateVerifyCredentialsForInstance(currentInstance)
|
|
||||||
let accessToken = this.store.get('accessToken')
|
|
||||||
let verifyCredentials = this.store.get('currentVerifyCredentials')
|
|
||||||
let statuses = await getPinnedStatuses(currentInstance, accessToken, verifyCredentials.id)
|
|
||||||
this.set({ statuses: statuses })
|
|
||||||
} catch (e) {
|
|
||||||
toast.say('Error: ' + (e.name || '') + ' ' + (e.message || ''))
|
|
||||||
} finally {
|
|
||||||
this.set({loading: false})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: () => ({
|
|
||||||
loading: true,
|
|
||||||
accounts: []
|
|
||||||
}),
|
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
LoadingPage,
|
LazyPage
|
||||||
StatusSearchResult,
|
},
|
||||||
DynamicPageBanner
|
data: () => ({
|
||||||
}
|
pageComponent
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,48 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Search</title>
|
<title>Pinafore – Search</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='search'>
|
<Layout page='search'>
|
||||||
{{#if $isUserLoggedIn}}
|
<LazyPage :pageComponent :params />
|
||||||
<div class="search-page">
|
|
||||||
<Search></Search>
|
|
||||||
</div>
|
|
||||||
{{else}}
|
|
||||||
<HiddenFromSSR>
|
|
||||||
<FreeTextLayout>
|
|
||||||
<h1>Search</h1>
|
|
||||||
|
|
||||||
<p>You can search once logged in to an instance.</p>
|
|
||||||
</FreeTextLayout>
|
|
||||||
</HiddenFromSSR>
|
|
||||||
{{/if}}
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<style>
|
|
||||||
.search-page {
|
|
||||||
min-height: 60vh;
|
|
||||||
padding: 20px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
|
||||||
.search-page {
|
|
||||||
padding: 20px 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
<script>
|
||||||
import Layout from './_components/Layout.html'
|
import Layout from './_components/Layout.html'
|
||||||
import FreeTextLayout from './_components/FreeTextLayout.html'
|
import LazyPage from './_components/LazyPage.html'
|
||||||
import { store } from './_store/store.js'
|
import pageComponent from './_pages/search.html'
|
||||||
import HiddenFromSSR from './_components/HiddenFromSSR'
|
|
||||||
import Search from './_components/search/Search.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
Search,
|
LazyPage
|
||||||
FreeTextLayout,
|
},
|
||||||
HiddenFromSSR
|
data: () => ({
|
||||||
}
|
pageComponent
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,33 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – About</title>
|
<title>Pinafore – About</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='settings'>
|
<Layout page='settings'>
|
||||||
<SettingsLayout page='settings/about' label="About Pinafore">
|
<LazyPage :pageComponent :params />
|
||||||
<h1>About Pinafore</h1>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Pinafore is <ExternalLink href="https://github.com/nolanlawson/pinafore">free and open-source software</ExternalLink>
|
|
||||||
created by <ExternalLink href="https://nolanlawson.com">Nolan Lawson</ExternalLink> and distributed under the
|
|
||||||
<ExternalLink href="https://github.com/nolanlawson/pinafore/blob/master/LICENSE">GNU Affero General Public License</ExternalLink>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>Icons provided by <ExternalLink href="http://fontawesome.io/">Font Awesome</ExternalLink>.</p>
|
|
||||||
|
|
||||||
<p>Logo thanks to "sailboat" by Gregor Cresnar from <ExternalLink href="https://thenounproject.com/">the Noun Project</ExternalLink>.</p>
|
|
||||||
</SettingsLayout>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Layout from '../_components/Layout.html';
|
import Layout from '../_components/Layout.html'
|
||||||
import SettingsLayout from './_components/SettingsLayout.html'
|
import LazyPage from '../_components/LazyPage.html'
|
||||||
import ExternalLink from '../_components/ExternalLink.html'
|
import pageComponent from '../_pages/settings/about.html'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
SettingsLayout,
|
LazyPage
|
||||||
ExternalLink
|
},
|
||||||
|
data: () => ({
|
||||||
|
pageComponent
|
||||||
|
})
|
||||||
}
|
}
|
||||||
};
|
|
||||||
</script>
|
</script>
|
|
@ -1,50 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – General Settings</title>
|
<title>Pinafore – General Settings</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='settings'>
|
<Layout page='settings'>
|
||||||
<SettingsLayout page='settings/general' label="General">
|
<LazyPage :pageComponent :params />
|
||||||
<h1>General Settings</h1>
|
|
||||||
|
|
||||||
<h2>UI Settings</h2>
|
|
||||||
<form class="ui-settings" aria-label="UI settings">
|
|
||||||
<div class="setting-group">
|
|
||||||
<input type="checkbox" id="choice-autoplay-gif"
|
|
||||||
bind:checked="$autoplayGifs" on:change="store.save()">
|
|
||||||
<label for="choice-autoplay-gif">Autoplay GIFs</label>
|
|
||||||
</div>
|
|
||||||
<div class="setting-group">
|
|
||||||
<input type="checkbox" id="choice-mark-media-sensitive"
|
|
||||||
bind:checked="$markMediaAsSensitive" on:change="store.save()">
|
|
||||||
<label for="choice-mark-media-sensitive">Always mark media as sensitive</label>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</SettingsLayout>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<style>
|
|
||||||
.ui-settings {
|
|
||||||
background: var(--form-bg);
|
|
||||||
border: 1px solid var(--main-border);
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 20px;
|
|
||||||
line-height: 2em;
|
|
||||||
}
|
|
||||||
.setting-group {
|
|
||||||
padding: 5px 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
<script>
|
||||||
import Layout from '../_components/Layout.html';
|
import Layout from '../_components/Layout.html'
|
||||||
import SettingsLayout from './_components/SettingsLayout.html'
|
import LazyPage from '../_components/LazyPage.html'
|
||||||
import { store } from '../_store/store'
|
import pageComponent from '../_pages/settings/general.html'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
SettingsLayout
|
LazyPage
|
||||||
},
|
},
|
||||||
store: () => store
|
data: () => ({
|
||||||
};
|
pageComponent
|
||||||
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,31 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Settings</title>
|
<title>Pinafore – Settings</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='settings'>
|
<Layout page='settings'>
|
||||||
<SettingsLayout page='settings' label="Settings">
|
<LazyPage :pageComponent :params />
|
||||||
<h1>Settings</h1>
|
|
||||||
|
|
||||||
<SettingsList>
|
|
||||||
<SettingsListItem href="/settings/general" label="General"/>
|
|
||||||
<SettingsListItem href="/settings/instances" label="Instances"/>
|
|
||||||
<SettingsListItem href="/settings/about" label="About Pinafore"/>
|
|
||||||
</SettingsList>
|
|
||||||
|
|
||||||
</SettingsLayout>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<script>
|
<script>
|
||||||
import Layout from '../_components/Layout.html';
|
import Layout from '../_components/Layout.html'
|
||||||
import SettingsLayout from './_components/SettingsLayout.html'
|
import LazyPage from '../_components/LazyPage.html'
|
||||||
import SettingsList from './_components/SettingsList.html'
|
import pageComponent from '../_pages/settings/index.html'
|
||||||
import SettingsListItem from './_components/SettingsListItem.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
SettingsLayout,
|
LazyPage
|
||||||
SettingsList,
|
},
|
||||||
SettingsListItem
|
data: () => ({
|
||||||
|
pageComponent
|
||||||
|
})
|
||||||
}
|
}
|
||||||
};
|
|
||||||
</script>
|
</script>
|
|
@ -1,159 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – {{params.instanceName}}</title>
|
<title>Pinafore – {{params.instanceName}}</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='settings'>
|
<Layout page='settings'>
|
||||||
<SettingsLayout page='settings/instances/{{params.instanceName}}' label="{{params.instanceName}}">
|
<LazyPage :pageComponent :params />
|
||||||
<h1 class="instance-name-h1">{{params.instanceName}}</h1>
|
|
||||||
|
|
||||||
{{#if verifyCredentials}}
|
|
||||||
<h2>Logged in as:</h2>
|
|
||||||
<div class="acct-current-user">
|
|
||||||
<Avatar account="{{verifyCredentials}}" className="acct-avatar" size="big"/>
|
|
||||||
<ExternalLink class="acct-handle"
|
|
||||||
href="{{verifyCredentials.url}}">
|
|
||||||
{{'@' + verifyCredentials.acct}}
|
|
||||||
</ExternalLink>
|
|
||||||
<span class="acct-display-name">{{verifyCredentials.display_name || verifyCredentials.acct}}</span>
|
|
||||||
</div>
|
|
||||||
<h2>Theme:</h2>
|
|
||||||
<form class="theme-chooser" aria-label="Choose a theme">
|
|
||||||
{{#each themes as theme}}
|
|
||||||
<div class="theme-group">
|
|
||||||
<input type="radio" id="choice-theme-{{theme.name}}"
|
|
||||||
value="{{theme.name}}" checked="$currentTheme === theme.name"
|
|
||||||
bind:group="selectedTheme" on:change="onThemeChange()">
|
|
||||||
<label for="choice-theme-{{theme.name}}">{{theme.label}}</label>
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<form class="instance-actions" aria-label="Switch to or log out of this instance">
|
|
||||||
{{#if $loggedInInstancesInOrder.length > 1 && $currentInstance !== params.instanceName}}
|
|
||||||
<button class="primary"
|
|
||||||
on:click="onSwitchToThisInstance(event)">
|
|
||||||
Switch to this instance
|
|
||||||
</button>
|
|
||||||
{{/if}}
|
|
||||||
<button on:click="onLogOut(event)">Log out</button>
|
|
||||||
</form>
|
|
||||||
{{/if}}
|
|
||||||
</SettingsLayout>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<style>
|
|
||||||
.acct-current-user {
|
|
||||||
background: var(--form-bg);
|
|
||||||
border: 1px solid var(--main-border);
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 20px;
|
|
||||||
display: grid;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 1.3em;
|
|
||||||
grid-template-areas:
|
|
||||||
"avatar handle"
|
|
||||||
"avatar display-name";
|
|
||||||
grid-template-columns: min-content 1fr;
|
|
||||||
grid-column-gap: 20px;
|
|
||||||
grid-row-gap: 10px;
|
|
||||||
}
|
|
||||||
:global(.acct-avatar) {
|
|
||||||
grid-area: avatar;
|
|
||||||
}
|
|
||||||
:global(.acct-handle) {
|
|
||||||
grid-area: handle;
|
|
||||||
}
|
|
||||||
.acct-display-name {
|
|
||||||
grid-area: display-name;
|
|
||||||
}
|
|
||||||
.theme-chooser {
|
|
||||||
background: var(--form-bg);
|
|
||||||
border: 1px solid var(--main-border);
|
|
||||||
border-radius: 4px;
|
|
||||||
display: block;
|
|
||||||
padding: 20px;
|
|
||||||
line-height: 2em;
|
|
||||||
}
|
|
||||||
.theme-group {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.theme-chooser label {
|
|
||||||
margin: 2px 10px 0;
|
|
||||||
}
|
|
||||||
.instance-actions {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: right;
|
|
||||||
margin: 20px 0;
|
|
||||||
}
|
|
||||||
.instance-actions button {
|
|
||||||
margin: 0 5px;
|
|
||||||
flex-basis: 100%;
|
|
||||||
}
|
|
||||||
.instance-name-h1 {
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
<script>
|
||||||
import { store } from '../../_store/store'
|
|
||||||
import Layout from '../../_components/Layout.html'
|
import Layout from '../../_components/Layout.html'
|
||||||
import SettingsLayout from '../_components/SettingsLayout.html'
|
import LazyPage from '../../_components/LazyPage.html'
|
||||||
import ExternalLink from '../../_components/ExternalLink.html'
|
import pageComponent from '../../_pages/settings/instances/[instanceName].html'
|
||||||
import Avatar from '../../_components/Avatar.html'
|
|
||||||
import { importDialogs } from '../../_utils/asyncModules'
|
|
||||||
import {
|
|
||||||
changeTheme,
|
|
||||||
switchToInstance,
|
|
||||||
logOutOfInstance,
|
|
||||||
updateVerifyCredentialsForInstance
|
|
||||||
} from '../../_actions/instances'
|
|
||||||
import { themes } from '../../_static/themes'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
SettingsLayout,
|
LazyPage
|
||||||
ExternalLink,
|
|
||||||
Avatar
|
|
||||||
},
|
},
|
||||||
store: () => store,
|
|
||||||
data: () => ({
|
data: () => ({
|
||||||
themes: themes,
|
pageComponent
|
||||||
}),
|
|
||||||
async oncreate() {
|
|
||||||
let instanceName = this.get('instanceName')
|
|
||||||
await updateVerifyCredentialsForInstance(instanceName)
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
instanceName: (params) => params.instanceName,
|
|
||||||
selectedTheme: ($instanceThemes, instanceName) => $instanceThemes[instanceName],
|
|
||||||
verifyCredentials: ($verifyCredentials, instanceName) => $verifyCredentials && $verifyCredentials[instanceName]
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onThemeChange() {
|
|
||||||
let newTheme = this.get('selectedTheme')
|
|
||||||
let instanceName = this.get('instanceName')
|
|
||||||
changeTheme(instanceName, newTheme)
|
|
||||||
},
|
|
||||||
onSwitchToThisInstance(e) {
|
|
||||||
e.preventDefault()
|
|
||||||
let instanceName = this.get('instanceName')
|
|
||||||
switchToInstance(instanceName)
|
|
||||||
},
|
|
||||||
async onLogOut(e) {
|
|
||||||
e.preventDefault()
|
|
||||||
let instanceName = this.get('instanceName')
|
|
||||||
|
|
||||||
let dialogs = await importDialogs()
|
|
||||||
dialogs.showConfirmationDialog({
|
|
||||||
text: `Log out of ${instanceName}?`,
|
|
||||||
onPositive() {
|
|
||||||
logOutOfInstance(instanceName)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
|
@ -1,98 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Add an Instance</title>
|
<title>Pinafore – Add an Instance</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='settings'>
|
<Layout page='settings'>
|
||||||
<SettingsLayout page='settings/instances/add' label="Add an Instance">
|
<LazyPage :pageComponent :params />
|
||||||
<h1 id="add-an-instance-h1">Add an Instance</h1>
|
|
||||||
|
|
||||||
{{#if $isUserLoggedIn}}
|
|
||||||
<p>Connect to an instance to log in.</p>
|
|
||||||
{{else}}
|
|
||||||
<p>Log in to an instance to use Pinafore.</p>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<form class="add-new-instance" on:submit='onSubmit(event)' aria-labelledby="add-an-instance-h1">
|
|
||||||
|
|
||||||
{{#if $logInToInstanceError && $logInToInstanceErrorForText === $instanceNameInSearch}}
|
|
||||||
<div class="form-error form-error-user-error" role="alert">
|
|
||||||
Error: {{$logInToInstanceError}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<noscript>
|
|
||||||
<div class="form-error" role="alert">
|
|
||||||
You must enable JavaScript to log in.
|
|
||||||
</div>
|
|
||||||
</noscript>
|
|
||||||
|
|
||||||
<label for="instanceInput">Instance:</label>
|
|
||||||
<input class="new-instance-input" type="text" id="instanceInput"
|
|
||||||
bind:value='$instanceNameInSearch' placeholder='' required
|
|
||||||
>
|
|
||||||
<button class="primary" type="submit" id="submitButton"
|
|
||||||
disabled="{{!$instanceNameInSearch || $logInToInstanceLoading}}">
|
|
||||||
Add instance
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{{#if !$isUserLoggedIn}}
|
|
||||||
<p>Don't have an instance? <ExternalLink href="https://joinmastodon.org">Join Mastodon!</ExternalLink></p>
|
|
||||||
{{/if}}
|
|
||||||
</SettingsLayout>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<style>
|
|
||||||
.form-error {
|
|
||||||
border: 2px solid red;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 10px;
|
|
||||||
font-size: 1.3em;
|
|
||||||
margin: 5px;
|
|
||||||
background-color: var(--main-bg);
|
|
||||||
}
|
|
||||||
input.new-instance-input {
|
|
||||||
min-width: 60%;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
form.add-new-instance {
|
|
||||||
background: var(--form-bg);
|
|
||||||
padding: 5px 10px 15px;
|
|
||||||
margin: 20px auto;
|
|
||||||
border: 1px solid var(--form-border);
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
form.add-new-instance label, form.add-new-instance input, form.add-new-instance button {
|
|
||||||
display: block;
|
|
||||||
margin: 20px 5px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
<script>
|
||||||
import Layout from '../../_components/Layout.html';
|
import Layout from '../../_components/Layout.html'
|
||||||
import SettingsLayout from '../_components/SettingsLayout.html'
|
import LazyPage from '../../_components/LazyPage.html'
|
||||||
import { store } from '../../_store/store'
|
import pageComponent from '../../_pages/settings/instances/add.html'
|
||||||
import { logInToInstance, handleOauthCode } from '../../_actions/addInstance'
|
|
||||||
import ExternalLink from '../../_components/ExternalLink.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
async oncreate () {
|
|
||||||
let codeMatch = location.search.match(/code=([^&]+)/)
|
|
||||||
if (codeMatch) {
|
|
||||||
handleOauthCode(codeMatch[1])
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
SettingsLayout,
|
LazyPage
|
||||||
ExternalLink
|
|
||||||
},
|
},
|
||||||
store: () => store,
|
data: () => ({
|
||||||
methods: {
|
pageComponent
|
||||||
onSubmit(event) {
|
})
|
||||||
event.preventDefault()
|
|
||||||
logInToInstance()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,43 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Instances</title>
|
<title>Pinafore – Instances</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='settings'>
|
<Layout page='settings'>
|
||||||
<SettingsLayout page='settings/instances' label="Instances">
|
<LazyPage :pageComponent :params />
|
||||||
<h1>Instances</h1>
|
|
||||||
|
|
||||||
{{#if $isUserLoggedIn}}
|
|
||||||
<p>Instances you've logged in to:</p>
|
|
||||||
<SettingsList label="Instances">
|
|
||||||
{{#each $loggedInInstancesAsList as instance}}
|
|
||||||
<SettingsListItem offsetForIcon="{{instance.name !== $currentInstance}}"
|
|
||||||
icon="{{instance.name === $currentInstance ? '#fa-star' : ''}}"
|
|
||||||
href="/settings/instances/{{instance.name}}"
|
|
||||||
label="{{instance.name}}"
|
|
||||||
ariaLabel="{{instance.name}} {{instance.name === $currentInstance ? '(current instance)' : ''}}" />
|
|
||||||
{{/each}}
|
|
||||||
</SettingsList>
|
|
||||||
<p><a href="/settings/instances/add">Add another instance</a></p>
|
|
||||||
{{else}}
|
|
||||||
<p>You're not logged in to any instances.</p>
|
|
||||||
<p><a href="/settings/instances/add">Log in to an instance</a> to start using Pinafore.</p>
|
|
||||||
{{/if}}
|
|
||||||
</SettingsLayout>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<script>
|
<script>
|
||||||
import { store } from '../../_store/store'
|
|
||||||
import Layout from '../../_components/Layout.html'
|
import Layout from '../../_components/Layout.html'
|
||||||
import SettingsLayout from '../_components/SettingsLayout.html'
|
import LazyPage from '../../_components/LazyPage.html'
|
||||||
import SettingsList from '../_components/SettingsList.html'
|
import pageComponent from '../../_pages/settings/instances/index.html'
|
||||||
import SettingsListItem from '../_components/SettingsListItem.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
SettingsLayout,
|
LazyPage
|
||||||
SettingsList,
|
|
||||||
SettingsListItem
|
|
||||||
},
|
},
|
||||||
store: () => store
|
data: () => ({
|
||||||
|
pageComponent
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,28 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Favorites</title>
|
<title>Pinafore – Favorites</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='favorites'>
|
<Layout page='favorites'>
|
||||||
<DynamicPageBanner title="Favorites" icon="#fa-star" />
|
<LazyPage :pageComponent :params />
|
||||||
<AccountsListPage :accountsFetcher />
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<script>
|
<script>
|
||||||
import Layout from '../../_components/Layout.html'
|
import Layout from '../../_components/Layout.html'
|
||||||
import { getFavorites } from '../../_api/reblogsAndFavs'
|
import LazyPage from '../../_components/LazyPage.html'
|
||||||
import AccountsListPage from '../../_components/AccountsListPage.html'
|
import pageComponent from '../../_pages/statuses/[statusId]/favorites.html'
|
||||||
import { store } from '../../_store/store'
|
|
||||||
import DynamicPageBanner from '../../_components/DynamicPageBanner.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
|
||||||
statusId: params => params.statusId,
|
|
||||||
accountsFetcher: ($currentInstance, $accessToken, statusId) => () => getFavorites($currentInstance, $accessToken, statusId)
|
|
||||||
},
|
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
AccountsListPage,
|
LazyPage
|
||||||
DynamicPageBanner
|
},
|
||||||
}
|
data: () => ({
|
||||||
|
pageComponent
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,37 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Status</title>
|
<title>Pinafore – Status</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='statuses' >
|
<Layout page='statuses' >
|
||||||
{{#if $isUserLoggedIn}}
|
<LazyPage :pageComponent :params />
|
||||||
<DynamicPageBanner title=""/>
|
|
||||||
<LazyTimeline timeline='status/{{params.statusId}}' />
|
|
||||||
{{else}}
|
|
||||||
<HiddenFromSSR>
|
|
||||||
<FreeTextLayout>
|
|
||||||
<h1>Status</h1>
|
|
||||||
|
|
||||||
<p>A status thread will appear here when logged in.</p>
|
|
||||||
</FreeTextLayout>
|
|
||||||
</HiddenFromSSR>
|
|
||||||
{{/if}}
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<script>
|
<script>
|
||||||
import Layout from '../../_components/Layout.html'
|
import Layout from '../../_components/Layout.html'
|
||||||
import LazyTimeline from '../../_components/timeline/LazyTimeline.html'
|
import LazyPage from '../../_components/LazyPage.html'
|
||||||
import FreeTextLayout from '../../_components/FreeTextLayout.html'
|
import pageComponent from '../../_pages/statuses/[statusId]/index.html'
|
||||||
import { store } from '../../_store/store.js'
|
|
||||||
import HiddenFromSSR from '../../_components/HiddenFromSSR'
|
|
||||||
import DynamicPageBanner from '../../_components/DynamicPageBanner.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
LazyTimeline,
|
LazyPage
|
||||||
FreeTextLayout,
|
},
|
||||||
HiddenFromSSR,
|
data: () => ({
|
||||||
DynamicPageBanner
|
pageComponent
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,28 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Reblogs</title>
|
<title>Pinafore – Reblogs</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='reblogs'>
|
<Layout page='reblogs'>
|
||||||
<DynamicPageBanner title="Boosts" icon="#fa-retweet" />
|
<LazyPage :pageComponent :params />
|
||||||
<AccountsListPage :accountsFetcher />
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<script>
|
<script>
|
||||||
import Layout from '../../_components/Layout.html'
|
import Layout from '../../_components/Layout.html'
|
||||||
import { getReblogs } from '../../_api/reblogsAndFavs'
|
import LazyPage from '../../_components/LazyPage.html'
|
||||||
import AccountsListPage from '../../_components/AccountsListPage.html'
|
import pageComponent from '../../_pages/statuses/[statusId]/reblogs.html'
|
||||||
import { store } from '../../_store/store'
|
|
||||||
import DynamicPageBanner from '../../_components/DynamicPageBanner.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
|
||||||
statusId: params => params.statusId,
|
|
||||||
accountsFetcher: ($currentInstance, $accessToken, statusId) => () => getReblogs($currentInstance, $accessToken, statusId)
|
|
||||||
},
|
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
AccountsListPage,
|
LazyPage
|
||||||
DynamicPageBanner
|
},
|
||||||
}
|
data: () => ({
|
||||||
|
pageComponent
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,53 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – Reply</title>
|
<title>Pinafore – Reply</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='reply' >
|
<Layout page='reply' >
|
||||||
<DynamicPageBanner title=""/>
|
<LazyPage :pageComponent :params />
|
||||||
<div class="reply-container">
|
|
||||||
{{#if status}}
|
|
||||||
<Status index="0"
|
|
||||||
length="1"
|
|
||||||
timelineType="reply"
|
|
||||||
timelineValue="{{params.statusId}}"
|
|
||||||
:status
|
|
||||||
/>
|
|
||||||
<ComposeBox realm="{{params.statusId}}" />
|
|
||||||
{{else}}
|
|
||||||
<LoadingPage />
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<style>
|
|
||||||
.reply-container {
|
|
||||||
position: relative;
|
|
||||||
margin-top: 20px;
|
|
||||||
min-height: 60vh;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script>
|
<script>
|
||||||
import Layout from '../../_components/Layout.html'
|
import Layout from '../../_components/Layout.html'
|
||||||
import { store } from '../../_store/store.js'
|
import LazyPage from '../../_components/LazyPage.html'
|
||||||
import DynamicPageBanner from '../../_components/DynamicPageBanner.html'
|
import pageComponent from '../../_pages/statuses/[statusId]/reply.html'
|
||||||
import LoadingPage from '../../_components/LoadingPage.html'
|
|
||||||
import ComposeBox from '../../_components/compose/ComposeBox.html'
|
|
||||||
import Status from '../../_components/status/Status.html'
|
|
||||||
import { database } from '../../_database/database'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
async oncreate() {
|
|
||||||
let statusId = this.get('params').statusId
|
|
||||||
let instanceName = this.store.get('currentInstance')
|
|
||||||
let status = await database.getStatus(instanceName, statusId)
|
|
||||||
this.set({status})
|
|
||||||
},
|
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
DynamicPageBanner,
|
LazyPage
|
||||||
LoadingPage,
|
},
|
||||||
ComposeBox,
|
data: () => ({
|
||||||
Status
|
pageComponent
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,37 +1,21 @@
|
||||||
<:Head>
|
<:Head>
|
||||||
<title>Pinafore – #{{params.tagName}}</title>
|
<title>Pinafore – #{{params.tagName}}</title>
|
||||||
</:Head>
|
</:Head>
|
||||||
|
|
||||||
<Layout page='tags'>
|
<Layout page='tags'>
|
||||||
{{#if $isUserLoggedIn}}
|
<LazyPage :pageComponent :params />
|
||||||
<DynamicPageBanner title="{{'#' + params.tagName}}"/>
|
|
||||||
<LazyTimeline timeline='tag/{{params.tagName}}' />
|
|
||||||
{{else}}
|
|
||||||
<HiddenFromSSR>
|
|
||||||
<FreeTextLayout>
|
|
||||||
<h1>#{{params.tagName}}</h1>
|
|
||||||
|
|
||||||
<p>A hashtag timeline will appear here when logged in.</p>
|
|
||||||
</FreeTextLayout>
|
|
||||||
</HiddenFromSSR>
|
|
||||||
{{/if}}
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<script>
|
<script>
|
||||||
import Layout from '../_components/Layout.html'
|
import Layout from '../_components/Layout.html'
|
||||||
import LazyTimeline from '../_components/timeline/LazyTimeline.html'
|
import LazyPage from '../_components/LazyPage.html'
|
||||||
import FreeTextLayout from '../_components/FreeTextLayout.html'
|
import pageComponent from '../_pages/tags/[tagName].html'
|
||||||
import { store } from '../_store/store.js'
|
|
||||||
import HiddenFromSSR from '../_components/HiddenFromSSR'
|
|
||||||
import DynamicPageBanner from '../_components/DynamicPageBanner.html'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
store: () => store,
|
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
LazyTimeline,
|
LazyPage
|
||||||
FreeTextLayout,
|
},
|
||||||
HiddenFromSSR,
|
data: () => ({
|
||||||
DynamicPageBanner
|
pageComponent
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -37,6 +37,7 @@ main {
|
||||||
background: var(--main-bg);
|
background: var(--main-bg);
|
||||||
border: 1px solid var(--main-border);
|
border: 1px solid var(--main-border);
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
|
min-height: 60vh;
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767px) {
|
||||||
margin: 5px auto 15px;
|
margin: 5px auto 15px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<style>
|
<style>
|
||||||
/* auto-generated w/ build-sass.js */
|
/* auto-generated w/ build-sass.js */
|
||||||
body{--button-primary-bg:#6081e6;--button-primary-text:#fff;--button-primary-border:#132c76;--button-primary-bg-active:#456ce2;--button-primary-bg-hover:#6988e7;--button-bg:#e6e6e6;--button-text:#333;--button-border:#a7a7a7;--button-bg-active:#bfbfbf;--button-bg-hover:#f2f2f2;--input-border:#dadada;--anchor-text:#4169e1;--main-bg:#fff;--body-bg:#e8edfb;--body-text-color:#333;--main-border:#dadada;--svg-fill:#4169e1;--form-bg:#f7f7f7;--form-border:#c1c1c1;--nav-bg:#4169e1;--nav-border:#214cce;--nav-a-border:#4169e1;--nav-a-selected-border:#fff;--nav-a-selected-bg:#6d8ce8;--nav-svg-fill:#fff;--nav-text-color:#fff;--nav-a-selected-border-hover:#fff;--nav-a-selected-bg-hover:#839deb;--nav-a-bg-hover:#577ae4;--nav-a-border-hover:#4169e1;--nav-svg-fill-hover:#fff;--nav-text-color-hover:#fff;--action-button-fill-color:#90a8ee;--action-button-fill-color-hover:#a2b6f0;--action-button-fill-color-active:#577ae4;--action-button-fill-color-pressed:#2351dc;--action-button-fill-color-pressed-hover:#3862e0;--action-button-fill-color-pressed-active:#1d44b8;--settings-list-item-bg:#fff;--settings-list-item-text:#4169e1;--settings-list-item-text-hover:#4169e1;--settings-list-item-border:#dadada;--settings-list-item-bg-active:#e6e6e6;--settings-list-item-bg-hover:#fafafa;--toast-bg:#333;--toast-border:#fafafa;--toast-text:#fff;--mask-bg:#333;--mask-svg-fill:#fff;--mask-opaque-bg:rgba(51,51,51,0.8);--loading-bg:#ededed;--deemphasized-text-color:#666;--focus-outline:#c5d1f6;--very-deemphasized-link-color:rgba(65,105,225,0.6);--very-deemphasized-text-color:rgba(102,102,102,0.6);--status-direct-background:#d2dcf8;--main-theme-color:#4169e1;--warning-color:#e01f19;--alt-input-bg:rgba(255,255,255,0.7)}
|
body{--button-primary-bg:#6081e6;--button-primary-text:#fff;--button-primary-border:#132c76;--button-primary-bg-active:#456ce2;--button-primary-bg-hover:#6988e7;--button-bg:#e6e6e6;--button-text:#333;--button-border:#a7a7a7;--button-bg-active:#bfbfbf;--button-bg-hover:#f2f2f2;--input-border:#dadada;--anchor-text:#4169e1;--main-bg:#fff;--body-bg:#e8edfb;--body-text-color:#333;--main-border:#dadada;--svg-fill:#4169e1;--form-bg:#f7f7f7;--form-border:#c1c1c1;--nav-bg:#4169e1;--nav-border:#214cce;--nav-a-border:#4169e1;--nav-a-selected-border:#fff;--nav-a-selected-bg:#6d8ce8;--nav-svg-fill:#fff;--nav-text-color:#fff;--nav-a-selected-border-hover:#fff;--nav-a-selected-bg-hover:#839deb;--nav-a-bg-hover:#577ae4;--nav-a-border-hover:#4169e1;--nav-svg-fill-hover:#fff;--nav-text-color-hover:#fff;--action-button-fill-color:#90a8ee;--action-button-fill-color-hover:#a2b6f0;--action-button-fill-color-active:#577ae4;--action-button-fill-color-pressed:#2351dc;--action-button-fill-color-pressed-hover:#3862e0;--action-button-fill-color-pressed-active:#1d44b8;--settings-list-item-bg:#fff;--settings-list-item-text:#4169e1;--settings-list-item-text-hover:#4169e1;--settings-list-item-border:#dadada;--settings-list-item-bg-active:#e6e6e6;--settings-list-item-bg-hover:#fafafa;--toast-bg:#333;--toast-border:#fafafa;--toast-text:#fff;--mask-bg:#333;--mask-svg-fill:#fff;--mask-opaque-bg:rgba(51,51,51,0.8);--loading-bg:#ededed;--deemphasized-text-color:#666;--focus-outline:#c5d1f6;--very-deemphasized-link-color:rgba(65,105,225,0.6);--very-deemphasized-text-color:rgba(102,102,102,0.6);--status-direct-background:#d2dcf8;--main-theme-color:#4169e1;--warning-color:#e01f19;--alt-input-bg:rgba(255,255,255,0.7)}
|
||||||
body{margin:0;font-family:system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue;font-size:14px;line-height:1.4;color:var(--body-text-color);background:var(--body-bg);position:fixed;left:0;right:0;bottom:0;top:0}.container{overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;will-change:transform;position:absolute;top:72px;left:0;right:0;bottom:0}@media (max-width: 767px){.container{top:62px}}main{position:relative;width:602px;max-width:100vw;padding:0;box-sizing:border-box;margin:30px auto 15px;background:var(--main-bg);border:1px solid var(--main-border);border-radius:1px}@media (max-width: 767px){main{margin:5px auto 15px}}footer{width:602px;max-width:100vw;box-sizing:border-box;margin:20px auto;border-radius:1px;background:var(--main-bg);font-size:0.9em;padding:20px;border:1px solid var(--main-border)}h1,h2,h3,h4,h5,h6{margin:0 0 0.5em 0;font-weight:400;line-height:1.2}h1{font-size:2em}a{color:var(--anchor-text);text-decoration:none}a:visited{color:var(--anchor-text)}a:hover{text-decoration:underline}input{border:1px solid var(--input-border);padding:5px;box-sizing:border-box}button,.button{font-size:1.2em;background:var(--button-bg);border-radius:2px;padding:10px 15px;border:1px solid var(--button-border);cursor:pointer;color:var(--button-text)}button:hover,.button:hover{background:var(--button-bg-hover);text-decoration:none}button:active,.button:active{background:var(--button-bg-active)}button[disabled],.button[disabled]{opacity:0.35;pointer-events:none;cursor:not-allowed}button.primary,.button.primary{border:1px solid var(--button-primary-border);background:var(--button-primary-bg);color:var(--button-primary-text)}button.primary:hover,.button.primary:hover{background:var(--button-primary-bg-hover)}button.primary:active,.button.primary:active{background:var(--button-primary-bg-active)}p,label,input{font-size:1.3em}ul,li,p{padding:0;margin:0}.hidden{opacity:0}*:focus{outline:2px solid var(--focus-outline)}button::-moz-focus-inner{border:0}input:required,input:invalid{box-shadow:none}textarea{font-family:inherit;font-size:inherit;box-sizing:border-box}@keyframes spin{0%{transform:rotate(0deg)}50%{transform:rotate(180deg)}100%{transform:rotate(360deg)}}.spin{animation:spin 2s infinite linear}
|
body{margin:0;font-family:system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue;font-size:14px;line-height:1.4;color:var(--body-text-color);background:var(--body-bg);position:fixed;left:0;right:0;bottom:0;top:0}.container{overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;will-change:transform;position:absolute;top:72px;left:0;right:0;bottom:0}@media (max-width: 767px){.container{top:62px}}main{position:relative;width:602px;max-width:100vw;padding:0;box-sizing:border-box;margin:30px auto 15px;background:var(--main-bg);border:1px solid var(--main-border);border-radius:1px;min-height:60vh}@media (max-width: 767px){main{margin:5px auto 15px}}footer{width:602px;max-width:100vw;box-sizing:border-box;margin:20px auto;border-radius:1px;background:var(--main-bg);font-size:0.9em;padding:20px;border:1px solid var(--main-border)}h1,h2,h3,h4,h5,h6{margin:0 0 0.5em 0;font-weight:400;line-height:1.2}h1{font-size:2em}a{color:var(--anchor-text);text-decoration:none}a:visited{color:var(--anchor-text)}a:hover{text-decoration:underline}input{border:1px solid var(--input-border);padding:5px;box-sizing:border-box}button,.button{font-size:1.2em;background:var(--button-bg);border-radius:2px;padding:10px 15px;border:1px solid var(--button-border);cursor:pointer;color:var(--button-text)}button:hover,.button:hover{background:var(--button-bg-hover);text-decoration:none}button:active,.button:active{background:var(--button-bg-active)}button[disabled],.button[disabled]{opacity:0.35;pointer-events:none;cursor:not-allowed}button.primary,.button.primary{border:1px solid var(--button-primary-border);background:var(--button-primary-bg);color:var(--button-primary-text)}button.primary:hover,.button.primary:hover{background:var(--button-primary-bg-hover)}button.primary:active,.button.primary:active{background:var(--button-primary-bg-active)}p,label,input{font-size:1.3em}ul,li,p{padding:0;margin:0}.hidden{opacity:0}*:focus{outline:2px solid var(--focus-outline)}button::-moz-focus-inner{border:0}input:required,input:invalid{box-shadow:none}textarea{font-family:inherit;font-size:inherit;box-sizing:border-box}@keyframes spin{0%{transform:rotate(0deg)}50%{transform:rotate(180deg)}100%{transform:rotate(360deg)}}.spin{animation:spin 2s infinite linear}
|
||||||
body.offline,body.theme-hotpants.offline,body.theme-majesty.offline,body.theme-oaken.offline,body.theme-scarlet.offline,body.theme-seafoam.offline,body.theme-gecko.offline{--button-primary-bg:#ababab;--button-primary-text:#fff;--button-primary-border:#4d4d4d;--button-primary-bg-active:#9c9c9c;--button-primary-bg-hover:#b0b0b0;--button-bg:#e6e6e6;--button-text:#333;--button-border:#a7a7a7;--button-bg-active:#bfbfbf;--button-bg-hover:#f2f2f2;--input-border:#dadada;--anchor-text:#999;--main-bg:#fff;--body-bg:#fafafa;--body-text-color:#333;--main-border:#dadada;--svg-fill:#999;--form-bg:#f7f7f7;--form-border:#c1c1c1;--nav-bg:#999;--nav-border:gray;--nav-a-border:#999;--nav-a-selected-border:#fff;--nav-a-selected-bg:#b3b3b3;--nav-svg-fill:#fff;--nav-text-color:#fff;--nav-a-selected-border-hover:#fff;--nav-a-selected-bg-hover:#bfbfbf;--nav-a-bg-hover:#a6a6a6;--nav-a-border-hover:#999;--nav-svg-fill-hover:#fff;--nav-text-color-hover:#fff;--action-button-fill-color:#c7c7c7;--action-button-fill-color-hover:#d1d1d1;--action-button-fill-color-active:#a6a6a6;--action-button-fill-color-pressed:#878787;--action-button-fill-color-pressed-hover:#949494;--action-button-fill-color-pressed-active:#737373;--settings-list-item-bg:#fff;--settings-list-item-text:#999;--settings-list-item-text-hover:#999;--settings-list-item-border:#dadada;--settings-list-item-bg-active:#e6e6e6;--settings-list-item-bg-hover:#fafafa;--toast-bg:#333;--toast-border:#fafafa;--toast-text:#fff;--mask-bg:#333;--mask-svg-fill:#fff;--mask-opaque-bg:rgba(51,51,51,0.8);--loading-bg:#ededed;--deemphasized-text-color:#666;--focus-outline:#bfbfbf;--very-deemphasized-link-color:rgba(153,153,153,0.6);--very-deemphasized-text-color:rgba(102,102,102,0.6);--status-direct-background:#ededed;--main-theme-color:#999;--warning-color:#e01f19;--alt-input-bg:rgba(255,255,255,0.7)}
|
body.offline,body.theme-hotpants.offline,body.theme-majesty.offline,body.theme-oaken.offline,body.theme-scarlet.offline,body.theme-seafoam.offline,body.theme-gecko.offline{--button-primary-bg:#ababab;--button-primary-text:#fff;--button-primary-border:#4d4d4d;--button-primary-bg-active:#9c9c9c;--button-primary-bg-hover:#b0b0b0;--button-bg:#e6e6e6;--button-text:#333;--button-border:#a7a7a7;--button-bg-active:#bfbfbf;--button-bg-hover:#f2f2f2;--input-border:#dadada;--anchor-text:#999;--main-bg:#fff;--body-bg:#fafafa;--body-text-color:#333;--main-border:#dadada;--svg-fill:#999;--form-bg:#f7f7f7;--form-border:#c1c1c1;--nav-bg:#999;--nav-border:gray;--nav-a-border:#999;--nav-a-selected-border:#fff;--nav-a-selected-bg:#b3b3b3;--nav-svg-fill:#fff;--nav-text-color:#fff;--nav-a-selected-border-hover:#fff;--nav-a-selected-bg-hover:#bfbfbf;--nav-a-bg-hover:#a6a6a6;--nav-a-border-hover:#999;--nav-svg-fill-hover:#fff;--nav-text-color-hover:#fff;--action-button-fill-color:#c7c7c7;--action-button-fill-color-hover:#d1d1d1;--action-button-fill-color-active:#a6a6a6;--action-button-fill-color-pressed:#878787;--action-button-fill-color-pressed-hover:#949494;--action-button-fill-color-pressed-active:#737373;--settings-list-item-bg:#fff;--settings-list-item-text:#999;--settings-list-item-text-hover:#999;--settings-list-item-border:#dadada;--settings-list-item-bg-active:#e6e6e6;--settings-list-item-bg-hover:#fafafa;--toast-bg:#333;--toast-border:#fafafa;--toast-text:#fff;--mask-bg:#333;--mask-svg-fill:#fff;--mask-opaque-bg:rgba(51,51,51,0.8);--loading-bg:#ededed;--deemphasized-text-color:#666;--focus-outline:#bfbfbf;--very-deemphasized-link-color:rgba(153,153,153,0.6);--very-deemphasized-text-color:rgba(102,102,102,0.6);--status-direct-background:#ededed;--main-theme-color:#999;--warning-color:#e01f19;--alt-input-bg:rgba(255,255,255,0.7)}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in a new issue