upgrade to svelte 2.0 (#251)
* upgrade to svelte 2.0 * update svelte-loader to 2.9.0
This commit is contained in:
parent
d2d82ba2e3
commit
42be854521
16
package-lock.json
generated
16
package-lock.json
generated
|
@ -9786,9 +9786,9 @@
|
||||||
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
|
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
|
||||||
},
|
},
|
||||||
"svelte": {
|
"svelte": {
|
||||||
"version": "1.64.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-1.64.1.tgz",
|
"resolved": "https://registry.npmjs.org/svelte/-/svelte-2.4.1.tgz",
|
||||||
"integrity": "sha512-RsEAcVYF90Bq5y4Lgg56LyKiuxiyDTU+5TG2GM0ppa50z446de0vQgnA3eQTrgecPdRR89ZIqNqN1cgdAdO7wQ=="
|
"integrity": "sha512-49huVkAZV42sLny2/d6fU4Dzg605hkSQfNxISv34Kkb7M5MxmMhe9ywQ3+didcqwiHAqXn0/P0MojdbqU58ZIQ=="
|
||||||
},
|
},
|
||||||
"svelte-dev-helper": {
|
"svelte-dev-helper": {
|
||||||
"version": "1.1.7",
|
"version": "1.1.7",
|
||||||
|
@ -9801,13 +9801,12 @@
|
||||||
"integrity": "sha512-yoxNehbDxGEHxJBTWq2RpIPDTHlNNy6eGR7RPSK7qsh8hoyOXbji8uF//l4+I/l2fLP+E8pQTJYrduPXrW3wsw=="
|
"integrity": "sha512-yoxNehbDxGEHxJBTWq2RpIPDTHlNNy6eGR7RPSK7qsh8hoyOXbji8uF//l4+I/l2fLP+E8pQTJYrduPXrW3wsw=="
|
||||||
},
|
},
|
||||||
"svelte-loader": {
|
"svelte-loader": {
|
||||||
"version": "2.8.1",
|
"version": "2.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/svelte-loader/-/svelte-loader-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/svelte-loader/-/svelte-loader-2.9.0.tgz",
|
||||||
"integrity": "sha512-t3cfLeYCkuz1eJem+urdCYrhI12qUz03wlYzaRJ6oER1qrKBRlOpq8S4ZraInsw2FtKGFbu/VBYekLJS07Ipnw==",
|
"integrity": "sha512-DmzPUCDBN/G/MKvi3iJZ6MDpoPKqN+um9PS8XBJn6yT6Kbu0pkU5AsdDdqauyKx2wEVQZ7DqpT9agWmDCr5TQg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"loader-utils": "1.1.0",
|
"loader-utils": "1.1.0",
|
||||||
"svelte-dev-helper": "1.1.7",
|
"svelte-dev-helper": "1.1.7"
|
||||||
"tmp": "0.0.31"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"svelte-transitions": {
|
"svelte-transitions": {
|
||||||
|
@ -10469,6 +10468,7 @@
|
||||||
"version": "0.0.31",
|
"version": "0.0.31",
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz",
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz",
|
||||||
"integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=",
|
"integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"os-tmpdir": "1.0.2"
|
"os-tmpdir": "1.0.2"
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,9 +77,9 @@
|
||||||
"shrink-ray-current": "2.1.0",
|
"shrink-ray-current": "2.1.0",
|
||||||
"stringz": "1.0.0",
|
"stringz": "1.0.0",
|
||||||
"style-loader": "0.21.0",
|
"style-loader": "0.21.0",
|
||||||
"svelte": "1.64.1",
|
"svelte": "2.4.1",
|
||||||
"svelte-extras": "2.0.2",
|
"svelte-extras": "2.0.2",
|
||||||
"svelte-loader": "2.8.1",
|
"svelte-loader": "2.9.0",
|
||||||
"svelte-transitions": "1.1.1",
|
"svelte-transitions": "1.1.1",
|
||||||
"svgo": "1.0.5",
|
"svgo": "1.0.5",
|
||||||
"timeago.js": "3.0.2",
|
"timeago.js": "3.0.2",
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
<div class="accounts-page">
|
<div class="accounts-page">
|
||||||
{{#if loading}}
|
{#if loading}
|
||||||
<LoadingPage />
|
<LoadingPage />
|
||||||
{{elseif accounts && accounts.length}}
|
{:elseif accounts && accounts.length}
|
||||||
<ul class="accounts-results">
|
<ul class="accounts-results">
|
||||||
{{#each accounts as account}}
|
{#each accounts as account}
|
||||||
<AccountSearchResult
|
<AccountSearchResult
|
||||||
:account
|
{account}
|
||||||
actions={{accountActions}}
|
actions={accountActions}
|
||||||
on:click="onClickAction(event)"
|
on:click="onClickAction(event)"
|
||||||
/>
|
/>
|
||||||
{{/each}}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.accounts-page {
|
.accounts-page {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<video
|
<video
|
||||||
class="autoplay-video {{className || ''}}"
|
class="autoplay-video {className || ''}"
|
||||||
aria-label={{ariaLabel || ''}}
|
aria-label={ariaLabel || ''}
|
||||||
style="background-image: url({{poster}});"
|
style="background-image: url({poster});"
|
||||||
:poster
|
{poster}
|
||||||
:width
|
{width}
|
||||||
:height
|
{height}
|
||||||
:src
|
{src}
|
||||||
autoplay
|
autoplay
|
||||||
muted
|
muted
|
||||||
loop
|
loop
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
{{#if error}}
|
{#if error}
|
||||||
<svg class={{computedClass}} aria-hidden="true">
|
<svg class={computedClass} aria-hidden="true">
|
||||||
<use xlink:href="#fa-user" />
|
<use xlink:href="#fa-user" />
|
||||||
</svg>
|
</svg>
|
||||||
{{elseif $autoplayGifs}}
|
{:elseif $autoplayGifs}
|
||||||
<img
|
<img
|
||||||
class={{computedClass}}
|
class={computedClass}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
alt=""
|
alt=""
|
||||||
src={{account.avatar}}
|
src={account.avatar}
|
||||||
on:imgLoad="set({loaded: true})"
|
on:imgLoad="set({loaded: true})"
|
||||||
on:imgLoadError="set({error: true})" />
|
on:imgLoadError="set({error: true})" />
|
||||||
{{else}}
|
{:else}
|
||||||
<NonAutoplayImg
|
<NonAutoplayImg
|
||||||
className={{computedClass}}
|
className={computedClass}
|
||||||
ariaHidden="true"
|
ariaHidden="true"
|
||||||
alt=""
|
alt=""
|
||||||
src={{account.avatar}}
|
src={account.avatar}
|
||||||
staticSrc={{account.avatar_static}}
|
staticSrc={account.avatar_static}
|
||||||
:isLink
|
{isLink}
|
||||||
on:imgLoad="set({loaded: true})"
|
on:imgLoad="set({loaded: true})"
|
||||||
on:imgLoadError="set({error: true})"
|
on:imgLoadError="set({error: true})"
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{/if}
|
||||||
<style>
|
<style>
|
||||||
:global(.avatar) {
|
:global(.avatar) {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
}),
|
}),
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
computedClass: (className, loaded, size) => (classname(
|
computedClass: ({ className, loaded, size }) => (classname(
|
||||||
'avatar',
|
'avatar',
|
||||||
className,
|
className,
|
||||||
loaded && 'loaded',
|
loaded && 'loaded',
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<div class="dynamic-page-banner {{icon ? 'dynamic-page-with-icon' : ''}}">
|
<div class="dynamic-page-banner {icon ? 'dynamic-page-with-icon' : ''}">
|
||||||
{{#if icon}}
|
{#if icon}
|
||||||
<svg class="dynamic-page-banner-svg">
|
<svg class="dynamic-page-banner-svg">
|
||||||
<use xlink:href={{icon}} />
|
<use xlink:href={icon} />
|
||||||
</svg>
|
</svg>
|
||||||
{{/if}}
|
{/if}
|
||||||
<h1 class="dynamic-page-title">{{title}}</h1>
|
<h1 class="dynamic-page-title">{title}</h1>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="dynamic-page-go-back"
|
class="dynamic-page-go-back"
|
||||||
on:click="onGoBack(event)">Back</button>
|
on:click="onGoBack(event)">Back</button>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<a rel="nofollow noopener"
|
<a rel="nofollow noopener"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
:href
|
{href}
|
||||||
aria-label={{ariaLabel}}
|
aria-label={ariaLabel}
|
||||||
class="{{className || ''}} {{showIcon ? 'external-link-with-icon' : ''}} {{normalIconColor ? 'normal-icon-color' : ''}}">
|
class="{className || ''} {showIcon ? 'external-link-with-icon' : ''} {normalIconColor ? 'normal-icon-color' : ''}">
|
||||||
<slot></slot>{{#if showIcon}}
|
<slot></slot>{#if showIcon}
|
||||||
<svg class="external-link-svg">
|
<svg class="external-link-svg">
|
||||||
<use xlink:href="#fa-external-link" />
|
<use xlink:href="#fa-external-link" />
|
||||||
</svg>
|
</svg>
|
||||||
{{/if}}</a>
|
{/if}</a>
|
||||||
<style>
|
<style>
|
||||||
.external-link-with-icon {
|
.external-link-with-icon {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
{{#if delegateKey}}
|
{#if delegateKey}
|
||||||
<button type="button"
|
<button type="button"
|
||||||
title={{label}}
|
title={label}
|
||||||
aria-label={{label}}
|
aria-label={label}
|
||||||
aria-pressed={{pressable ? !!pressed : ''}}
|
aria-pressed={pressable ? !!pressed : ''}
|
||||||
class={{computedClass}}
|
class={computedClass}
|
||||||
:disabled
|
{disabled}
|
||||||
delegate-key={{delegateKey}}
|
delegate-key={delegateKey}
|
||||||
focus-key={{focusKey || ''}} >
|
focus-key={focusKey || ''} >
|
||||||
<svg class="icon-button-svg {{svgClassName || ''}}" ref:svg>
|
<svg class="icon-button-svg {svgClassName || ''}" ref:svg>
|
||||||
<use xlink:href={{href}} />
|
<use xlink:href={href} />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
{{else}}
|
{:else}
|
||||||
<button type="button"
|
<button type="button"
|
||||||
title={{label}}
|
title={label}
|
||||||
aria-label={{label}}
|
aria-label={label}
|
||||||
aria-pressed={{pressable ? !!pressed : ''}}
|
aria-pressed={pressable ? !!pressed : ''}
|
||||||
class={{computedClass}}
|
class={computedClass}
|
||||||
focus-key={{focusKey || ''}}
|
focus-key={focusKey || ''}
|
||||||
:disabled
|
{disabled}
|
||||||
on:click >
|
on:click >
|
||||||
<svg class="icon-button-svg {{svgClassName || ''}}" ref:svg>
|
<svg class="icon-button-svg {svgClassName || ''}" ref:svg>
|
||||||
<use xlink:href={{href}} />
|
<use xlink:href={href} />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
{{/if}}
|
{/if}
|
||||||
<style>
|
<style>
|
||||||
.icon-button {
|
.icon-button {
|
||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
|
@ -118,7 +118,7 @@
|
||||||
}),
|
}),
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
computedClass: (pressable, pressed, big, muted, className) => {
|
computedClass: ({ pressable, pressed, big, muted, className }) => {
|
||||||
return classname(
|
return classname(
|
||||||
'icon-button',
|
'icon-button',
|
||||||
!pressable && 'not-pressable',
|
!pressable && 'not-pressable',
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<Nav :page />
|
<Nav {page} />
|
||||||
|
|
||||||
<div class="container" tabindex="0" ref:container>
|
<div class="container" tabindex="0" ref:container>
|
||||||
<main>
|
<main>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</main>
|
</main>
|
||||||
{{#if !$isUserLoggedIn && page === 'home'}}
|
{#if !$isUserLoggedIn && page === 'home'}
|
||||||
<InformationalFooter />
|
<InformationalFooter />
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
import Nav from './Nav.html'
|
import Nav from './Nav.html'
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
<div class="lazy-image"
|
<div class="lazy-image"
|
||||||
style="width: {{width}}px; height: {{height}}px; background: {{background}};">
|
style="width: {width}px; height: {height}px; background: {background};">
|
||||||
{{#if displaySrc}}
|
{#if displaySrc}
|
||||||
<img
|
<img
|
||||||
class="{{hidden ? 'hidden' : ''}} {{className || ''}}"
|
class="{hidden ? 'hidden' : ''} {className || ''}"
|
||||||
aria-hidden={{ariaHidden || ''}}
|
aria-hidden={ariaHidden || ''}
|
||||||
alt={{alt || ''}}
|
alt={alt || ''}
|
||||||
title={{alt || ''}}
|
title={alt || ''}
|
||||||
src={{displaySrc}}
|
src={displaySrc}
|
||||||
:width
|
{width}
|
||||||
:height
|
{height}
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.lazy-image {
|
.lazy-image {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{{#if revealed}}
|
{#if revealed}
|
||||||
<:Component {pageComponent} :params />
|
<svelte:component this={pageComponent} {params} />
|
||||||
{{/if}}
|
{/if}
|
||||||
<script>
|
<script>
|
||||||
// On the very first page load, avoid doing a "reveal" because
|
// On the very first page load, avoid doing a "reveal" because
|
||||||
// it leads to a flash between when the SSR is shown, the two frame we hide it,
|
// it leads to a flash between when the SSR is shown, the two frame we hide it,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<div class="loading-mask-container {{shown ? 'loading-mask-container-shown' : ''}}">
|
<div class="loading-mask-container {shown ? 'loading-mask-container-shown' : ''}">
|
||||||
{{#if shown}}
|
{#if shown}
|
||||||
<div class="loading-mask">
|
<div class="loading-mask">
|
||||||
<LoadingSpinner maskStyle="true"/>
|
<LoadingSpinner maskStyle="true"/>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.loading-mask-container {
|
.loading-mask-container {
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
export default {
|
export default {
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
shown: ($logInToInstanceLoading) => $logInToInstanceLoading
|
shown: ({ $logInToInstanceLoading }) => $logInToInstanceLoading
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
LoadingSpinner
|
LoadingSpinner
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="loading-page {{shown ? '' : 'hidden'}}">
|
<div class="loading-page {shown ? '' : 'hidden'}">
|
||||||
<LoadingSpinner />
|
<LoadingSpinner />
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<svg class="loading-spinner-icon spin {{maskStyle ? 'mask-style' : ''}}"
|
<svg class="loading-spinner-icon spin {maskStyle ? 'mask-style' : ''}"
|
||||||
style="width: {{size}}px; height: {{size}}px;"
|
style="width: {size}px; height: {size}px;"
|
||||||
aria-label="Loading"
|
aria-label="Loading"
|
||||||
>
|
>
|
||||||
<use xlink:href="#fa-spinner" />
|
<use xlink:href="#fa-spinner" />
|
||||||
|
|
Before Width: | Height: | Size: 449 B After Width: | Height: | Size: 443 B |
|
@ -1,36 +1,36 @@
|
||||||
<nav class="main-nav">
|
<nav class="main-nav">
|
||||||
<ul class="main-nav-ul">
|
<ul class="main-nav-ul">
|
||||||
<li class="main-nav-li">
|
<li class="main-nav-li">
|
||||||
<NavItem :page name="home" href="/" svg="#pinafore-logo" label="Home" />
|
<NavItem {page} name="home" href="/" svg="#pinafore-logo" label="Home" />
|
||||||
</li>
|
</li>
|
||||||
<li class="main-nav-li">
|
<li class="main-nav-li">
|
||||||
<NavItem :page name="notifications" href="/notifications" svg="#fa-bell" label="Notifications" />
|
<NavItem {page} name="notifications" href="/notifications" svg="#fa-bell" label="Notifications" />
|
||||||
</li>
|
</li>
|
||||||
{{#if $pinnedPage === '/local'}}
|
{#if $pinnedPage === '/local'}
|
||||||
<li class="main-nav-li">
|
<li class="main-nav-li">
|
||||||
<NavItem :page name="local" href="/local" svg="#fa-users" label="Local" />
|
<NavItem {page} name="local" href="/local" svg="#fa-users" label="Local" />
|
||||||
</li>
|
</li>
|
||||||
{{elseif $pinnedPage === '/federated'}}
|
{:elseif $pinnedPage === '/federated'}
|
||||||
<li class="main-nav-li">
|
<li class="main-nav-li">
|
||||||
<NavItem :page name="federated" href="/federated" svg="#fa-globe" label="Federated" />
|
<NavItem {page} name="federated" href="/federated" svg="#fa-globe" label="Federated" />
|
||||||
</li>
|
</li>
|
||||||
{{elseif $pinnedPage === '/favorites'}}
|
{:elseif $pinnedPage === '/favorites'}
|
||||||
<li class="main-nav-li">
|
<li class="main-nav-li">
|
||||||
<NavItem :page name="favorites" href="/favorites" svg="#fa-star" label="Favorites" />
|
<NavItem {page} name="favorites" href="/favorites" svg="#fa-star" label="Favorites" />
|
||||||
</li>
|
</li>
|
||||||
{{elseif $pinnedPage.startsWith('/lists/')}}
|
{:elseif $pinnedPage.startsWith('/lists/')}
|
||||||
<li class="main-nav-li">
|
<li class="main-nav-li">
|
||||||
<NavItem :page name="lists" href={{$pinnedPage}} svg="#fa-bars" label={{$pinnedListTitle}} />
|
<NavItem {page} name="lists" href={$pinnedPage} svg="#fa-bars" label={$pinnedListTitle} />
|
||||||
</li>
|
</li>
|
||||||
{{/if}}
|
{/if}
|
||||||
<li class="main-nav-li">
|
<li class="main-nav-li">
|
||||||
<NavItem :page name="community" href="/community" svg="#fa-comments" label="Community" />
|
<NavItem {page} name="community" href="/community" svg="#fa-comments" label="Community" />
|
||||||
</li>
|
</li>
|
||||||
<li class="main-nav-li">
|
<li class="main-nav-li">
|
||||||
<NavItem :page name="search" href="/search" svg="#fa-search" label="Search" />
|
<NavItem {page} name="search" href="/search" svg="#fa-search" label="Search" />
|
||||||
</li>
|
</li>
|
||||||
<li class="main-nav-li">
|
<li class="main-nav-li">
|
||||||
<NavItem :page name="settings" href="/settings" svg="#fa-gear" label="Settings" />
|
<NavItem {page} name="settings" href="/settings" svg="#fa-gear" label="Settings" />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
<a class='main-nav-link {{selected ? "selected" : ""}}'
|
<a class='main-nav-link {selected ? "selected" : ""}'
|
||||||
aria-label={{ariaLabel}}
|
aria-label={ariaLabel}
|
||||||
aria-current={{selected}}
|
aria-current={selected}
|
||||||
on:click="onClick(event)"
|
on:click="onClick(event)"
|
||||||
:href >
|
{href} >
|
||||||
{{#if name === 'notifications'}}
|
{#if name === 'notifications'}
|
||||||
<div class="nav-link-svg-wrapper">
|
<div class="nav-link-svg-wrapper">
|
||||||
<svg class="nav-link-svg">
|
<svg class="nav-link-svg">
|
||||||
<use xlink:href={{svg}} />
|
<use xlink:href={svg} />
|
||||||
</svg>
|
</svg>
|
||||||
{{#if $hasNotifications}}
|
{#if $hasNotifications}
|
||||||
<span class="nav-link-notifications" aria-hidden="true">
|
<span class="nav-link-notifications" aria-hidden="true">
|
||||||
{{$numberOfNotifications}}
|
{$numberOfNotifications}
|
||||||
</span>
|
</span>
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{:else}
|
||||||
<svg class="nav-link-svg">
|
<svg class="nav-link-svg">
|
||||||
<use xlink:href={{svg}} />
|
<use xlink:href={svg} />
|
||||||
</svg>
|
</svg>
|
||||||
{{/if}}
|
{/if}
|
||||||
<span class="nav-link-label">{{label}}</span>
|
<span class="nav-link-label">{label}</span>
|
||||||
</a>
|
</a>
|
||||||
<style>
|
<style>
|
||||||
.main-nav-link {
|
.main-nav-link {
|
||||||
|
@ -122,8 +122,8 @@
|
||||||
export default {
|
export default {
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
selected: (page, name) => page === name,
|
selected: ({ page, name }) => page === name,
|
||||||
ariaLabel: (selected, name, label, $numberOfNotifications) => {
|
ariaLabel: ({ selected, name, label, $numberOfNotifications }) => {
|
||||||
let res = label
|
let res = label
|
||||||
if (selected) {
|
if (selected) {
|
||||||
res += ' (current page)'
|
res += ' (current page)'
|
||||||
|
|
|
@ -1,29 +1,29 @@
|
||||||
<div class="non-autoplay-gifv" style="width: {{width}}px; height: {{height}}px;"
|
<div class="non-autoplay-gifv" style="width: {width}px; height: {height}px;"
|
||||||
on:mouseover="onMouseOver(event)"
|
on:mouseover="onMouseOver(event)"
|
||||||
ref:node
|
ref:node
|
||||||
>
|
>
|
||||||
{{#if playing}}
|
{#if playing}
|
||||||
<AutoplayVideo
|
<AutoplayVideo
|
||||||
className={{class}}
|
className={class}
|
||||||
ariaLabel={{label}}
|
ariaLabel={label}
|
||||||
:poster
|
{poster}
|
||||||
:src
|
{src}
|
||||||
:width
|
{width}
|
||||||
:height
|
{height}
|
||||||
/>
|
/>
|
||||||
{{else}}
|
{:else}
|
||||||
<LazyImage
|
<LazyImage
|
||||||
alt={{label || ''}}
|
alt={label || ''}
|
||||||
title={{label || ''}}
|
title={label || ''}
|
||||||
src={{staticSrc}}
|
src={staticSrc}
|
||||||
fallback={{oneTransparentPixel}}
|
fallback={oneTransparentPixel}
|
||||||
:width
|
{width}
|
||||||
:height
|
{height}
|
||||||
background="var(--loading-bg)"
|
background="var(--loading-bg)"
|
||||||
className={{class}}
|
className={class}
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{/if}
|
||||||
<PlayVideoIcon className={{playing ? 'hidden' : ''}}/>
|
<PlayVideoIcon className={playing ? 'hidden' : ''}/>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.non-autoplay-gifv {
|
.non-autoplay-gifv {
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
{{#if staticSrc === src}}
|
{#if staticSrc === src}
|
||||||
<img class={{className || ''}}
|
<img class={className || ''}
|
||||||
aria-hidden={{ariaHidden}}
|
aria-hidden={ariaHidden}
|
||||||
alt={{alt || ''}}
|
alt={alt || ''}
|
||||||
title={{alt || ''}}
|
title={alt || ''}
|
||||||
:src
|
{src}
|
||||||
on:imgLoad
|
on:imgLoad
|
||||||
on:imgLoadError />
|
on:imgLoadError />
|
||||||
{{else}}
|
{:else}
|
||||||
<img class="{{className || ''}} non-autoplay-zoom-in {{isLink ? 'is-link' : ''}}"
|
<img class="{className || ''} non-autoplay-zoom-in {isLink ? 'is-link' : ''}"
|
||||||
aria-hidden={{ariaHidden}}
|
aria-hidden={ariaHidden}
|
||||||
alt={{alt || ''}}
|
alt={alt || ''}
|
||||||
title={{alt || ''}}
|
title={alt || ''}
|
||||||
src={{staticSrc}}
|
src={staticSrc}
|
||||||
on:imgLoad
|
on:imgLoad
|
||||||
on:imgLoadError
|
on:imgLoadError
|
||||||
on:mouseover="onMouseOver(event)"
|
on:mouseover="onMouseOver(event)"
|
||||||
ref:node />
|
ref:node />
|
||||||
{{/if}}
|
{/if}
|
||||||
<style>
|
<style>
|
||||||
.non-autoplay-zoom-in {
|
.non-autoplay-zoom-in {
|
||||||
cursor: zoom-in;
|
cursor: zoom-in;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="play-video-icon {{className || ''}}">
|
<div class="play-video-icon {className || ''}">
|
||||||
<svg class="play-video-icon-svg">
|
<svg class="play-video-icon-svg">
|
||||||
<use xlink:href="#fa-play-circle" />
|
<use xlink:href="#fa-play-circle" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
@ -3,18 +3,18 @@
|
||||||
without a div wrapper due to sticky-positioned compose button.
|
without a div wrapper due to sticky-positioned compose button.
|
||||||
TODO: this is a bit hacky due to code duplication
|
TODO: this is a bit hacky due to code duplication
|
||||||
-->
|
-->
|
||||||
<div class="timeline-home-page" aria-busy={{hideTimeline}}>
|
<div class="timeline-home-page" aria-busy={hideTimeline}>
|
||||||
{{#if hidePage}}
|
{#if hidePage}
|
||||||
<LoadingPage />
|
<LoadingPage />
|
||||||
{{/if}}
|
{/if}
|
||||||
{{#if $currentVerifyCredentials }}
|
{#if $currentVerifyCredentials }
|
||||||
<ComposeBox realm="home" hidden={{hidePage}}/>
|
<ComposeBox realm="home" hidden={hidePage}/>
|
||||||
{{/if}}
|
{/if}
|
||||||
<div class="timeline-home-anchor-container">
|
<div class="timeline-home-anchor-container">
|
||||||
{{#if !hidePage && hideTimeline}}
|
{#if !hidePage && hideTimeline}
|
||||||
<LoadingPage />
|
<LoadingPage />
|
||||||
{{/if}}
|
{/if}
|
||||||
<div class="timeline-home-reveal-container {{hideTimeline ? 'hidden' : ''}}">
|
<div class="timeline-home-reveal-container {hideTimeline ? 'hidden' : ''}">
|
||||||
<LazyTimeline timeline="home" />
|
<LazyTimeline timeline="home" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,8 +41,8 @@
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
hidePage: ($timelineInitialized, $timelinePreinitialized) => !$timelineInitialized && !$timelinePreinitialized,
|
hidePage: ({ $timelineInitialized, $timelinePreinitialized }) => !$timelineInitialized && !$timelinePreinitialized,
|
||||||
hideTimeline: ($timelineInitialized) => !$timelineInitialized
|
hideTimeline: ({ $timelineInitialized }) => !$timelineInitialized
|
||||||
},
|
},
|
||||||
store: () => store,
|
store: () => store,
|
||||||
components: {
|
components: {
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
<div class="timeline-page" aria-busy={{hideTimeline}}>
|
<div class="timeline-page" aria-busy={hideTimeline}>
|
||||||
{{#if hidePage}}
|
{#if hidePage}
|
||||||
<LoadingPage />
|
<LoadingPage />
|
||||||
{{/if}}
|
{/if}
|
||||||
<div class="timeline-slot-reveal-container {{hidePage ? 'hidden' : ''}}">
|
<div class="timeline-slot-reveal-container {hidePage ? 'hidden' : ''}">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="timeline-anchor-container">
|
<div class="timeline-anchor-container">
|
||||||
{{#if !hidePage && hideTimeline}}
|
{#if !hidePage && hideTimeline}
|
||||||
<LoadingPage />
|
<LoadingPage />
|
||||||
{{/if}}
|
{/if}
|
||||||
<div class="timeline-reveal-container {{hideTimeline ? 'hidden' : ''}}">
|
<div class="timeline-reveal-container {hideTimeline ? 'hidden' : ''}">
|
||||||
<LazyTimeline :timeline />
|
<LazyTimeline {timeline} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -35,8 +35,8 @@
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
hidePage: ($timelineInitialized, $timelinePreinitialized) => !$timelineInitialized && !$timelinePreinitialized,
|
hidePage: ({ $timelineInitialized, $timelinePreinitialized }) => !$timelineInitialized && !$timelinePreinitialized,
|
||||||
hideTimeline: ($timelineInitialized) => !$timelineInitialized
|
hideTimeline: ({ $timelineInitialized }) => !$timelineInitialized
|
||||||
},
|
},
|
||||||
store: () => store,
|
store: () => store,
|
||||||
components: {
|
components: {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="toast-modal {{shown ? 'shown' : ''}}" role="alert" aria-hidden={{shown}}>
|
<div class="toast-modal {shown ? 'shown' : ''}" role="alert" aria-hidden={shown}>
|
||||||
<div class="toast-container">
|
<div class="toast-container">
|
||||||
{{text}}
|
{text}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<div class="page-list-wrapper">
|
<div class="page-list-wrapper">
|
||||||
{{#if label}}
|
{#if label}
|
||||||
<ul class="page-list" aria-label={{label}}>
|
<ul class="page-list" aria-label={label}>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</ul>
|
</ul>
|
||||||
{{else}}
|
{:else}
|
||||||
<ul class="page-list">
|
<ul class="page-list">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</ul>
|
</ul>
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.page-list-wrapper {
|
.page-list-wrapper {
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
<li class="page-list-item">
|
<li class="page-list-item">
|
||||||
<a :href>
|
<a {href}>
|
||||||
<svg class="page-list-item-svg">
|
<svg class="page-list-item-svg">
|
||||||
<use xlink:href={{icon}} />
|
<use xlink:href={icon} />
|
||||||
</svg>
|
</svg>
|
||||||
<span aria-label="{{label}} {{$pinnedPage === href ? 'Pinned page' : 'Unpinned page'}}">
|
<span aria-label="{label} {$pinnedPage === href ? 'Pinned page' : 'Unpinned page'}">
|
||||||
{{label}}
|
{label}
|
||||||
</span>
|
</span>
|
||||||
{{#if pinnable}}
|
{#if pinnable}
|
||||||
<IconButton pressable="true"
|
<IconButton pressable="true"
|
||||||
pressed={{$pinnedPage === href}}
|
pressed={$pinnedPage === href}
|
||||||
label={{$pinnedPage === href ? 'Unpin timeline' : 'Pin timeline'}}
|
label={$pinnedPage === href ? 'Unpin timeline' : 'Pin timeline'}
|
||||||
href="#fa-thumb-tack"
|
href="#fa-thumb-tack"
|
||||||
on:click="onPinClick(event)" />
|
on:click="onPinClick(event)" />
|
||||||
{{/if}}
|
{/if}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<a href="/accounts/{{verifyCredentials.id}}"
|
<a href="/accounts/{verifyCredentials.id}"
|
||||||
class="compose-box-avatar"
|
class="compose-box-avatar"
|
||||||
aria-label="Profile for {{verifyCredentials.display_name || verifyCredentials.acct}}">
|
aria-label="Profile for {verifyCredentials.display_name || verifyCredentials.acct}">
|
||||||
<Avatar account={{verifyCredentials}} size="small"/>
|
<Avatar account={verifyCredentials} size="small"/>
|
||||||
</a>
|
</a>
|
||||||
<a class="compose-box-display-name" href="/accounts/{{verifyCredentials.id}}">
|
<a class="compose-box-display-name" href="/accounts/{verifyCredentials.id}">
|
||||||
{{verifyCredentials.display_name || verifyCredentials.acct}}
|
{verifyCredentials.display_name || verifyCredentials.acct}
|
||||||
</a>
|
</a>
|
||||||
<span class="compose-box-handle">
|
<span class="compose-box-handle">
|
||||||
{{'@' + verifyCredentials.acct}}
|
{'@' + verifyCredentials.acct}
|
||||||
</span>
|
</span>
|
||||||
<style>
|
<style>
|
||||||
.compose-box-avatar {
|
.compose-box-avatar {
|
||||||
|
@ -57,7 +57,7 @@
|
||||||
},
|
},
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
verifyCredentials: ($currentVerifyCredentials) => $currentVerifyCredentials
|
verifyCredentials: ({ $currentVerifyCredentials }) => $currentVerifyCredentials
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,10 +1,10 @@
|
||||||
<div class="compose-autosuggest {{shown ? 'shown' : ''}} {{realm === 'dialog' ? 'is-dialog' : ''}}"
|
<div class="compose-autosuggest {shown ? 'shown' : ''} {realm === 'dialog' ? 'is-dialog' : ''}"
|
||||||
aria-hidden="true" >
|
aria-hidden="true" >
|
||||||
<ComposeAutosuggestionList
|
<ComposeAutosuggestionList
|
||||||
items={{searchResults}}
|
items={searchResults}
|
||||||
on:click="onClick(event)"
|
on:click="onClick(event)"
|
||||||
:type
|
{type}
|
||||||
:selected
|
{selected}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
|
@ -139,13 +139,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
composeSelectionStart: ($composeSelectionStart) => $composeSelectionStart,
|
composeSelectionStart: ({ $composeSelectionStart }) => $composeSelectionStart,
|
||||||
composeFocused: ($composeFocused) => $composeFocused,
|
composeFocused: ({ $composeFocused }) => $composeFocused,
|
||||||
thisComposeFocused: (composeFocusedDeferred, realm) => composeFocusedDeferred === realm,
|
thisComposeFocused: ({ composeFocusedDeferred, realm }) => composeFocusedDeferred === realm,
|
||||||
searchResults: ($composeAutosuggestionSearchResults) => $composeAutosuggestionSearchResults || [],
|
searchResults: ({ $composeAutosuggestionSearchResults }) => $composeAutosuggestionSearchResults || [],
|
||||||
type: ($composeAutosuggestionType) => $composeAutosuggestionType || 'account',
|
type: ({ $composeAutosuggestionType }) => $composeAutosuggestionType || 'account',
|
||||||
selected: ($composeAutosuggestionSelected) => $composeAutosuggestionSelected || 0,
|
selected: ({ $composeAutosuggestionSelected }) => $composeAutosuggestionSelected || 0,
|
||||||
searchText: (text, composeSelectionStartDeferred, thisComposeFocused) => {
|
searchText: ({ text, composeSelectionStartDeferred, thisComposeFocused }) => {
|
||||||
if (!thisComposeFocused) {
|
if (!thisComposeFocused) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@
|
||||||
let match = textUpToCursor.match(ACCOUNT_SEARCH_REGEX) || textUpToCursor.match(EMOJI_SEARCH_REGEX)
|
let match = textUpToCursor.match(ACCOUNT_SEARCH_REGEX) || textUpToCursor.match(EMOJI_SEARCH_REGEX)
|
||||||
return match && match[1]
|
return match && match[1]
|
||||||
},
|
},
|
||||||
shown: (thisComposeFocused, searchText, searchResults) => {
|
shown: ({ thisComposeFocused, searchText, searchResults }) => {
|
||||||
return !!(thisComposeFocused &&
|
return !!(thisComposeFocused &&
|
||||||
searchText &&
|
searchText &&
|
||||||
searchResults.length)
|
searchResults.length)
|
||||||
|
|
|
@ -1,35 +1,35 @@
|
||||||
<ul class="compose-autosuggest-list">
|
<ul class="compose-autosuggest-list">
|
||||||
{{#each items as item, i}}
|
{#each items as item, i}
|
||||||
<li class="compose-autosuggest-list-item">
|
<li class="compose-autosuggest-list-item">
|
||||||
<button class="compose-autosuggest-list-button {{i === selected ? 'selected' : ''}}"
|
<button class="compose-autosuggest-list-button {i === selected ? 'selected' : ''}"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
on:click="fire('click', item)">
|
on:click="fire('click', item)">
|
||||||
<div class="compose-autosuggest-list-grid">
|
<div class="compose-autosuggest-list-grid">
|
||||||
{{#if type === 'account'}}
|
{#if type === 'account'}
|
||||||
<Avatar
|
<Avatar
|
||||||
className="compose-autosuggest-list-item-avatar"
|
className="compose-autosuggest-list-item-avatar"
|
||||||
size="small"
|
size="small"
|
||||||
account={{item}}
|
account={item}
|
||||||
/>
|
/>
|
||||||
<span class="compose-autosuggest-list-display-name">
|
<span class="compose-autosuggest-list-display-name">
|
||||||
{{item.display_name || item.acct}}
|
{item.display_name || item.acct}
|
||||||
</span>
|
</span>
|
||||||
<span class="compose-autosuggest-list-username">
|
<span class="compose-autosuggest-list-username">
|
||||||
{{'@' + item.acct}}
|
{'@' + item.acct}
|
||||||
</span>
|
</span>
|
||||||
{{else}}
|
{:else}
|
||||||
<img src={{$autoplayGifs ? item.url : item.static_url}}
|
<img src={$autoplayGifs ? item.url : item.static_url}
|
||||||
class="compose-autosuggest-list-item-icon"
|
class="compose-autosuggest-list-item-icon"
|
||||||
alt="{{':' + item.shortcode + ':'}}"
|
alt="{':' + item.shortcode + ':'}"
|
||||||
/>
|
/>
|
||||||
<span class="compose-autosuggest-list-display-name">
|
<span class="compose-autosuggest-list-display-name">
|
||||||
{{':' + item.shortcode + ':'}}
|
{':' + item.shortcode + ':'}
|
||||||
</span>
|
</span>
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
<style>
|
<style>
|
||||||
.compose-autosuggest-list {
|
.compose-autosuggest-list {
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
{{#if realm === 'home'}}
|
{#if realm === 'home'}
|
||||||
<h1 class="sr-only">Compose toot</h1>
|
<h1 class="sr-only">Compose toot</h1>
|
||||||
{{/if}}
|
{/if}
|
||||||
<div class="{{computedClassName}} {{hideAndFadeIn}}">
|
<div class="{computedClassName} {hideAndFadeIn}">
|
||||||
<ComposeAuthor />
|
<ComposeAuthor />
|
||||||
{{#if contentWarningShown}}
|
{#if contentWarningShown}
|
||||||
<div class="compose-content-warning-wrapper"
|
<div class="compose-content-warning-wrapper"
|
||||||
transition:slide="{duration: 333}">
|
transition:slide="{duration: 333}">
|
||||||
<ComposeContentWarning :realm :contentWarning />
|
<ComposeContentWarning {realm} {contentWarning} />
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{/if}
|
||||||
<ComposeInput :realm :text :autoFocus on:postAction="doPostStatus()" />
|
<ComposeInput {realm} {text} {autoFocus} on:postAction="doPostStatus()" />
|
||||||
<ComposeLengthGauge :length :overLimit />
|
<ComposeLengthGauge {length} {overLimit} />
|
||||||
<ComposeToolbar :realm :postPrivacy :media :contentWarningShown :text />
|
<ComposeToolbar {realm} {postPrivacy} {media} {contentWarningShown} {text} />
|
||||||
<ComposeLengthIndicator :length :overLimit />
|
<ComposeLengthIndicator {length} {overLimit} />
|
||||||
<ComposeMedia :realm :media :mediaDescriptions />
|
<ComposeMedia {realm} {media} {mediaDescriptions} />
|
||||||
</div>
|
</div>
|
||||||
<div class="compose-box-button-sentinel {{hideAndFadeIn}}" ref:sentinel></div>
|
<div class="compose-box-button-sentinel {hideAndFadeIn}" ref:sentinel></div>
|
||||||
<div class="compose-box-button-wrapper {{realm === 'home' ? 'compose-button-sticky' : ''}} {{hideAndFadeIn}}" >
|
<div class="compose-box-button-wrapper {realm === 'home' ? 'compose-button-sticky' : ''} {hideAndFadeIn}" >
|
||||||
<ComposeButton :length :overLimit :sticky on:click="onClickPostButton()" />
|
<ComposeButton {length} {overLimit} {sticky} on:click="onClickPostButton()" />
|
||||||
</div>
|
</div>
|
||||||
{{#if !hideBottomBorder}}
|
{#if !hideBottomBorder}
|
||||||
<div class="compose-box-border-bottom {{hideAndFadeIn}}"></div>
|
<div class="compose-box-border-bottom {hideAndFadeIn}"></div>
|
||||||
{{/if}}
|
{/if}
|
||||||
<style>
|
<style>
|
||||||
.compose-box {
|
.compose-box {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
@ -162,32 +162,32 @@
|
||||||
}),
|
}),
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
computedClassName: (overLimit, realm, size, postPrivacyKey, isReply) => (classname(
|
computedClassName: ({ overLimit, realm, size, postPrivacyKey, isReply }) => (classname(
|
||||||
'compose-box',
|
'compose-box',
|
||||||
overLimit && 'over-char-limit',
|
overLimit && 'over-char-limit',
|
||||||
size === 'slim' && 'slim-size',
|
size === 'slim' && 'slim-size',
|
||||||
isReply && postPrivacyKey === 'direct' && 'direct-reply'
|
isReply && postPrivacyKey === 'direct' && 'direct-reply'
|
||||||
)),
|
)),
|
||||||
hideAndFadeIn: (hidden) => (classname(
|
hideAndFadeIn: ({ hidden }) => (classname(
|
||||||
'compose-box-fade-in',
|
'compose-box-fade-in',
|
||||||
hidden && 'hidden'
|
hidden && 'hidden'
|
||||||
)),
|
)),
|
||||||
composeData: ($currentComposeData, realm) => $currentComposeData[realm] || {},
|
composeData: ({ $currentComposeData, realm }) => $currentComposeData[realm] || {},
|
||||||
text: (composeData) => composeData.text || '',
|
text: ({ composeData }) => composeData.text || '',
|
||||||
media: (composeData) => composeData.media || [],
|
media: ({ composeData }) => composeData.media || [],
|
||||||
postPrivacy: (postPrivacyKey) => POST_PRIVACY_OPTIONS.find(_ => _.key === postPrivacyKey),
|
postPrivacy: ({ postPrivacyKey }) => POST_PRIVACY_OPTIONS.find(_ => _.key === postPrivacyKey),
|
||||||
defaultPostPrivacyKey: ($currentVerifyCredentials) => $currentVerifyCredentials.source.privacy,
|
defaultPostPrivacyKey: ({ $currentVerifyCredentials }) => $currentVerifyCredentials.source.privacy,
|
||||||
postPrivacyKey: (composeData, defaultPostPrivacyKey) => composeData.postPrivacy || defaultPostPrivacyKey,
|
postPrivacyKey: ({ composeData, defaultPostPrivacyKey }) => composeData.postPrivacy || defaultPostPrivacyKey,
|
||||||
textLength: (text) => measureText(text),
|
textLength: ({ text }) => measureText(text),
|
||||||
contentWarningLength: (contentWarning) => measureText(contentWarning),
|
contentWarningLength: ({ contentWarning }) => measureText(contentWarning),
|
||||||
length: (textLength, contentWarningLength, contentWarningShown) => (
|
length: ({ textLength, contentWarningLength, contentWarningShown }) => (
|
||||||
textLength + (contentWarningShown ? contentWarningLength : 0)
|
textLength + (contentWarningShown ? contentWarningLength : 0)
|
||||||
),
|
),
|
||||||
overLimit: (length) => length > CHAR_LIMIT,
|
overLimit: ({ length }) => length > CHAR_LIMIT,
|
||||||
contentWarningShown: (composeData) => composeData.contentWarningShown,
|
contentWarningShown: ({ composeData }) => composeData.contentWarningShown,
|
||||||
contentWarning: (composeData) => composeData.contentWarning || '',
|
contentWarning: ({ composeData }) => composeData.contentWarning || '',
|
||||||
timelineInitialized: ($timelineInitialized) => $timelineInitialized,
|
timelineInitialized: ({ $timelineInitialized }) => $timelineInitialized,
|
||||||
mediaDescriptions: (composeData) => composeData.mediaDescriptions || []
|
mediaDescriptions: ({ composeData }) => composeData.mediaDescriptions || []
|
||||||
},
|
},
|
||||||
transitions: {
|
transitions: {
|
||||||
slide
|
slide
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
<div class="compose-box-button-halo">
|
<div class="compose-box-button-halo">
|
||||||
<button class="primary compose-box-button"
|
<button class="primary compose-box-button"
|
||||||
:disabled
|
{disabled}
|
||||||
aria-label={{sticky ? 'Compose' : 'Toot!'}}
|
aria-label={sticky ? 'Compose' : 'Toot!'}
|
||||||
on:click>
|
on:click>
|
||||||
<span class={{$postingStatus || sticky ? 'hidden' : ''}}>
|
<span class={$postingStatus || sticky ? 'hidden' : ''}>
|
||||||
Toot!
|
Toot!
|
||||||
</span>
|
</span>
|
||||||
<div class="compose-box-button-spinner"
|
<div class="compose-box-button-spinner"
|
||||||
aria-hidden="true">
|
aria-hidden="true">
|
||||||
<svg class="compose-box-button-svg {{$postingStatus ? 'spin' : 'hidden'}}">
|
<svg class="compose-box-button-svg {$postingStatus ? 'spin' : 'hidden'}">
|
||||||
<use xlink:href="#fa-spinner" />
|
<use xlink:href="#fa-spinner" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="compose-box-button-compose {{sticky ? '' : 'hidden'}}"
|
<div class="compose-box-button-compose {sticky ? '' : 'hidden'}"
|
||||||
aria-hidden="true">
|
aria-hidden="true">
|
||||||
<svg class="compose-box-button-svg">
|
<svg class="compose-box-button-svg">
|
||||||
<use xlink:href="#fa-pencil" />
|
<use xlink:href="#fa-pencil" />
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
export default {
|
export default {
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
disabled: ($postingStatus, overLimit) => $postingStatus || overLimit
|
disabled: ({ $postingStatus, overLimit }) => $postingStatus || overLimit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="compose-box-length-gauge {{shouldAnimate ? 'should-animate' : ''}} {{overLimit ? 'over-char-limit' : ''}}"
|
<div class="compose-box-length-gauge {shouldAnimate ? 'should-animate' : ''} {overLimit ? 'over-char-limit' : ''}"
|
||||||
style="transform: scaleX({{lengthAsFractionDeferred}});"
|
style="transform: scaleX({lengthAsFractionDeferred});"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
></div>
|
></div>
|
||||||
<style>
|
<style>
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
}),
|
}),
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
lengthAsFraction: (length) => {
|
lengthAsFraction: ({ length }) => {
|
||||||
// We don't need to update the gauge for every decimal point, so round it to the nearest 0.02
|
// We don't need to update the gauge for every decimal point, so round it to the nearest 0.02
|
||||||
let int = Math.round(Math.min(CHAR_LIMIT, length) / CHAR_LIMIT * 100)
|
let int = Math.round(Math.min(CHAR_LIMIT, length) / CHAR_LIMIT * 100)
|
||||||
return (int - (int % 2)) / 100
|
return (int - (int % 2)) / 100
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<span class="compose-box-length {{overLimit ? 'over-char-limit' : ''}}"
|
<span class="compose-box-length {overLimit ? 'over-char-limit' : ''}"
|
||||||
aria-label={{lengthLabel}}>
|
aria-label={lengthLabel}>
|
||||||
{{lengthToDisplayDeferred}}
|
{lengthToDisplayDeferred}
|
||||||
</span>
|
</span>
|
||||||
<style>
|
<style>
|
||||||
.compose-box-length {
|
.compose-box-length {
|
||||||
|
@ -41,8 +41,8 @@
|
||||||
}),
|
}),
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
lengthToDisplay: (length) => CHAR_LIMIT - length,
|
lengthToDisplay: ({ length }) => CHAR_LIMIT - length,
|
||||||
lengthLabel: (overLimit, lengthToDisplayDeferred) => {
|
lengthLabel: ({ overLimit, lengthToDisplayDeferred }) => {
|
||||||
if (overLimit) {
|
if (overLimit) {
|
||||||
return `${lengthToDisplayDeferred} characters over limit`
|
return `${lengthToDisplayDeferred} characters over limit`
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
{{#if media.length}}
|
{#if media.length}
|
||||||
<div class="compose-media-container" style="grid-template-columns: repeat({{media.length}}, 1fr);">
|
<div class="compose-media-container" style="grid-template-columns: repeat({media.length}, 1fr);">
|
||||||
{{#each media as mediaItem, index}}
|
{#each media as mediaItem, index}
|
||||||
<ComposeMediaItem :realm :mediaItem :index :mediaDescriptions />
|
<ComposeMediaItem {realm} {mediaItem} {index} {mediaDescriptions} />
|
||||||
{{/each}}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{/if}
|
||||||
<style>
|
<style>
|
||||||
.compose-media-container {
|
.compose-media-container {
|
||||||
grid-area: media;
|
grid-area: media;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<div class="compose-media">
|
<div class="compose-media">
|
||||||
<img src={{mediaItem.data.preview_url}} alt={{mediaItem.file.name}}/>
|
<img src={mediaItem.data.preview_url} alt={mediaItem.file.name}/>
|
||||||
<div class="compose-media-delete">
|
<div class="compose-media-delete">
|
||||||
<button class="compose-media-delete-button"
|
<button class="compose-media-delete-button"
|
||||||
aria-label="Delete {{mediaItem.file.name}}"
|
aria-label="Delete {mediaItem.file.name}"
|
||||||
on:click="onDeleteMedia()" >
|
on:click="onDeleteMedia()" >
|
||||||
<svg class="compose-media-delete-button-svg">
|
<svg class="compose-media-delete-button-svg">
|
||||||
<use xlink:href="#fa-times" />
|
<use xlink:href="#fa-times" />
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<div class="compose-media-alt">
|
<div class="compose-media-alt">
|
||||||
<input type="text"
|
<input type="text"
|
||||||
placeholder="Description"
|
placeholder="Description"
|
||||||
aria-label="Describe {{mediaItem.file.name}} for the visually impaired"
|
aria-label="Describe {mediaItem.file.name} for the visually impaired"
|
||||||
bind:value=rawText
|
bind:value=rawText
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,23 +6,23 @@
|
||||||
on:click="onEmojiClick()"
|
on:click="onEmojiClick()"
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
svgClassName={{$uploadingMedia ? 'spin' : ''}}
|
svgClassName={$uploadingMedia ? 'spin' : ''}
|
||||||
label="Add media"
|
label="Add media"
|
||||||
href={{$uploadingMedia ? '#fa-spinner' : '#fa-camera'}}
|
href={$uploadingMedia ? '#fa-spinner' : '#fa-camera'}
|
||||||
on:click="onMediaClick()"
|
on:click="onMediaClick()"
|
||||||
disabled={{$uploadingMedia || (media.length === 4)}}
|
disabled={$uploadingMedia || (media.length === 4)}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
label="Adjust privacy (currently {{postPrivacy.label}})"
|
label="Adjust privacy (currently {postPrivacy.label})"
|
||||||
href={{postPrivacy.icon}}
|
href={postPrivacy.icon}
|
||||||
on:click="onPostPrivacyClick()"
|
on:click="onPostPrivacyClick()"
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
label={{contentWarningShown ? 'Remove content warning' : 'Add content warning'}}
|
label={contentWarningShown ? 'Remove content warning' : 'Add content warning'}
|
||||||
href="#fa-exclamation-triangle"
|
href="#fa-exclamation-triangle"
|
||||||
on:click="onContentWarningClick()"
|
on:click="onContentWarningClick()"
|
||||||
pressable="true"
|
pressable="true"
|
||||||
pressed={{contentWarningShown}}
|
pressed={contentWarningShown}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<input ref:input
|
<input ref:input
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
style="display: none;"
|
style="display: none;"
|
||||||
type="file"
|
type="file"
|
||||||
accept=".jpg,.jpeg,.png,.gif,.webm,.mp4,.m4v,image/jpeg,image/png,image/gif,video/webm,video/mp4">
|
accept=".jpg,.jpeg,.png,.gif,.webm,.mp4,.m4v,image/jpeg,image/png,image/gif,video/webm,video/mp4">
|
||||||
<ComposeAutosuggest :realm :text />
|
<ComposeAutosuggest {realm} {text} />
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.compose-box-toolbar {
|
.compose-box-toolbar {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<ModalDialog
|
<ModalDialog
|
||||||
:id
|
{id}
|
||||||
:label
|
{label}
|
||||||
:title
|
{title}
|
||||||
background="var(--main-bg)"
|
background="var(--main-bg)"
|
||||||
>
|
>
|
||||||
<GenericDialogList :items on:click="onClick(event)"/>
|
<GenericDialogList {items} on:click="onClick(event)"/>
|
||||||
</ModalDialog>
|
</ModalDialog>
|
||||||
<script>
|
<script>
|
||||||
import ModalDialog from './ModalDialog.html'
|
import ModalDialog from './ModalDialog.html'
|
||||||
|
@ -27,14 +27,14 @@ export default {
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
// begin account data copypasta
|
// begin account data copypasta
|
||||||
verifyCredentialsId: (verifyCredentials) => verifyCredentials.id,
|
verifyCredentialsId: ({ verifyCredentials }) => verifyCredentials.id,
|
||||||
following: (relationship) => relationship && relationship.following,
|
following: ({ relationship }) => relationship && relationship.following,
|
||||||
followRequested: (relationship) => relationship && relationship.requested,
|
followRequested: ({ relationship }) => relationship && relationship.requested,
|
||||||
accountId: (account) => account && account.id,
|
accountId: ({ account }) => account && account.id,
|
||||||
acct: (account) => account.acct,
|
acct: ({ account }) => account.acct,
|
||||||
muting: (relationship) => relationship.muting,
|
muting: ({ relationship }) => relationship.muting,
|
||||||
blocking: (relationship) => relationship.blocking,
|
blocking: ({ relationship }) => relationship.blocking,
|
||||||
followLabel: (following, followRequested, account, acct) => {
|
followLabel: ({ following, followRequested, account, acct }) => {
|
||||||
if (typeof following === 'undefined' || !account) {
|
if (typeof following === 'undefined' || !account) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
@ -42,21 +42,21 @@ export default {
|
||||||
? `Unfollow @${acct}`
|
? `Unfollow @${acct}`
|
||||||
: `Follow @${acct}`
|
: `Follow @${acct}`
|
||||||
},
|
},
|
||||||
followIcon: (following, followRequested) => {
|
followIcon: ({ following, followRequested }) => {
|
||||||
return following ? '#fa-user-times' : followRequested ? '#fa-hourglass' : '#fa-user-plus'
|
return following ? '#fa-user-times' : followRequested ? '#fa-hourglass' : '#fa-user-plus'
|
||||||
},
|
},
|
||||||
blockLabel: (blocking, acct) => {
|
blockLabel: ({ blocking, acct }) => {
|
||||||
return blocking ? `Unblock @${acct}` : `Block @${acct}`
|
return blocking ? `Unblock @${acct}` : `Block @${acct}`
|
||||||
},
|
},
|
||||||
blockIcon: (blocking) => blocking ? '#fa-unlock' : '#fa-ban',
|
blockIcon: ({ blocking }) => blocking ? '#fa-unlock' : '#fa-ban',
|
||||||
muteLabel: (muting, acct) => {
|
muteLabel: ({ muting, acct }) => {
|
||||||
return muting ? `Unmute @${acct}` : `Mute @${acct}`
|
return muting ? `Unmute @${acct}` : `Mute @${acct}`
|
||||||
},
|
},
|
||||||
muteIcon: (muting) => muting ? '#fa-volume-up' : '#fa-volume-off',
|
muteIcon: ({ muting }) => muting ? '#fa-volume-up' : '#fa-volume-off',
|
||||||
// end account data copypasta
|
// end account data copypasta
|
||||||
items: (blockLabel, blocking, blockIcon, muteLabel, muteIcon,
|
items: ({ blockLabel, blocking, blockIcon, muteLabel, muteIcon,
|
||||||
followLabel, followIcon, following, followRequested,
|
followLabel, followIcon, following, followRequested,
|
||||||
accountId, verifyCredentialsId, acct) => {
|
accountId, verifyCredentialsId, acct }) => {
|
||||||
let isUser = accountId === verifyCredentialsId
|
let isUser = accountId === verifyCredentialsId
|
||||||
return [
|
return [
|
||||||
!isUser && {
|
!isUser && {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<ModalDialog
|
<ModalDialog
|
||||||
:id
|
{id}
|
||||||
:label
|
{label}
|
||||||
:title
|
{title}
|
||||||
background="var(--main-bg)"
|
background="var(--main-bg)"
|
||||||
>
|
>
|
||||||
<ComposeBox realm="dialog" size="slim" autoFocus="true" />
|
<ComposeBox realm="dialog" size="slim" autoFocus="true" />
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
<ModalDialog
|
<ModalDialog
|
||||||
:id
|
{id}
|
||||||
:label
|
{label}
|
||||||
background="var(--main-bg)"
|
background="var(--main-bg)"
|
||||||
>
|
>
|
||||||
<form class="confirmation-dialog-form">
|
<form class="confirmation-dialog-form">
|
||||||
<p>
|
<p>
|
||||||
{{text}}
|
{text}
|
||||||
</p>
|
</p>
|
||||||
<div class="confirmation-dialog-form-flex">
|
<div class="confirmation-dialog-form-flex">
|
||||||
<button type="button" on:click="onPositive()">
|
<button type="button" on:click="onPositive()">
|
||||||
{{positiveText || 'OK'}}
|
{positiveText || 'OK'}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" on:click="onNegative()">
|
<button type="button" on:click="onNegative()">
|
||||||
{{negativeText || 'Cancel'}}
|
{negativeText || 'Cancel'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
<ModalDialog
|
<ModalDialog
|
||||||
:id
|
{id}
|
||||||
:label
|
{label}
|
||||||
:title
|
{title}
|
||||||
background="var(--main-bg)"
|
background="var(--main-bg)"
|
||||||
>
|
>
|
||||||
<div class="custom-emoji-container">
|
<div class="custom-emoji-container">
|
||||||
{{#if emojis.length}}
|
{#if emojis.length}
|
||||||
<ul class="custom-emoji-list">
|
<ul class="custom-emoji-list">
|
||||||
{{#each emojis as emoji}}
|
{#each emojis as emoji}
|
||||||
<li class="custom-emoji">
|
<li class="custom-emoji">
|
||||||
<button type="button" on:click="onClickEmoji(emoji)">
|
<button type="button" on:click="onClickEmoji(emoji)">
|
||||||
<img src={{$autoplayGifs ? emoji.url : emoji.static_url}}
|
<img src={$autoplayGifs ? emoji.url : emoji.static_url}
|
||||||
alt=":{{emoji.shortcode}}:"
|
alt=":{emoji.shortcode}:"
|
||||||
title=":{{emoji.shortcode}}:"
|
title=":{emoji.shortcode}:"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
{{else}}
|
{:else}
|
||||||
<div class="custom-emoji-no-emoji">No custom emoji found for this instance.</div>
|
<div class="custom-emoji-no-emoji">No custom emoji found for this instance.</div>
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</ModalDialog>
|
</ModalDialog>
|
||||||
<style>
|
<style>
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
},
|
},
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
emojis: ($currentCustomEmoji) => {
|
emojis: ({ $currentCustomEmoji }) => {
|
||||||
if (!$currentCustomEmoji) {
|
if (!$currentCustomEmoji) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
<ul class="generic-dialog-list">
|
<ul class="generic-dialog-list">
|
||||||
{{#each items as item @key}}
|
{#each items as item (item.key)}
|
||||||
<li class="generic-dialog-list-item">
|
<li class="generic-dialog-list-item">
|
||||||
<button class="generic-dialog-list-button" on:click="fire('click', item)">
|
<button class="generic-dialog-list-button" on:click="fire('click', item)">
|
||||||
<svg class="generic-dialog-list-item-svg">
|
<svg class="generic-dialog-list-item-svg">
|
||||||
<use xlink:href={{item.icon}} />
|
<use xlink:href={item.icon} />
|
||||||
</svg>
|
</svg>
|
||||||
<span>
|
<span>
|
||||||
{{item.label}}
|
{item.label}
|
||||||
</span>
|
</span>
|
||||||
<svg class="generic-dialog-list-item-svg {{item.selected ? '' : 'hidden'}}" aria-hidden={{!item.selected}}>
|
<svg class="generic-dialog-list-item-svg {item.selected ? '' : 'hidden'}" aria-hidden={!item.selected}>
|
||||||
<use xlink:href="#fa-check" />
|
<use xlink:href="#fa-check" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
<style>
|
<style>
|
||||||
.generic-dialog-list {
|
.generic-dialog-list {
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
<ModalDialog
|
<ModalDialog
|
||||||
:id
|
{id}
|
||||||
:label
|
{label}
|
||||||
background="var(--muted-modal-bg)"
|
background="var(--muted-modal-bg)"
|
||||||
muted="true"
|
muted="true"
|
||||||
className="image-modal-dialog"
|
className="image-modal-dialog"
|
||||||
>
|
>
|
||||||
{{#if type === 'gifv'}}
|
{#if type === 'gifv'}
|
||||||
<AutoplayVideo
|
<AutoplayVideo
|
||||||
ariaLabel="Animated GIF: {{description || ''}}"
|
ariaLabel="Animated GIF: {description || ''}"
|
||||||
:poster
|
{poster}
|
||||||
:src
|
{src}
|
||||||
:width
|
{width}
|
||||||
:height
|
{height}
|
||||||
/>
|
/>
|
||||||
{{else}}
|
{:else}
|
||||||
<img
|
<img
|
||||||
:src
|
{src}
|
||||||
:width
|
{width}
|
||||||
:height
|
{height}
|
||||||
alt={{description || ''}}
|
alt={description || ''}
|
||||||
title={{description || ''}}
|
title={description || ''}
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{/if}
|
||||||
</ModalDialog>
|
</ModalDialog>
|
||||||
<style>
|
<style>
|
||||||
:global(.image-modal-dialog img, .image-modal-dialog video) {
|
:global(.image-modal-dialog img, .image-modal-dialog video) {
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
<div class={{backdropClass}}
|
<div class={backdropClass}
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
data-a11y-dialog-hide
|
data-a11y-dialog-hide
|
||||||
></div>
|
></div>
|
||||||
<div class={{contentsClass}}
|
<div class={contentsClass}
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-label={{label || ''}}
|
aria-label={label || ''}
|
||||||
ref:node
|
ref:node
|
||||||
>
|
>
|
||||||
<div class="modal-dialog-document" role="document" style="background: {{background || '#000'}};">
|
<div class="modal-dialog-document" role="document" style="background: {background || '#000'};">
|
||||||
<div class="modal-dialog-header">
|
<div class="modal-dialog-header">
|
||||||
{{#if title}}
|
{#if title}
|
||||||
<h1 class="modal-dialog-title">{{title}}</h1>
|
<h1 class="modal-dialog-title">{title}</h1>
|
||||||
{{/if}}
|
{/if}
|
||||||
<div class="close-dialog-button-wrapper">
|
<div class="close-dialog-button-wrapper">
|
||||||
<button class="close-dialog-button"
|
<button class="close-dialog-button"
|
||||||
data-a11y-dialog-hide aria-label="Close dialog">
|
data-a11y-dialog-hide aria-label="Close dialog">
|
||||||
|
@ -148,14 +148,14 @@
|
||||||
title: void 0
|
title: void 0
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
backdropClass: (fadedIn, shouldAnimate) => {
|
backdropClass: ({ fadedIn, shouldAnimate }) => {
|
||||||
return classname(
|
return classname(
|
||||||
'modal-dialog-backdrop',
|
'modal-dialog-backdrop',
|
||||||
!fadedIn && 'hidden',
|
!fadedIn && 'hidden',
|
||||||
shouldAnimate && 'should-animate'
|
shouldAnimate && 'should-animate'
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
contentsClass: (fadedIn, muted, shouldAnimate, className) => {
|
contentsClass: ({ fadedIn, muted, shouldAnimate, className }) => {
|
||||||
return classname(
|
return classname(
|
||||||
'modal-dialog-contents',
|
'modal-dialog-contents',
|
||||||
!fadedIn && 'hidden',
|
!fadedIn && 'hidden',
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<ModalDialog
|
<ModalDialog
|
||||||
:id
|
{id}
|
||||||
:label
|
{label}
|
||||||
:title
|
{title}
|
||||||
background="var(--main-bg)"
|
background="var(--main-bg)"
|
||||||
>
|
>
|
||||||
<GenericDialogList :items on:click="onClick(event)" />
|
<GenericDialogList {items} on:click="onClick(event)" />
|
||||||
</ModalDialog>
|
</ModalDialog>
|
||||||
<script>
|
<script>
|
||||||
import ModalDialog from './ModalDialog.html'
|
import ModalDialog from './ModalDialog.html'
|
||||||
|
@ -36,14 +36,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
composeData: ($currentComposeData, realm) => $currentComposeData[realm] || {},
|
composeData: ({ $currentComposeData, realm }) => $currentComposeData[realm] || {},
|
||||||
postPrivacy: (postPrivacyKey) => {
|
postPrivacy: ({ postPrivacyKey }) => {
|
||||||
return POST_PRIVACY_OPTIONS.find(_ => _.key === postPrivacyKey)
|
return POST_PRIVACY_OPTIONS.find(_ => _.key === postPrivacyKey)
|
||||||
},
|
},
|
||||||
postPrivacyKey: (composeData, $currentVerifyCredentials) => {
|
postPrivacyKey: ({ composeData, $currentVerifyCredentials }) => {
|
||||||
return composeData.postPrivacy || $currentVerifyCredentials.source.privacy
|
return composeData.postPrivacy || $currentVerifyCredentials.source.privacy
|
||||||
},
|
},
|
||||||
items: (postPrivacy, postPrivacyOptions) => {
|
items: ({ postPrivacy, postPrivacyOptions }) => {
|
||||||
return postPrivacyOptions.map(option => ({
|
return postPrivacyOptions.map(option => ({
|
||||||
key: option.key,
|
key: option.key,
|
||||||
label: option.label,
|
label: option.label,
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<ModalDialog
|
<ModalDialog
|
||||||
:id
|
{id}
|
||||||
:label
|
{label}
|
||||||
:title
|
{title}
|
||||||
background="var(--main-bg)"
|
background="var(--main-bg)"
|
||||||
>
|
>
|
||||||
<GenericDialogList :items on:click="onClick(event)"/>
|
<GenericDialogList {items} on:click="onClick(event)"/>
|
||||||
</ModalDialog>
|
</ModalDialog>
|
||||||
<script>
|
<script>
|
||||||
import ModalDialog from './ModalDialog.html'
|
import ModalDialog from './ModalDialog.html'
|
||||||
|
@ -22,20 +22,20 @@ import { setStatusPinnedOrUnpinned } from '../../../_actions/pin'
|
||||||
export default {
|
export default {
|
||||||
oncreate,
|
oncreate,
|
||||||
computed: {
|
computed: {
|
||||||
relationship: ($currentAccountRelationship) => $currentAccountRelationship,
|
relationship: ({ $currentAccountRelationship }) => $currentAccountRelationship,
|
||||||
account: ($currentAccountProfile) => $currentAccountProfile,
|
account: ({ $currentAccountProfile }) => $currentAccountProfile,
|
||||||
verifyCredentials: ($currentVerifyCredentials) => $currentVerifyCredentials,
|
verifyCredentials: ({ $currentVerifyCredentials }) => $currentVerifyCredentials,
|
||||||
statusId: (status) => status.id,
|
statusId: ({ status }) => status.id,
|
||||||
pinned: (status) => status.pinned,
|
pinned: ({ status }) => status.pinned,
|
||||||
// begin account data copypasta
|
// begin account data copypasta
|
||||||
verifyCredentialsId: (verifyCredentials) => verifyCredentials.id,
|
verifyCredentialsId: ({ verifyCredentials }) => verifyCredentials.id,
|
||||||
following: (relationship) => relationship && relationship.following,
|
following: ({ relationship }) => relationship && relationship.following,
|
||||||
followRequested: (relationship) => relationship && relationship.requested,
|
followRequested: ({ relationship }) => relationship && relationship.requested,
|
||||||
accountId: (account) => account && account.id,
|
accountId: ({ account }) => account && account.id,
|
||||||
acct: (account) => account.acct,
|
acct: ({ account }) => account.acct,
|
||||||
muting: (relationship) => relationship.muting,
|
muting: ({ relationship }) => relationship.muting,
|
||||||
blocking: (relationship) => relationship.blocking,
|
blocking: ({ relationship }) => relationship.blocking,
|
||||||
followLabel: (following, followRequested, account, acct) => {
|
followLabel: ({ following, followRequested, account, acct }) => {
|
||||||
if (typeof following === 'undefined' || !account) {
|
if (typeof following === 'undefined' || !account) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
@ -43,22 +43,22 @@ export default {
|
||||||
? `Unfollow @${acct}`
|
? `Unfollow @${acct}`
|
||||||
: `Follow @${acct}`
|
: `Follow @${acct}`
|
||||||
},
|
},
|
||||||
followIcon: (following, followRequested) => {
|
followIcon: ({ following, followRequested }) => {
|
||||||
return following ? '#fa-user-times' : followRequested ? '#fa-hourglass' : '#fa-user-plus'
|
return following ? '#fa-user-times' : followRequested ? '#fa-hourglass' : '#fa-user-plus'
|
||||||
},
|
},
|
||||||
blockLabel: (blocking, acct) => {
|
blockLabel: ({ blocking, acct }) => {
|
||||||
return blocking ? `Unblock @${acct}` : `Block @${acct}`
|
return blocking ? `Unblock @${acct}` : `Block @${acct}`
|
||||||
},
|
},
|
||||||
blockIcon: (blocking) => blocking ? '#fa-unlock' : '#fa-ban',
|
blockIcon: ({ blocking }) => blocking ? '#fa-unlock' : '#fa-ban',
|
||||||
muteLabel: (muting, acct) => {
|
muteLabel: ({ muting, acct }) => {
|
||||||
return muting ? `Unmute @${acct}` : `Mute @${acct}`
|
return muting ? `Unmute @${acct}` : `Mute @${acct}`
|
||||||
},
|
},
|
||||||
muteIcon: (muting) => muting ? '#fa-volume-up' : '#fa-volume-off',
|
muteIcon: ({ muting }) => muting ? '#fa-volume-up' : '#fa-volume-off',
|
||||||
// end account data copypasta
|
// end account data copypasta
|
||||||
isUser: (accountId, verifyCredentialsId) => accountId === verifyCredentialsId,
|
isUser: ({ accountId, verifyCredentialsId }) => accountId === verifyCredentialsId,
|
||||||
pinLabel: (pinned, isUser) => isUser ? (pinned ? 'Unpin from profile' : 'Pin to profile') : '',
|
pinLabel: ({ pinned, isUser }) => isUser ? (pinned ? 'Unpin from profile' : 'Pin to profile') : '',
|
||||||
items: (blockLabel, blocking, blockIcon, muteLabel, muteIcon, followLabel, followIcon,
|
items: ({ blockLabel, blocking, blockIcon, muteLabel, muteIcon, followLabel, followIcon,
|
||||||
following, followRequested, pinLabel, isUser) => {
|
following, followRequested, pinLabel, isUser }) => {
|
||||||
return [
|
return [
|
||||||
isUser && {
|
isUser && {
|
||||||
key: 'delete',
|
key: 'delete',
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
<ModalDialog
|
<ModalDialog
|
||||||
:id
|
{id}
|
||||||
:label
|
{label}
|
||||||
background="var(--muted-modal-bg)"
|
background="var(--muted-modal-bg)"
|
||||||
muted="true"
|
muted="true"
|
||||||
className="video-modal-dialog"
|
className="video-modal-dialog"
|
||||||
>
|
>
|
||||||
<video :poster
|
<video {poster}
|
||||||
:src
|
{src}
|
||||||
:width
|
{width}
|
||||||
:height
|
{height}
|
||||||
aria-label="Video: {{description || ''}}"
|
aria-label="Video: {description || ''}"
|
||||||
controls
|
controls
|
||||||
/>
|
/>
|
||||||
</ModalDialog>
|
</ModalDialog>
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<div class="account-profile {{headerImageIsMissing ? 'header-image-is-missing' : ''}}"
|
<div class="account-profile {headerImageIsMissing ? 'header-image-is-missing' : ''}"
|
||||||
style="background-image: url({{headerImage}});">
|
style="background-image: url({headerImage});">
|
||||||
<div class="account-profile-grid-wrapper">
|
<div class="account-profile-grid-wrapper">
|
||||||
<div class="account-profile-grid">
|
<div class="account-profile-grid">
|
||||||
<AccountProfileHeader :account :relationship :verifyCredentials />
|
<AccountProfileHeader {account} {relationship} {verifyCredentials} />
|
||||||
<AccountProfileFollow :account :relationship :verifyCredentials />
|
<AccountProfileFollow {account} {relationship} {verifyCredentials} />
|
||||||
<AccountProfileNote :account />
|
<AccountProfileNote {account} />
|
||||||
<AccountProfileDetails :account :relationship :verifyCredentials />
|
<AccountProfileDetails {account} {relationship} {verifyCredentials} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -73,8 +73,8 @@
|
||||||
export default {
|
export default {
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
headerImageIsMissing: (account) => account.header.endsWith('missing.png'),
|
headerImageIsMissing: ({ account }) => account.header.endsWith('missing.png'),
|
||||||
headerImage: ($autoplayGifs, account) => $autoplayGifs ? account.header : account.header_static
|
headerImage: ({ $autoplayGifs, account }) => $autoplayGifs ? account.header : account.header_static
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
AccountProfileHeader,
|
AccountProfileHeader,
|
||||||
|
|
|
@ -4,33 +4,33 @@
|
||||||
Toots
|
Toots
|
||||||
</span>
|
</span>
|
||||||
<span class="account-profile-details-item-datum">
|
<span class="account-profile-details-item-datum">
|
||||||
{{numStatusesDisplay}}
|
{numStatusesDisplay}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<a class="account-profile-details-item"
|
<a class="account-profile-details-item"
|
||||||
href='/accounts/{{account.id}}/follows'
|
href='/accounts/{account.id}/follows'
|
||||||
aria-label={{followingLabel}}
|
aria-label={followingLabel}
|
||||||
>
|
>
|
||||||
<span class="account-profile-details-item-title">
|
<span class="account-profile-details-item-title">
|
||||||
Follows
|
Follows
|
||||||
</span>
|
</span>
|
||||||
<span class="account-profile-details-item-datum">
|
<span class="account-profile-details-item-datum">
|
||||||
{{numFollowingDisplay}}
|
{numFollowingDisplay}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<a class="account-profile-details-item"
|
<a class="account-profile-details-item"
|
||||||
href='/accounts/{{account.id}}/followers'
|
href='/accounts/{account.id}/followers'
|
||||||
aria-label={{followersLabel}}
|
aria-label={followersLabel}
|
||||||
>
|
>
|
||||||
<span class="account-profile-details-item-title">
|
<span class="account-profile-details-item-title">
|
||||||
Followers
|
Followers
|
||||||
</span>
|
</span>
|
||||||
<span class="account-profile-details-item-datum">
|
<span class="account-profile-details-item-datum">
|
||||||
{{numFollowersDisplay}}
|
{numFollowersDisplay}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<!-- TODO: re-enable this when we support profile editing -->
|
<!-- TODO: re-enable this when we support profile editing -->
|
||||||
{{#if account && verifyCredentials && account.id !== verifyCredentials.id}}
|
{#if account && verifyCredentials && account.id !== verifyCredentials.id}
|
||||||
<div class="account-profile-more-options">
|
<div class="account-profile-more-options">
|
||||||
<IconButton
|
<IconButton
|
||||||
label="More options"
|
label="More options"
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
on:click="onMoreOptionsClick()"
|
on:click="onMoreOptionsClick()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.account-profile-details {
|
.account-profile-details {
|
||||||
|
@ -119,14 +119,14 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
numStatuses: account => account.statuses_count || 0,
|
numStatuses: ({ account }) => account.statuses_count || 0,
|
||||||
numFollowing: account => account.following_count || 0,
|
numFollowing: ({ account }) => account.following_count || 0,
|
||||||
numFollowers: account => account.followers_count || 0,
|
numFollowers: ({ account }) => account.followers_count || 0,
|
||||||
numStatusesDisplay: numStatuses => numberFormat.format(numStatuses),
|
numStatusesDisplay: ({ numStatuses }) => numberFormat.format(numStatuses),
|
||||||
numFollowingDisplay: numFollowing => numberFormat.format(numFollowing),
|
numFollowingDisplay: ({ numFollowing }) => numberFormat.format(numFollowing),
|
||||||
numFollowersDisplay: numFollowers => numberFormat.format(numFollowers),
|
numFollowersDisplay: ({ numFollowers }) => numberFormat.format(numFollowers),
|
||||||
followersLabel: numFollowers => `Followed by ${numFollowers}`,
|
followersLabel: ({ numFollowers }) => `Followed by ${numFollowers}`,
|
||||||
followingLabel: numFollowing => `Follows ${numFollowing}`
|
followingLabel: ({ numFollowing }) => `Follows ${numFollowing}`
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async onMoreOptionsClick () {
|
async onMoreOptionsClick () {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<div class="account-profile-follow {{shown ? 'shown' : ''}}">
|
<div class="account-profile-follow {shown ? 'shown' : ''}">
|
||||||
<IconButton
|
<IconButton
|
||||||
label={{followLabel}}
|
label={followLabel}
|
||||||
href={{followIcon}}
|
href={followIcon}
|
||||||
pressable="true"
|
pressable="true"
|
||||||
pressed={{following}}
|
pressed={following}
|
||||||
big="true"
|
big="true"
|
||||||
on:click="onFollowButtonClick(event)"
|
on:click="onFollowButtonClick(event)"
|
||||||
ref:icon
|
ref:icon
|
||||||
|
@ -57,18 +57,18 @@
|
||||||
overrideFollowing: void 0
|
overrideFollowing: void 0
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
accountId: (account) => account.id,
|
accountId: ({ account }) => account.id,
|
||||||
following: (relationship, overrideFollowing) => {
|
following: ({ relationship, overrideFollowing }) => {
|
||||||
if (typeof overrideFollowing === 'boolean') {
|
if (typeof overrideFollowing === 'boolean') {
|
||||||
return overrideFollowing
|
return overrideFollowing
|
||||||
}
|
}
|
||||||
return relationship && relationship.following
|
return relationship && relationship.following
|
||||||
},
|
},
|
||||||
blocking: (relationship) => relationship && relationship.blocking,
|
blocking: ({ relationship }) => relationship && relationship.blocking,
|
||||||
followRequested: (relationship, account) => {
|
followRequested: ({ relationship, account }) => {
|
||||||
return relationship && relationship.requested && account && account.locked
|
return relationship && relationship.requested && account && account.locked
|
||||||
},
|
},
|
||||||
followLabel: (blocking, following, followRequested) => {
|
followLabel: ({ blocking, following, followRequested }) => {
|
||||||
if (blocking) {
|
if (blocking) {
|
||||||
return 'Unblock'
|
return 'Unblock'
|
||||||
} else if (following) {
|
} else if (following) {
|
||||||
|
@ -79,7 +79,7 @@
|
||||||
return 'Follow'
|
return 'Follow'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
followIcon: (blocking, following, followRequested) => {
|
followIcon: ({ blocking, following, followRequested }) => {
|
||||||
if (blocking) {
|
if (blocking) {
|
||||||
return '#fa-unlock'
|
return '#fa-unlock'
|
||||||
} else if (following) {
|
} else if (following) {
|
||||||
|
@ -90,7 +90,7 @@
|
||||||
return '#fa-user-plus'
|
return '#fa-user-plus'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
shown: (verifyCredentials, relationship) => {
|
shown: ({ verifyCredentials, relationship }) => {
|
||||||
return verifyCredentials && relationship && verifyCredentials.id !== relationship.id
|
return verifyCredentials && relationship && verifyCredentials.id !== relationship.id
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
<div class="account-profile-avatar">
|
<div class="account-profile-avatar">
|
||||||
<Avatar :account size="big" />
|
<Avatar {account} size="big" />
|
||||||
</div>
|
</div>
|
||||||
<div class="account-profile-name">
|
<div class="account-profile-name">
|
||||||
<ExternalLink href={{account.url}}
|
<ExternalLink href={account.url}
|
||||||
showIcon="true"
|
showIcon="true"
|
||||||
normalIconColor="true"
|
normalIconColor="true"
|
||||||
ariaLabel="{{account.display_name || account.acct}} (opens in new window)"
|
ariaLabel="{account.display_name || account.acct} (opens in new window)"
|
||||||
>
|
>
|
||||||
{{account.display_name || account.acct}}
|
{account.display_name || account.acct}
|
||||||
</ExternalLink>
|
</ExternalLink>
|
||||||
</div>
|
</div>
|
||||||
<div class="account-profile-username">
|
<div class="account-profile-username">
|
||||||
{{'@' + account.acct}}
|
{'@' + account.acct}
|
||||||
</div>
|
</div>
|
||||||
<div class="account-profile-followed-by">
|
<div class="account-profile-followed-by">
|
||||||
{{#if relationship && relationship.blocking}}
|
{#if relationship && relationship.blocking}
|
||||||
<span class="account-profile-followed-by-span">Blocked</span>
|
<span class="account-profile-followed-by-span">Blocked</span>
|
||||||
{{elseif relationship && relationship.followed_by}}
|
{:elseif relationship && relationship.followed_by}
|
||||||
<span class="account-profile-followed-by-span">Follows you</span>
|
<span class="account-profile-followed-by-span">Follows you</span>
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.account-profile-followed-by {
|
.account-profile-followed-by {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="account-profile-note">
|
<div class="account-profile-note">
|
||||||
{{{massagedNote}}}
|
{@html massagedNote}
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.account-profile-note {
|
.account-profile-note {
|
||||||
|
@ -32,8 +32,8 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
note: (account) => account.note,
|
note: ({ account }) => account.note,
|
||||||
massagedNote: (note) => {
|
massagedNote: ({ note }) => {
|
||||||
// GNU Social / Pleroma don't add <p> tags
|
// GNU Social / Pleroma don't add <p> tags
|
||||||
if (!note.startsWith('<p>')) {
|
if (!note.startsWith('<p>')) {
|
||||||
note = `<p>${note}</p>`
|
note = `<p>${note}</p>`
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
<div class="pseudo-virtual-list" on:initialized ref:node>
|
<div class="pseudo-virtual-list" on:initialized ref:node>
|
||||||
{{#each wrappedItems as wrappedItem, i @item}}
|
{#each wrappedItems as wrappedItem, i (wrappedItem.item)}
|
||||||
<PseudoVirtualListLazyItem
|
<PseudoVirtualListLazyItem
|
||||||
:component
|
{component}
|
||||||
index={{i}}
|
index={i}
|
||||||
length={{wrappedItems.length}}
|
length={wrappedItems.length}
|
||||||
:makeProps
|
{makeProps}
|
||||||
key={{wrappedItem.item}}
|
key={wrappedItem.item}
|
||||||
:intersectionObserver
|
{intersectionObserver}
|
||||||
isIntersecting={{isIntersecting(wrappedItem.item, $intersectionStates)}}
|
isIntersecting={isIntersecting(wrappedItem.item, $intersectionStates)}
|
||||||
isCached={{isCached(wrappedItem.item, $intersectionStates)}}
|
isCached={isCached(wrappedItem.item, $intersectionStates)}
|
||||||
height={{getHeight(wrappedItem.item, $intersectionStates)}}
|
height={getHeight(wrappedItem.item, $intersectionStates)}
|
||||||
/>
|
/>
|
||||||
{{/each}}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.pseudo-virtual-list {
|
.pseudo-virtual-list {
|
||||||
|
@ -110,8 +110,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
wrappedItems: (items) => items ? items.map(item => ({item})) : [],
|
wrappedItems: ({ items }) => items ? items.map(item => ({item})) : [],
|
||||||
allItemsHaveHeight: (items, $intersectionStates) => {
|
allItemsHaveHeight: ({ items, $intersectionStates }) => {
|
||||||
if (!items) {
|
if (!items) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
<div class="pseudo-virtual-list-item"
|
<div class="pseudo-virtual-list-item"
|
||||||
aria-hidden={{hide}}
|
aria-hidden={hide}
|
||||||
pseudo-virtual-list-key={{key}}
|
pseudo-virtual-list-key={key}
|
||||||
style="height: {{shouldHide ? `${height}px` : ''}};"
|
style="height: {shouldHide ? `${height}px` : ''};"
|
||||||
ref:node>
|
ref:node>
|
||||||
{{#if !shouldHide}}
|
{#if !shouldHide}
|
||||||
<:Component {component}
|
<svelte:component this={component}
|
||||||
virtualProps={{props}}
|
virtualProps={props}
|
||||||
virtualIndex={{index}}
|
virtualIndex={index}
|
||||||
virtualLength={{length}}
|
virtualLength={length}
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
import { scheduleIdleTask } from '../../_utils/scheduleIdleTask'
|
import { scheduleIdleTask } from '../../_utils/scheduleIdleTask'
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
hide: false
|
hide: false
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
shouldHide: (isIntersecting, isCached, hide) => {
|
shouldHide: ({ isIntersecting, isCached, hide }) => {
|
||||||
if (isCached) {
|
if (isCached) {
|
||||||
return true // if it's cached, always unrender immediately until proven it's intersecting
|
return true // if it's cached, always unrender immediately until proven it's intersecting
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
{{#if props}}
|
{#if props}
|
||||||
<PseudoVirtualListItem :component
|
<PseudoVirtualListItem {component}
|
||||||
:props
|
{props}
|
||||||
:key
|
{key}
|
||||||
:index
|
{index}
|
||||||
:length
|
{length}
|
||||||
:intersectionObserver
|
{intersectionObserver}
|
||||||
:isIntersecting
|
{isIntersecting}
|
||||||
:isCached
|
{isCached}
|
||||||
:height
|
{height}
|
||||||
on:scrollToPosition
|
on:scrollToPosition
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{/if}
|
||||||
<script>
|
<script>
|
||||||
import PseudoVirtualListItem from './PseudoVirtualListItem.html'
|
import PseudoVirtualListItem from './PseudoVirtualListItem.html'
|
||||||
import { mark, stop } from '../../_utils/marks'
|
import { mark, stop } from '../../_utils/marks'
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
<SearchResult href="/accounts/{{account.id}}">
|
<SearchResult href="/accounts/{account.id}">
|
||||||
<div class="search-result-account">
|
<div class="search-result-account">
|
||||||
<Avatar :account size="small" className="search-result-account-avatar"/>
|
<Avatar {account} size="small" className="search-result-account-avatar"/>
|
||||||
<div class="search-result-account-name">
|
<div class="search-result-account-name">
|
||||||
{{account.display_name || account.acct}}
|
{account.display_name || account.acct}
|
||||||
</div>
|
</div>
|
||||||
<div class="search-result-account-username">
|
<div class="search-result-account-username">
|
||||||
{{'@' + account.acct}}
|
{'@' + account.acct}
|
||||||
</div>
|
</div>
|
||||||
{{#if actions && actions.length}}
|
{#if actions && actions.length}
|
||||||
<div class="search-result-account-buttons">
|
<div class="search-result-account-buttons">
|
||||||
{{#each actions as action}}
|
{#each actions as action}
|
||||||
<IconButton
|
<IconButton
|
||||||
label={{action.label}}
|
label={action.label}
|
||||||
on:click="onButtonClick(event, action, account.id)"
|
on:click="onButtonClick(event, action, account.id)"
|
||||||
href={{action.icon}}
|
href={action.icon}
|
||||||
big="true"
|
big="true"
|
||||||
/>
|
/>
|
||||||
{{/each}}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</SearchResult>
|
</SearchResult>
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<SearchResult href="/tags/{{hashtag}}">
|
<SearchResult href="/tags/{hashtag}">
|
||||||
{{'#' + hashtag}}
|
{'#' + hashtag}
|
||||||
</SearchResult>
|
</SearchResult>
|
||||||
<style>
|
<style>
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -7,21 +7,21 @@
|
||||||
required
|
required
|
||||||
bind:value="$queryInSearch">
|
bind:value="$queryInSearch">
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="primary search-button" aria-label="Search" disabled={{$searchLoading}}>
|
<button type="submit" class="primary search-button" aria-label="Search" disabled={$searchLoading}>
|
||||||
<svg class="search-button-svg">
|
<svg class="search-button-svg">
|
||||||
<use xlink:href="#fa-search" />
|
<use xlink:href="#fa-search" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
{{#if $searchLoading}}
|
{#if $searchLoading}
|
||||||
<div class="search-results-container">
|
<div class="search-results-container">
|
||||||
<LoadingPage />
|
<LoadingPage />
|
||||||
</div>
|
</div>
|
||||||
{{elseif $searchResults && $searchResultsForQuery === $queryInSearch}}
|
{:elseif $searchResults && $searchResultsForQuery === $queryInSearch}
|
||||||
<div class="search-results-container">
|
<div class="search-results-container">
|
||||||
<SearchResults />
|
<SearchResults />
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{/if}
|
||||||
<style>
|
<style>
|
||||||
.search-input-form {
|
.search-input-form {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<li class="search-result">
|
<li class="search-result">
|
||||||
<a :href class="search-result-anchor">
|
<a {href} class="search-result-anchor">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<ul class="search-results">
|
<ul class="search-results">
|
||||||
{{#each $searchResults.hashtags as hashtag}}
|
{#each $searchResults.hashtags as hashtag}
|
||||||
<HashtagSearchResult :hashtag />
|
<HashtagSearchResult {hashtag} />
|
||||||
{{/each}}
|
{/each}
|
||||||
{{#each $searchResults.accounts as account}}
|
{#each $searchResults.accounts as account}
|
||||||
<AccountSearchResult :account />
|
<AccountSearchResult {account} />
|
||||||
{{/each}}
|
{/each}
|
||||||
{{#each $searchResults.statuses as status, index}}
|
{#each $searchResults.statuses as status, index}
|
||||||
<StatusSearchResult :status :index length={{$searchResults.statuses.length}}/>
|
<StatusSearchResult {status} {index} length={$searchResults.statuses.length}/>
|
||||||
{{/each}}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
<style>
|
<style>
|
||||||
.search-results {
|
.search-results {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<SearchResult href="/statuses/{{status.id}}">
|
<SearchResult href="/statuses/{status.id}">
|
||||||
<Status :index :length
|
<Status {index} {length}
|
||||||
timelineType="search" timelineValue="search"
|
timelineType="search" timelineValue="search"
|
||||||
:status />
|
{status} />
|
||||||
</SearchResult>
|
</SearchResult>
|
||||||
<style>
|
<style>
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<SettingsNav :page :label/>
|
<SettingsNav {page} {label}/>
|
||||||
|
|
||||||
<div class="settings">
|
<div class="settings">
|
||||||
<FreeTextLayout>
|
<FreeTextLayout>
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<div class="settings-list-wrapper">
|
<div class="settings-list-wrapper">
|
||||||
{{#if label}}
|
{#if label}
|
||||||
<ul class="settings-list" aria-label={{label}}>
|
<ul class="settings-list" aria-label={label}>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</ul>
|
</ul>
|
||||||
{{else}}
|
{:else}
|
||||||
<ul class="settings-list">
|
<ul class="settings-list">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</ul>
|
</ul>
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.settings-list-wrapper {
|
.settings-list-wrapper {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<li class="settings-list-item">
|
<li class="settings-list-item">
|
||||||
<a :href>
|
<a {href}>
|
||||||
{{#if icon}}
|
{#if icon}
|
||||||
<svg class="settings-list-item-svg">
|
<svg class="settings-list-item-svg">
|
||||||
<use xlink:href={{icon}} />
|
<use xlink:href={icon} />
|
||||||
</svg>
|
</svg>
|
||||||
{{/if}}
|
{/if}
|
||||||
<span aria-label={{ariaLabel || label}} class={{offsetForIcon ? 'offset-for-icon' : ''}}>
|
<span aria-label={ariaLabel || label} class={offsetForIcon ? 'offset-for-icon' : ''}>
|
||||||
{{label}}
|
{label}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<nav class="settings-nav">
|
<nav class="settings-nav">
|
||||||
<ul>
|
<ul>
|
||||||
{{#each navItems as navItem}}
|
{#each navItems as navItem}
|
||||||
<li>
|
<li>
|
||||||
<SettingsNavItem :page name={{navItem.name}} href={{navItem.href}} label={{navItem.label}} />
|
<SettingsNavItem {page} name={navItem.name} href={navItem.href} label={navItem.label} />
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{/each}
|
||||||
<li>
|
<li>
|
||||||
<SettingsNavItem :page name={{page}} href="/{{page}}" :label />
|
<SettingsNavItem {page} name={page} href="/{page}" {label} />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
SettingsNavItem
|
SettingsNavItem
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
navItems: page => {
|
navItems: ({ page }) => {
|
||||||
let res = []
|
let res = []
|
||||||
let breadcrumbs = page.split('/')
|
let breadcrumbs = page.split('/')
|
||||||
let path = ''
|
let path = ''
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<a class="settings-nav-item {{className}}"
|
<a class="settings-nav-item {className}"
|
||||||
aria-label={{ariaLabel}}
|
aria-label={ariaLabel}
|
||||||
:href >
|
{href} >
|
||||||
{{label}}
|
{label}
|
||||||
</a>
|
</a>
|
||||||
<style>
|
<style>
|
||||||
a.settings-nav-item {
|
a.settings-nav-item {
|
||||||
|
@ -15,8 +15,8 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
className: (page, name) => page === name ? 'selected' : '',
|
className: ({ page, name }) => page === name ? 'selected' : '',
|
||||||
ariaLabel: (page, name, label) => page === name ? `${label} (current page)` : label
|
ariaLabel: ({ page, name, label }) => page === name ? `${label} (current page)` : label
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,64 +1,64 @@
|
||||||
{{#if type === 'video'}}
|
{#if type === 'video'}
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="play-video-button"
|
class="play-video-button"
|
||||||
aria-label="Play video: {{description}}"
|
aria-label="Play video: {description}"
|
||||||
delegate-key={{delegateKey}}
|
delegate-key={delegateKey}
|
||||||
style="width: {{inlineWidth}}px; height: {{inlineHeight}}px;">
|
style="width: {inlineWidth}px; height: {inlineHeight}px;">
|
||||||
<PlayVideoIcon />
|
<PlayVideoIcon />
|
||||||
<LazyImage
|
<LazyImage
|
||||||
alt={{description}}
|
alt={description}
|
||||||
title={{description}}
|
title={description}
|
||||||
src={{previewUrl}}
|
src={previewUrl}
|
||||||
fallback={{oneTransparentPixel}}
|
fallback={oneTransparentPixel}
|
||||||
width={{inlineWidth}}
|
width={inlineWidth}
|
||||||
height={{inlineHeight}}
|
height={inlineHeight}
|
||||||
background="var(--loading-bg)"
|
background="var(--loading-bg)"
|
||||||
className={{noNativeWidthHeight ? 'no-native-width-height' : ''}}
|
className={noNativeWidthHeight ? 'no-native-width-height' : ''}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
{{else}}
|
{:else}
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="show-image-button"
|
class="show-image-button"
|
||||||
aria-label="Show image: {{description}}"
|
aria-label="Show image: {description}"
|
||||||
title={{description}}
|
title={description}
|
||||||
delegate-key={{delegateKey}}
|
delegate-key={delegateKey}
|
||||||
on:mouseover="set({mouseover: event})"
|
on:mouseover="set({mouseover: event})"
|
||||||
style="width: {{inlineWidth}}px; height: {{inlineHeight}}px;"
|
style="width: {inlineWidth}px; height: {inlineHeight}px;"
|
||||||
>
|
>
|
||||||
{{#if type === 'gifv' && $autoplayGifs}}
|
{#if type === 'gifv' && $autoplayGifs}
|
||||||
<AutoplayVideo
|
<AutoplayVideo
|
||||||
className={{noNativeWidthHeight ? 'no-native-width-height' : ''}}
|
className={noNativeWidthHeight ? 'no-native-width-height' : ''}
|
||||||
ariaLabel="Animated GIF: {{description}}"
|
ariaLabel="Animated GIF: {description}"
|
||||||
poster={{previewUrl}}
|
poster={previewUrl}
|
||||||
src={{url}}
|
src={url}
|
||||||
width={{inlineWidth}}
|
width={inlineWidth}
|
||||||
height={{inlineHeight}}
|
height={inlineHeight}
|
||||||
/>
|
/>
|
||||||
{{elseif type === 'gifv' && !$autoplayGifs}}
|
{:elseif type === 'gifv' && !$autoplayGifs}
|
||||||
<NonAutoplayGifv
|
<NonAutoplayGifv
|
||||||
class={{noNativeWidthHeight ? 'no-native-width-height' : ''}}
|
class={noNativeWidthHeight ? 'no-native-width-height' : ''}
|
||||||
label="Animated GIF: {{description}}"
|
label="Animated GIF: {description}"
|
||||||
poster={{previewUrl}}
|
poster={previewUrl}
|
||||||
src={{url}}
|
src={url}
|
||||||
staticSrc={{previewUrl}}
|
staticSrc={previewUrl}
|
||||||
width={{inlineWidth}}
|
width={inlineWidth}
|
||||||
height={{inlineHeight}}
|
height={inlineHeight}
|
||||||
playing={{mouseover}}
|
playing={mouseover}
|
||||||
/>
|
/>
|
||||||
{{else}}
|
{:else}
|
||||||
<LazyImage
|
<LazyImage
|
||||||
alt={{description}}
|
alt={description}
|
||||||
title={{description}}
|
title={description}
|
||||||
src={{previewUrl}}
|
src={previewUrl}
|
||||||
fallback={{oneTransparentPixel}}
|
fallback={oneTransparentPixel}
|
||||||
width={{inlineWidth}}
|
width={inlineWidth}
|
||||||
height={{inlineHeight}}
|
height={inlineHeight}
|
||||||
background="var(--loading-bg)"
|
background="var(--loading-bg)"
|
||||||
className={{noNativeWidthHeight ? 'no-native-width-height' : ''}}
|
className={noNativeWidthHeight ? 'no-native-width-height' : ''}
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
{{/if}}
|
{/if}
|
||||||
<style>
|
<style>
|
||||||
:global(.status-media video, .status-media img) {
|
:global(.status-media video, .status-media img) {
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
|
@ -121,24 +121,24 @@
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// width/height to show inline
|
// width/height to show inline
|
||||||
inlineWidth: smallWidth => smallWidth || DEFAULT_MEDIA_WIDTH,
|
inlineWidth: ({ smallWidth }) => smallWidth || DEFAULT_MEDIA_WIDTH,
|
||||||
inlineHeight: smallHeight => smallHeight || DEFAULT_MEDIA_HEIGHT,
|
inlineHeight: ({ smallHeight }) => smallHeight || DEFAULT_MEDIA_HEIGHT,
|
||||||
// width/height to show in a modal
|
// width/height to show in a modal
|
||||||
modalWidth: (originalWidth, inlineWidth) => originalWidth || inlineWidth,
|
modalWidth: ({ originalWidth, inlineWidth }) => originalWidth || inlineWidth,
|
||||||
modalHeight: (originalHeight, inlineHeight) => originalHeight || inlineHeight,
|
modalHeight: ({ originalHeight, inlineHeight }) => originalHeight || inlineHeight,
|
||||||
meta: media => media.meta,
|
meta: ({ media }) => media.meta,
|
||||||
small: meta => meta && meta.small,
|
small: ({ meta }) => meta && meta.small,
|
||||||
original: meta => meta && meta.original,
|
original: ({ meta }) => meta && meta.original,
|
||||||
smallWidth: small => small && small.width,
|
smallWidth: ({ small }) => small && small.width,
|
||||||
smallHeight: small => small && small.height,
|
smallHeight: ({ small }) => small && small.height,
|
||||||
originalWidth: original => original && original.width,
|
originalWidth: ({ original }) => original && original.width,
|
||||||
originalHeight: original => original && original.height,
|
originalHeight: ({ original }) => original && original.height,
|
||||||
noNativeWidthHeight: (smallWidth, smallHeight) => typeof smallWidth !== 'number' || typeof smallHeight !== 'number',
|
noNativeWidthHeight: ({ smallWidth, smallHeight }) => typeof smallWidth !== 'number' || typeof smallHeight !== 'number',
|
||||||
delegateKey: (media, uuid) => `media-${uuid}-${media.id}`,
|
delegateKey: ({ media, uuid }) => `media-${uuid}-${media.id}`,
|
||||||
description: (media) => media.description || '',
|
description: ({ media }) => media.description || '',
|
||||||
previewUrl: (media) => media.preview_url,
|
previewUrl: ({ media }) => media.preview_url,
|
||||||
url: (media) => media.url,
|
url: ({ media }) => media.url,
|
||||||
type: (media) => media.type
|
type: ({ media }) => media.type
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async onClickPlayVideoButton () {
|
async onClickPlayVideoButton () {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<div class="status-media {{sensitive ? 'status-media-is-sensitive' : ''}}"
|
<div class="status-media {sensitive ? 'status-media-is-sensitive' : ''}"
|
||||||
style="grid-template-columns: repeat(auto-fit, minmax({{maxMediaWidth}}px, 1fr));" >
|
style="grid-template-columns: repeat(auto-fit, minmax({maxMediaWidth}px, 1fr));" >
|
||||||
{{#each mediaAttachments as media}}
|
{#each mediaAttachments as media}
|
||||||
<Media :media :uuid />
|
<Media {media} {uuid} />
|
||||||
{{/each}}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.status-media {
|
.status-media {
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
maxMediaWidth: (mediaAttachments) => {
|
maxMediaWidth: ({ mediaAttachments }) => {
|
||||||
return Math.max.apply(Math, mediaAttachments.map(media => {
|
return Math.max.apply(Math, mediaAttachments.map(media => {
|
||||||
return media.meta && media.meta.small && typeof media.meta.small.width === 'number' ? media.meta.small.width : DEFAULT_MEDIA_WIDTH
|
return media.meta && media.meta.small && typeof media.meta.small.width === 'number' ? media.meta.small.width : DEFAULT_MEDIA_WIDTH
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
{{#if status}}
|
{#if status}
|
||||||
<Status :index :length :timelineType :timelineValue :focusSelector
|
<Status {index} {length} {timelineType} {timelineValue} {focusSelector}
|
||||||
:status :notification on:recalculateHeight
|
{status} {notification} on:recalculateHeight
|
||||||
/>
|
/>
|
||||||
{{else}}
|
{:else}
|
||||||
<article class="notification-article"
|
<article class="notification-article"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
aria-posinset={{index}}
|
aria-posinset={index}
|
||||||
aria-setsize={{length}} >
|
aria-setsize={length} >
|
||||||
<StatusHeader :notification :notificationId :status :statusId :timelineType
|
<StatusHeader {notification} {notificationId} {status} {statusId} {timelineType}
|
||||||
:account :accountId :uuid isStatusInNotification="true" />
|
{account} {accountId} {uuid} isStatusInNotification="true" />
|
||||||
</article>
|
</article>
|
||||||
{{/if}}
|
{/if}
|
||||||
<style>
|
<style>
|
||||||
.notification-article {
|
.notification-article {
|
||||||
width: 560px;
|
width: 560px;
|
||||||
|
@ -38,12 +38,12 @@
|
||||||
},
|
},
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
account: (notification) => notification.account,
|
account: ({ notification }) => notification.account,
|
||||||
accountId: (account) => account.id,
|
accountId: ({ account }) => account.id,
|
||||||
notificationId: (notification) => notification.id,
|
notificationId: ({ notification }) => notification.id,
|
||||||
status: (notification) => notification.status,
|
status: ({ notification }) => notification.status,
|
||||||
statusId: (status) => status && status.id,
|
statusId: ({ status }) => status && status.id,
|
||||||
uuid: ($currentInstance, timelineType, timelineValue, notificationId, statusId) => {
|
uuid: ({ $currentInstance, timelineType, timelineValue, notificationId, statusId }) => {
|
||||||
return `${$currentInstance}/${timelineType}/${timelineValue}/${notificationId}/${statusId || ''}`
|
return `${$currentInstance}/${timelineType}/${timelineValue}/${notificationId}/${statusId || ''}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
<article class={{className}}
|
<article class={className}
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
delegate-key={{delegateKey}}
|
delegate-key={delegateKey}
|
||||||
focus-key={{delegateKey}}
|
focus-key={delegateKey}
|
||||||
aria-posinset={{index}}
|
aria-posinset={index}
|
||||||
aria-setsize={{length}}
|
aria-setsize={length}
|
||||||
aria-label={{ariaLabel}}
|
aria-label={ariaLabel}
|
||||||
on:recalculateHeight>
|
on:recalculateHeight>
|
||||||
{{#if showHeader}}
|
{#if showHeader}
|
||||||
<StatusHeader {{...params}} />
|
<StatusHeader {...params} />
|
||||||
{{/if}}
|
{/if}
|
||||||
<StatusAuthorName {{...params}} />
|
<StatusAuthorName {...params} />
|
||||||
<StatusAuthorHandle {{...params}} />
|
<StatusAuthorHandle {...params} />
|
||||||
{{#if !isStatusInOwnThread}}
|
{#if !isStatusInOwnThread}
|
||||||
<StatusRelativeDate {{...params}} />
|
<StatusRelativeDate {...params} />
|
||||||
{{/if}}
|
{/if}
|
||||||
<StatusSidebar {{...params}} />
|
<StatusSidebar {...params} />
|
||||||
{{#if spoilerText}}
|
{#if spoilerText}
|
||||||
<StatusSpoiler {{...params}} on:recalculateHeight />
|
<StatusSpoiler {...params} on:recalculateHeight />
|
||||||
{{/if}}
|
{/if}
|
||||||
{{#if showContent || contentPreloaded}}
|
{#if showContent || contentPreloaded}
|
||||||
<StatusContent {{...params}} shown={{showContent}}/>
|
<StatusContent {...params} shown={showContent}/>
|
||||||
{{/if}}
|
{/if}
|
||||||
{{#if showMedia }}
|
{#if showMedia }
|
||||||
<StatusMediaAttachments {{...params}} on:recalculateHeight />
|
<StatusMediaAttachments {...params} on:recalculateHeight />
|
||||||
{{/if}}
|
{/if}
|
||||||
{{#if isStatusInOwnThread}}
|
{#if isStatusInOwnThread}
|
||||||
<StatusDetails {{...params}} />
|
<StatusDetails {...params} />
|
||||||
{{/if}}
|
{/if}
|
||||||
<StatusToolbar {{...params}} on:recalculateHeight />
|
<StatusToolbar {...params} on:recalculateHeight />
|
||||||
{{#if replyShown}}
|
{#if replyShown}
|
||||||
<StatusComposeBox {{...params}} on:recalculateHeight />
|
<StatusComposeBox {...params} on:recalculateHeight />
|
||||||
{{/if}}
|
{/if}
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -170,56 +170,56 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
originalStatus: (status) => status.reblog ? status.reblog : status,
|
originalStatus: ({ status }) => status.reblog ? status.reblog : status,
|
||||||
originalStatusId: (originalStatus) => originalStatus.id,
|
originalStatusId: ({ originalStatus }) => originalStatus.id,
|
||||||
statusId: (status) => status.id,
|
statusId: ({ status }) => status.id,
|
||||||
notificationId: (notification) => notification && notification.id,
|
notificationId: ({ notification }) => notification && notification.id,
|
||||||
account: (notification, status) => (
|
account: ({ notification, status }) => (
|
||||||
(notification && notification.account) || status.account
|
(notification && notification.account) || status.account
|
||||||
),
|
),
|
||||||
accountId: (account) => account.id,
|
accountId: ({ account }) => account.id,
|
||||||
originalAccount: (originalStatus) => originalStatus.account,
|
originalAccount: ({ originalStatus }) => originalStatus.account,
|
||||||
originalAccountId: (originalAccount) => originalAccount.id,
|
originalAccountId: ({ originalAccount }) => originalAccount.id,
|
||||||
visibility: (originalStatus) => originalStatus.visibility,
|
visibility: ({ originalStatus }) => originalStatus.visibility,
|
||||||
spoilerText: (originalStatus) => originalStatus.spoiler_text,
|
spoilerText: ({ originalStatus }) => originalStatus.spoiler_text,
|
||||||
uuid: ($currentInstance, timelineType, timelineValue, notificationId, statusId) => (
|
uuid: ({ $currentInstance, timelineType, timelineValue, notificationId, statusId }) => (
|
||||||
`${$currentInstance}/${timelineType}/${timelineValue}/${notificationId || ''}/${statusId}`
|
`${$currentInstance}/${timelineType}/${timelineValue}/${notificationId || ''}/${statusId}`
|
||||||
),
|
),
|
||||||
delegateKey: (uuid) => `status-${uuid}`,
|
delegateKey: ({ uuid }) => `status-${uuid}`,
|
||||||
isStatusInOwnThread: (timelineType, timelineValue, originalStatusId) => (
|
isStatusInOwnThread: ({ timelineType, timelineValue, originalStatusId }) => (
|
||||||
(timelineType === 'status' || timelineType === 'reply') && timelineValue === originalStatusId
|
(timelineType === 'status' || timelineType === 'reply') && timelineValue === originalStatusId
|
||||||
),
|
),
|
||||||
isStatusInNotification: (originalStatusId, notification) => (
|
isStatusInNotification: ({ originalStatusId, notification }) => (
|
||||||
notification && notification.status &&
|
notification && notification.status &&
|
||||||
notification.type !== 'mention' && notification.status.id === originalStatusId
|
notification.type !== 'mention' && notification.status.id === originalStatusId
|
||||||
),
|
),
|
||||||
spoilerShown: ($spoilersShown, uuid) => !!$spoilersShown[uuid],
|
spoilerShown: ({ $spoilersShown, uuid }) => !!$spoilersShown[uuid],
|
||||||
replyShown: ($repliesShown, uuid) => !!$repliesShown[uuid],
|
replyShown: ({ $repliesShown, uuid }) => !!$repliesShown[uuid],
|
||||||
showMedia: (originalStatus, isStatusInNotification) => (
|
showMedia: ({ originalStatus, isStatusInNotification }) => (
|
||||||
!isStatusInNotification &&
|
!isStatusInNotification &&
|
||||||
originalStatus.media_attachments &&
|
originalStatus.media_attachments &&
|
||||||
originalStatus.media_attachments.length
|
originalStatus.media_attachments.length
|
||||||
),
|
),
|
||||||
ariaLabel: (originalAccount, originalStatus, visibility) => (
|
ariaLabel: ({ originalAccount, originalStatus, visibility }) => (
|
||||||
(visibility === 'direct' ? 'Direct message' : 'Status') +
|
(visibility === 'direct' ? 'Direct message' : 'Status') +
|
||||||
` by ${originalAccount.display_name || originalAccount.username}`
|
` by ${originalAccount.display_name || originalAccount.username}`
|
||||||
),
|
),
|
||||||
showHeader: (notification, status, timelineType) => (
|
showHeader: ({ notification, status, timelineType }) => (
|
||||||
(notification && (notification.type === 'reblog' || notification.type === 'favourite')) ||
|
(notification && (notification.type === 'reblog' || notification.type === 'favourite')) ||
|
||||||
status.reblog ||
|
status.reblog ||
|
||||||
timelineType === 'pinned'
|
timelineType === 'pinned'
|
||||||
),
|
),
|
||||||
className: (visibility, timelineType, isStatusInOwnThread) => (classname(
|
className: ({ visibility, timelineType, isStatusInOwnThread }) => (classname(
|
||||||
'status-article',
|
'status-article',
|
||||||
visibility === 'direct' && 'status-direct',
|
visibility === 'direct' && 'status-direct',
|
||||||
timelineType !== 'search' && 'status-in-timeline',
|
timelineType !== 'search' && 'status-in-timeline',
|
||||||
isStatusInOwnThread && 'status-in-own-thread'
|
isStatusInOwnThread && 'status-in-own-thread'
|
||||||
)),
|
)),
|
||||||
showContent: (spoilerText, spoilerShown) => !spoilerText || spoilerShown,
|
showContent: ({ spoilerText, spoilerShown }) => !spoilerText || spoilerShown,
|
||||||
params: (notification, notificationId, status, statusId, timelineType,
|
params: ({ notification, notificationId, status, statusId, timelineType,
|
||||||
account, accountId, uuid, isStatusInNotification, isStatusInOwnThread,
|
account, accountId, uuid, isStatusInNotification, isStatusInOwnThread,
|
||||||
originalAccount, originalAccountId, spoilerShown, visibility, replyShown,
|
originalAccount, originalAccountId, spoilerShown, visibility, replyShown,
|
||||||
replyVisibility, spoilerText, originalStatus, originalStatusId) => ({
|
replyVisibility, spoilerText, originalStatus, originalStatusId }) => ({
|
||||||
notification,
|
notification,
|
||||||
notificationId,
|
notificationId,
|
||||||
status,
|
status,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<span class="status-author-handle {{isStatusInNotification ? 'status-in-notification' : '' }}">
|
<span class="status-author-handle {isStatusInNotification ? 'status-in-notification' : '' }">
|
||||||
{{'@' + originalAccount.acct}}
|
{'@' + originalAccount.acct}
|
||||||
</span>
|
</span>
|
||||||
<style>
|
<style>
|
||||||
.status-author-handle {
|
.status-author-handle {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<a class="status-author-name {{isStatusInNotification ? 'status-in-notification' : '' }} {{isStatusInOwnThread ? 'status-in-own-thread' : ''}}"
|
<a class="status-author-name {isStatusInNotification ? 'status-in-notification' : '' } {isStatusInOwnThread ? 'status-in-own-thread' : ''}"
|
||||||
href="/accounts/{{originalAccountId}}"
|
href="/accounts/{originalAccountId}"
|
||||||
title="{{'@' + originalAccount.acct}}"
|
title="{'@' + originalAccount.acct}"
|
||||||
focus-key={{focusKey}}
|
focus-key={focusKey}
|
||||||
>
|
>
|
||||||
{{originalAccount.display_name || originalAccount.username}}
|
{originalAccount.display_name || originalAccount.username}
|
||||||
</a>
|
</a>
|
||||||
<style>
|
<style>
|
||||||
.status-author-name {
|
.status-author-name {
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
focusKey: (uuid) => `status-author-name-${uuid}`
|
focusKey: ({ uuid }) => `status-author-name-${uuid}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,12 +1,12 @@
|
||||||
<div class="status-article-compose-box">
|
<div class="status-article-compose-box">
|
||||||
<ComposeBox realm={{originalStatusId}}
|
<ComposeBox realm={originalStatusId}
|
||||||
size="slim"
|
size="slim"
|
||||||
autoFocus="true"
|
autoFocus="true"
|
||||||
hideBottomBorder="true"
|
hideBottomBorder="true"
|
||||||
isReply="true"
|
isReply="true"
|
||||||
replyVisibility={{visibility}}
|
replyVisibility={visibility}
|
||||||
replySpoiler={{spoilerText}}
|
replySpoiler={spoilerText}
|
||||||
inReplyToUuid={{uuid}}
|
inReplyToUuid={uuid}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
},
|
},
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
composeData: ($currentComposeData, originalStatusId) => $currentComposeData[originalStatusId] || {}
|
composeData: ({ $currentComposeData, originalStatusId }) => $currentComposeData[originalStatusId] || {}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
observe,
|
observe,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class={{computedClass}} ref:node>
|
<div class={computedClass} ref:node>
|
||||||
{{{massagedContent}}}
|
{@html massagedContent}
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.status-content {
|
.status-content {
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
},
|
},
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
computedClass: (isStatusInOwnThread, isStatusInNotification, shown) => {
|
computedClass: ({ isStatusInOwnThread, isStatusInNotification, shown }) => {
|
||||||
return classname(
|
return classname(
|
||||||
'status-content',
|
'status-content',
|
||||||
isStatusInOwnThread && 'status-in-own-thread',
|
isStatusInOwnThread && 'status-in-own-thread',
|
||||||
|
@ -79,9 +79,9 @@
|
||||||
shown && 'shown'
|
shown && 'shown'
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
content: (originalStatus) => originalStatus.content,
|
content: ({ originalStatus }) => originalStatus.content,
|
||||||
emojis: (originalStatus) => originalStatus.emojis,
|
emojis: ({ originalStatus }) => originalStatus.emojis,
|
||||||
massagedContent: (content, emojis, $autoplayGifs) => {
|
massagedContent: ({ content, emojis, $autoplayGifs }) => {
|
||||||
content = emojifyText(content, emojis, $autoplayGifs)
|
content = emojifyText(content, emojis, $autoplayGifs)
|
||||||
|
|
||||||
// GNU Social and Pleroma don't add <p> tags
|
// GNU Social and Pleroma don't add <p> tags
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
<div class="status-details">
|
<div class="status-details">
|
||||||
<ExternalLink className="status-absolute-date"
|
<ExternalLink className="status-absolute-date"
|
||||||
href={{originalStatus.url}}
|
href={originalStatus.url}
|
||||||
showIcon="true"
|
showIcon="true"
|
||||||
ariaLabel="{{formattedDate}} (opens in new window)"
|
ariaLabel="{formattedDate} (opens in new window)"
|
||||||
>
|
>
|
||||||
<time datetime={{createdAtDate}} title={{formattedDate}}>{{formattedDate}}</time>
|
<time datetime={createdAtDate} title={formattedDate}>{formattedDate}</time>
|
||||||
</ExternalLink>
|
</ExternalLink>
|
||||||
<a class="status-favs-reblogs"
|
<a class="status-favs-reblogs"
|
||||||
href="/statuses/{{originalStatusId}}/reblogs"
|
href="/statuses/{originalStatusId}/reblogs"
|
||||||
aria-label={{reblogsLabel}}>
|
aria-label={reblogsLabel}>
|
||||||
<svg class="status-favs-reblogs-svg">
|
<svg class="status-favs-reblogs-svg">
|
||||||
<use xlink:href="#fa-retweet"/>
|
<use xlink:href="#fa-retweet"/>
|
||||||
</svg>
|
</svg>
|
||||||
<span>{{numReblogs}}</span>
|
<span>{numReblogs}</span>
|
||||||
</a>
|
</a>
|
||||||
<a class="status-favs-reblogs"
|
<a class="status-favs-reblogs"
|
||||||
href="/statuses/{{originalStatusId}}/favorites"
|
href="/statuses/{originalStatusId}/favorites"
|
||||||
aria-label={{favoritesLabel}}>
|
aria-label={favoritesLabel}>
|
||||||
<svg class="status-favs-reblogs-svg">
|
<svg class="status-favs-reblogs-svg">
|
||||||
<use xlink:href="#fa-star" />
|
<use xlink:href="#fa-star" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>{{numFavs}}</span>
|
<span>{numFavs}</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
|
@ -99,17 +99,17 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
createdAtDate: (originalStatus) => originalStatus.created_at,
|
createdAtDate: ({ originalStatus }) => originalStatus.created_at,
|
||||||
numReblogs: (originalStatus) => originalStatus.reblogs_count || 0,
|
numReblogs: ({ originalStatus }) => originalStatus.reblogs_count || 0,
|
||||||
numFavs: (originalStatus) => originalStatus.favourites_count || 0,
|
numFavs: ({ originalStatus }) => originalStatus.favourites_count || 0,
|
||||||
formattedDate: (createdAtDate) => formatter.format(new Date(createdAtDate)),
|
formattedDate: ({ createdAtDate }) => formatter.format(new Date(createdAtDate)),
|
||||||
reblogsLabel: (numReblogs) => {
|
reblogsLabel: ({ numReblogs }) => {
|
||||||
// TODO: intl
|
// TODO: intl
|
||||||
return numReblogs === 1
|
return numReblogs === 1
|
||||||
? `Boosted ${numReblogs} time`
|
? `Boosted ${numReblogs} time`
|
||||||
: `Boosted ${numReblogs} times`
|
: `Boosted ${numReblogs} times`
|
||||||
},
|
},
|
||||||
favoritesLabel: (numFavs) => {
|
favoritesLabel: ({ numFavs }) => {
|
||||||
// TODO: intl
|
// TODO: intl
|
||||||
return numFavs === 1
|
return numFavs === 1
|
||||||
? `Favorited ${numFavs} time`
|
? `Favorited ${numFavs} time`
|
||||||
|
|
|
@ -1,30 +1,30 @@
|
||||||
<div class="status-header {{isStatusInNotification ? 'status-in-notification' : ''}} {{notification && notification.type === 'follow' ? 'header-is-follow' : ''}}">
|
<div class="status-header {isStatusInNotification ? 'status-in-notification' : ''} {notification && notification.type === 'follow' ? 'header-is-follow' : ''}">
|
||||||
<div class="status-header-avatar {{timelineType === 'pinned' ? 'hidden' : ''}}">
|
<div class="status-header-avatar {timelineType === 'pinned' ? 'hidden' : ''}">
|
||||||
<Avatar :account size="extra-small"/>
|
<Avatar {account} size="extra-small"/>
|
||||||
</div>
|
</div>
|
||||||
<svg class="status-header-svg">
|
<svg class="status-header-svg">
|
||||||
<use xlink:href={{icon}}/>
|
<use xlink:href={icon}/>
|
||||||
</svg>
|
</svg>
|
||||||
<span class="status-header-span">
|
<span class="status-header-span">
|
||||||
{{#if timelineType === 'pinned'}}
|
{#if timelineType === 'pinned'}
|
||||||
Pinned toot
|
Pinned toot
|
||||||
{{else}}
|
{:else}
|
||||||
<a href="/accounts/{{accountId}}"
|
<a href="/accounts/{accountId}"
|
||||||
class="status-header-a"
|
class="status-header-a"
|
||||||
title="{{'@' + account.acct}}"
|
title="{'@' + account.acct}"
|
||||||
focus-key={{focusKey}} >
|
focus-key={focusKey} >
|
||||||
{{account.display_name || account.username}}
|
{account.display_name || account.username}
|
||||||
</a>
|
</a>
|
||||||
{{#if notification && notification.type === 'reblog'}}
|
{#if notification && notification.type === 'reblog'}
|
||||||
boosted your status
|
boosted your status
|
||||||
{{elseif notification && notification.type === 'favourite'}}
|
{:elseif notification && notification.type === 'favourite'}
|
||||||
favorited your status
|
favorited your status
|
||||||
{{elseif notification && notification.type === 'follow'}}
|
{:elseif notification && notification.type === 'follow'}
|
||||||
followed you
|
followed you
|
||||||
{{elseif status && status.reblog}}
|
{:elseif status && status.reblog}
|
||||||
boosted
|
boosted
|
||||||
{{/if}}
|
{/if}
|
||||||
{{/if}}
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
|
@ -88,8 +88,8 @@
|
||||||
Avatar
|
Avatar
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
focusKey: (uuid) => `status-header-${uuid}`,
|
focusKey: ({ uuid }) => `status-header-${uuid}`,
|
||||||
icon: (notification, status, timelineType) => {
|
icon: ({ notification, status, timelineType }) => {
|
||||||
if (timelineType === 'pinned') {
|
if (timelineType === 'pinned') {
|
||||||
return '#fa-thumb-tack'
|
return '#fa-thumb-tack'
|
||||||
} else if ((notification && notification.type === 'reblog') || (status && status.reblog)) {
|
} else if ((notification && notification.type === 'reblog') || (status && status.reblog)) {
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
{{#if sensitive }}
|
{#if sensitive }
|
||||||
<div class="status-sensitive-media-container {{sensitiveShown ? 'status-sensitive-media-shown' : 'status-sensitive-media-hidden'}}"
|
<div class="status-sensitive-media-container {sensitiveShown ? 'status-sensitive-media-shown' : 'status-sensitive-media-hidden'}"
|
||||||
>
|
>
|
||||||
{{#if sensitiveShown}}
|
{#if sensitiveShown}
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="status-sensitive-media-button"
|
class="status-sensitive-media-button"
|
||||||
aria-label="Hide sensitive media"
|
aria-label="Hide sensitive media"
|
||||||
delegate-key={{delegateKey}} >
|
delegate-key={delegateKey} >
|
||||||
<div class="svg-wrapper">
|
<div class="svg-wrapper">
|
||||||
<svg class="status-sensitive-media-svg">
|
<svg class="status-sensitive-media-svg">
|
||||||
<use xlink:href="#fa-eye-slash" />
|
<use xlink:href="#fa-eye-slash" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
<MediaAttachments :mediaAttachments :sensitive :uuid />
|
<MediaAttachments {mediaAttachments} {sensitive} {uuid} />
|
||||||
{{else}}
|
{:else}
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="status-sensitive-media-button"
|
class="status-sensitive-media-button"
|
||||||
aria-label="Show sensitive media"
|
aria-label="Show sensitive media"
|
||||||
delegate-key={{delegateKey}} >
|
delegate-key={delegateKey} >
|
||||||
|
|
||||||
<div class="status-sensitive-media-warning">
|
<div class="status-sensitive-media-warning">
|
||||||
<span>Sensitive content. Click to show.</span>
|
<span>Sensitive content. Click to show.</span>
|
||||||
|
@ -28,11 +28,11 @@
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{:else}
|
||||||
<MediaAttachments :mediaAttachments :sensitive :uuid />
|
<MediaAttachments {mediaAttachments} {sensitive} {uuid} />
|
||||||
{{/if}}
|
{/if}
|
||||||
<style>
|
<style>
|
||||||
.status-sensitive-media-container {
|
.status-sensitive-media-container {
|
||||||
grid-area: media;
|
grid-area: media;
|
||||||
|
@ -138,10 +138,10 @@
|
||||||
},
|
},
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
mediaAttachments: (originalStatus) => originalStatus.media_attachments,
|
mediaAttachments: ({ originalStatus }) => originalStatus.media_attachments,
|
||||||
sensitiveShown: ($sensitivesShown, uuid) => !!$sensitivesShown[uuid],
|
sensitiveShown: ({ $sensitivesShown, uuid }) => !!$sensitivesShown[uuid],
|
||||||
sensitive: (originalStatus, $markMediaAsSensitive) => originalStatus.sensitive || $markMediaAsSensitive,
|
sensitive: ({ originalStatus, $markMediaAsSensitive }) => originalStatus.sensitive || $markMediaAsSensitive,
|
||||||
delegateKey: (uuid) => `sensitive-${uuid}`
|
delegateKey: ({ uuid }) => `sensitive-${uuid}`
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onClickSensitiveMediaButton () {
|
onClickSensitiveMediaButton () {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<a class="status-relative-date {{isStatusInNotification ? 'status-in-notification' : '' }}"
|
<a class="status-relative-date {isStatusInNotification ? 'status-in-notification' : '' }"
|
||||||
href="/statuses/{{originalStatusId}}"
|
href="/statuses/{originalStatusId}"
|
||||||
focus-key={{focusKey}}
|
focus-key={focusKey}
|
||||||
>
|
>
|
||||||
<time datetime={{createdAtDate}} title={{relativeDate}}
|
<time datetime={createdAtDate} title={relativeDate}
|
||||||
aria-label="{{relativeDate}} – click to show thread">
|
aria-label="{relativeDate} – click to show thread">
|
||||||
{{relativeDate}}
|
{relativeDate}
|
||||||
</time>
|
</time>
|
||||||
</a>
|
</a>
|
||||||
<style>
|
<style>
|
||||||
|
@ -35,14 +35,14 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
createdAtDate: (originalStatus) => originalStatus.created_at,
|
createdAtDate: ({ originalStatus }) => originalStatus.created_at,
|
||||||
relativeDate: (createdAtDate) => {
|
relativeDate: ({ createdAtDate }) => {
|
||||||
mark('compute relativeDate')
|
mark('compute relativeDate')
|
||||||
let res = timeagoInstance.format(createdAtDate)
|
let res = timeagoInstance.format(createdAtDate)
|
||||||
stop('compute relativeDate')
|
stop('compute relativeDate')
|
||||||
return res
|
return res
|
||||||
},
|
},
|
||||||
focusKey: (uuid) => `status-relative-date-${uuid}`
|
focusKey: ({ uuid }) => `status-relative-date-${uuid}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,11 +1,11 @@
|
||||||
<a class="status-sidebar size-{{size}}"
|
<a class="status-sidebar size-{size}"
|
||||||
href="/accounts/{{originalAccountId}}"
|
href="/accounts/{originalAccountId}"
|
||||||
focus-key={{focusKey}}
|
focus-key={focusKey}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
<Avatar account={{originalAccount}}
|
<Avatar account={originalAccount}
|
||||||
isLink="true"
|
isLink="true"
|
||||||
:size />
|
{size} />
|
||||||
</a>
|
</a>
|
||||||
<style>
|
<style>
|
||||||
.status-sidebar {
|
.status-sidebar {
|
||||||
|
@ -36,8 +36,8 @@
|
||||||
Avatar
|
Avatar
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
focusKey: (uuid) => `status-author-avatar-${uuid}`,
|
focusKey: ({ uuid }) => `status-author-avatar-${uuid}`,
|
||||||
size: (isStatusInOwnThread) => isStatusInOwnThread ? 'medium' : 'small'
|
size: ({ isStatusInOwnThread }) => isStatusInOwnThread ? 'medium' : 'small'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,9 +1,9 @@
|
||||||
<div class="status-spoiler {{isStatusInNotification ? 'status-in-notification' : ''}} {{isStatusInOwnThread ? 'status-in-own-thread' : ''}}">
|
<div class="status-spoiler {isStatusInNotification ? 'status-in-notification' : ''} {isStatusInOwnThread ? 'status-in-own-thread' : ''}">
|
||||||
<p>{{{massagedSpoilerText}}}</p>
|
<p>{@html massagedSpoilerText}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-spoiler-button {{isStatusInOwnThread ? 'status-in-own-thread' : ''}}">
|
<div class="status-spoiler-button {isStatusInOwnThread ? 'status-in-own-thread' : ''}">
|
||||||
<button type="button" delegate-key={{delegateKey}}>
|
<button type="button" delegate-key={delegateKey}>
|
||||||
{{spoilerShown ? 'Show less' : 'Show more'}}
|
{spoilerShown ? 'Show less' : 'Show more'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
|
@ -60,13 +60,13 @@
|
||||||
},
|
},
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
spoilerText: (originalStatus) => originalStatus.spoiler_text,
|
spoilerText: ({ originalStatus }) => originalStatus.spoiler_text,
|
||||||
emojis: (originalStatus) => originalStatus.emojis,
|
emojis: ({ originalStatus }) => originalStatus.emojis,
|
||||||
massagedSpoilerText: (spoilerText, emojis, $autoplayGifs) => {
|
massagedSpoilerText: ({ spoilerText, emojis, $autoplayGifs }) => {
|
||||||
spoilerText = escapeHtml(spoilerText)
|
spoilerText = escapeHtml(spoilerText)
|
||||||
return emojifyText(spoilerText, emojis, $autoplayGifs)
|
return emojifyText(spoilerText, emojis, $autoplayGifs)
|
||||||
},
|
},
|
||||||
delegateKey: (uuid) => `spoiler-${uuid}`
|
delegateKey: ({ uuid }) => `spoiler-${uuid}`
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onClickSpoilerButton () {
|
onClickSpoilerButton () {
|
||||||
|
|
|
@ -1,34 +1,34 @@
|
||||||
<div class="status-toolbar {{isStatusInOwnThread ? 'status-in-own-thread' : ''}}" ref:node>
|
<div class="status-toolbar {isStatusInOwnThread ? 'status-in-own-thread' : ''}" ref:node>
|
||||||
<IconButton
|
<IconButton
|
||||||
className="status-toolbar-reply-button"
|
className="status-toolbar-reply-button"
|
||||||
label={{replyLabel}}
|
label={replyLabel}
|
||||||
pressable="true"
|
pressable="true"
|
||||||
pressed={{replyShown}}
|
pressed={replyShown}
|
||||||
href="#fa-reply"
|
href="#fa-reply"
|
||||||
delegateKey={{replyKey}}
|
delegateKey={replyKey}
|
||||||
focusKey={{replyKey}}
|
focusKey={replyKey}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
label={{reblogLabel}}
|
label={reblogLabel}
|
||||||
pressable={{!reblogDisabled}}
|
pressable={!reblogDisabled}
|
||||||
pressed={{reblogged}}
|
pressed={reblogged}
|
||||||
disabled={{reblogDisabled}}
|
disabled={reblogDisabled}
|
||||||
href={{reblogIcon}}
|
href={reblogIcon}
|
||||||
delegateKey={{reblogKey}}
|
delegateKey={reblogKey}
|
||||||
ref:reblogIcon
|
ref:reblogIcon
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
label="Favorite"
|
label="Favorite"
|
||||||
pressable="true"
|
pressable="true"
|
||||||
pressed={{favorited}}
|
pressed={favorited}
|
||||||
href="#fa-star"
|
href="#fa-star"
|
||||||
delegateKey={{favoriteKey}}
|
delegateKey={favoriteKey}
|
||||||
ref:favoriteIcon
|
ref:favoriteIcon
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
label="Show more options"
|
label="Show more options"
|
||||||
href="#fa-ellipsis-h"
|
href="#fa-ellipsis-h"
|
||||||
delegateKey={{optionsKey}}
|
delegateKey={optionsKey}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
|
@ -133,8 +133,8 @@
|
||||||
reblogAnimation: REBLOG_ANIMATION
|
reblogAnimation: REBLOG_ANIMATION
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
replyLabel: (replyShown) => replyShown ? 'Close reply' : 'Reply',
|
replyLabel: ({ replyShown }) => replyShown ? 'Close reply' : 'Reply',
|
||||||
reblogLabel: (visibility) => {
|
reblogLabel: ({ visibility }) => {
|
||||||
switch (visibility) {
|
switch (visibility) {
|
||||||
case 'private':
|
case 'private':
|
||||||
return 'Cannot be boosted because this is followers-only'
|
return 'Cannot be boosted because this is followers-only'
|
||||||
|
@ -144,7 +144,7 @@
|
||||||
return 'Boost'
|
return 'Boost'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
reblogIcon: (visibility) => {
|
reblogIcon: ({ visibility }) => {
|
||||||
switch (visibility) {
|
switch (visibility) {
|
||||||
case 'private':
|
case 'private':
|
||||||
return '#fa-lock'
|
return '#fa-lock'
|
||||||
|
@ -154,25 +154,25 @@
|
||||||
return '#fa-retweet'
|
return '#fa-retweet'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
reblogDisabled: (visibility) => {
|
reblogDisabled: ({ visibility }) => {
|
||||||
return visibility === 'private' || visibility === 'direct'
|
return visibility === 'private' || visibility === 'direct'
|
||||||
},
|
},
|
||||||
reblogged: (originalStatusId, $currentStatusModifications, originalStatus) => {
|
reblogged: ({ originalStatusId, $currentStatusModifications, originalStatus }) => {
|
||||||
if ($currentStatusModifications && originalStatusId in $currentStatusModifications.reblogs) {
|
if ($currentStatusModifications && originalStatusId in $currentStatusModifications.reblogs) {
|
||||||
return $currentStatusModifications.reblogs[originalStatusId]
|
return $currentStatusModifications.reblogs[originalStatusId]
|
||||||
}
|
}
|
||||||
return originalStatus.reblogged
|
return originalStatus.reblogged
|
||||||
},
|
},
|
||||||
favorited: (originalStatusId, $currentStatusModifications, originalStatus) => {
|
favorited: ({ originalStatusId, $currentStatusModifications, originalStatus }) => {
|
||||||
if ($currentStatusModifications && originalStatusId in $currentStatusModifications.favorites) {
|
if ($currentStatusModifications && originalStatusId in $currentStatusModifications.favorites) {
|
||||||
return $currentStatusModifications.favorites[originalStatusId]
|
return $currentStatusModifications.favorites[originalStatusId]
|
||||||
}
|
}
|
||||||
return originalStatus.favourited
|
return originalStatus.favourited
|
||||||
},
|
},
|
||||||
favoriteKey: (uuid) => `fav-${uuid}`,
|
favoriteKey: ({ uuid }) => `fav-${uuid}`,
|
||||||
reblogKey: (uuid) => `reblog-${uuid}`,
|
reblogKey: ({ uuid }) => `reblog-${uuid}`,
|
||||||
replyKey: (uuid) => `reply-${uuid}`,
|
replyKey: ({ uuid }) => `reply-${uuid}`,
|
||||||
optionsKey: (uuid) => `options-${uuid}`
|
optionsKey: ({ uuid }) => `options-${uuid}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,11 +1,11 @@
|
||||||
<div class="lazy-timeline">
|
<div class="lazy-timeline">
|
||||||
{{#await importTimeline}}
|
{#await importTimeline}
|
||||||
<!-- awaiting promise -->
|
<!-- awaiting promise -->
|
||||||
{{then constructor}}
|
{:then constructor}
|
||||||
<:Component {constructor} :timeline />
|
<svelte:component this={constructor} {timeline} />
|
||||||
{{catch error}}
|
{:catch error}
|
||||||
<div>Component failed to load. Try refreshing! {{error}}</div>
|
<div>Component failed to load. Try refreshing! {error}</div>
|
||||||
{{/await}}
|
{/await}
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.lazy-timeline {
|
.lazy-timeline {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="loading-footer">
|
<div class="loading-footer">
|
||||||
<LoadingSpinner size={{48}} />
|
<LoadingSpinner size={48} />
|
||||||
<span class="loading-footer-info">
|
<span class="loading-footer-info">
|
||||||
Loading more...
|
Loading more...
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="more-items-header">
|
<div class="more-items-header">
|
||||||
<button class="primary" type="button" on:click="onClick(event)">
|
<button class="primary" type="button" on:click="onClick(event)">
|
||||||
Show {{count}} more
|
Show {count} more
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<MoreHeader count={{virtualProps.count}}
|
<MoreHeader count={virtualProps.count}
|
||||||
onClick={{virtualProps.onClick}}
|
onClick={virtualProps.onClick}
|
||||||
/>
|
/>
|
||||||
<script>
|
<script>
|
||||||
import MoreHeader from './MoreHeader.html'
|
import MoreHeader from './MoreHeader.html'
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<Notification
|
<Notification
|
||||||
notification={{virtualProps.notification}}
|
notification={virtualProps.notification}
|
||||||
timelineType={{virtualProps.timelineType}}
|
timelineType={virtualProps.timelineType}
|
||||||
timelineValue={{virtualProps.timelineValue}}
|
timelineValue={virtualProps.timelineValue}
|
||||||
focusSelector={{virtualProps.focusSelector}}
|
focusSelector={virtualProps.focusSelector}
|
||||||
index={{virtualIndex}}
|
index={virtualIndex}
|
||||||
length={{virtualLength}}
|
length={virtualLength}
|
||||||
on:recalculateHeight />
|
on:recalculateHeight />
|
||||||
<script>
|
<script>
|
||||||
import Notification from '../status/Notification.html'
|
import Notification from '../status/Notification.html'
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<div role="feed" aria-label="Pinned toots" class="pinned-statuses">
|
<div role="feed" aria-label="Pinned toots" class="pinned-statuses">
|
||||||
{{#each pinnedStatuses as status, index @id}}
|
{#each pinnedStatuses as status, index (status.id)}
|
||||||
<Status :status
|
<Status {status}
|
||||||
timelineType="pinned"
|
timelineType="pinned"
|
||||||
timelineValue={{accountId}}
|
timelineValue={accountId}
|
||||||
:index
|
{index}
|
||||||
length={{pinnedStatuses.length}}
|
length={pinnedStatuses.length}
|
||||||
/>
|
/>
|
||||||
{{/each}}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
import { store } from '../../_store/store'
|
import { store } from '../../_store/store'
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
await this.updatePinnedStatuses()
|
await this.updatePinnedStatuses()
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
pinnedStatuses: ($pinnedStatuses, $currentInstance, accountId) => {
|
pinnedStatuses: ({ $pinnedStatuses, $currentInstance, accountId }) => {
|
||||||
return ($pinnedStatuses[$currentInstance] && $pinnedStatuses[$currentInstance][accountId]) || []
|
return ($pinnedStatuses[$currentInstance] && $pinnedStatuses[$currentInstance][accountId]) || []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<Status status={{virtualProps.status}}
|
<Status status={virtualProps.status}
|
||||||
timelineType={{virtualProps.timelineType}}
|
timelineType={virtualProps.timelineType}
|
||||||
timelineValue={{virtualProps.timelineValue}}
|
timelineValue={virtualProps.timelineValue}
|
||||||
focusSelector={{virtualProps.focusSelector}}
|
focusSelector={virtualProps.focusSelector}
|
||||||
index={{virtualIndex}}
|
index={virtualIndex}
|
||||||
length={{virtualLength}}
|
length={virtualLength}
|
||||||
on:recalculateHeight />
|
on:recalculateHeight />
|
||||||
<script>
|
<script>
|
||||||
import Status from '../status/Status.html'
|
import Status from '../status/Status.html'
|
||||||
|
|
|
@ -1,33 +1,33 @@
|
||||||
<h1 class="sr-only">{{label}}</h1>
|
<h1 class="sr-only">{label}</h1>
|
||||||
<div class="timeline"
|
<div class="timeline"
|
||||||
role="feed"
|
role="feed"
|
||||||
on:focusWithCapture="saveFocus(event)"
|
on:focusWithCapture="saveFocus(event)"
|
||||||
on:blurWithCapture="clearFocus(event)"
|
on:blurWithCapture="clearFocus(event)"
|
||||||
>
|
>
|
||||||
{{#await componentsPromise}}
|
{#await componentsPromise}
|
||||||
<!-- awaiting promise -->
|
<!-- awaiting promise -->
|
||||||
{{then result}}
|
{:then result}
|
||||||
<:Component {result.listComponent}
|
<svelte:component this={result.listComponent}
|
||||||
component={{result.listItemComponent}}
|
component={result.listItemComponent}
|
||||||
realm="{{$currentInstance + '/' + timeline}}"
|
realm="{$currentInstance + '/' + timeline}"
|
||||||
containerQuery=".container"
|
containerQuery=".container"
|
||||||
:makeProps
|
{makeProps}
|
||||||
items={{$timelineItemIds}}
|
items={$timelineItemIds}
|
||||||
showFooter={{$timelineInitialized && $runningUpdate}}
|
showFooter={$timelineInitialized && $runningUpdate}
|
||||||
footerComponent={{LoadingFooter}}
|
footerComponent={LoadingFooter}
|
||||||
showHeader={{$showHeader}}
|
showHeader={$showHeader}
|
||||||
headerComponent={{MoreHeaderVirtualWrapper}}
|
headerComponent={MoreHeaderVirtualWrapper}
|
||||||
:headerProps
|
{headerProps}
|
||||||
:scrollToItem
|
{scrollToItem}
|
||||||
on:scrollToBottom="onScrollToBottom()"
|
on:scrollToBottom="onScrollToBottom()"
|
||||||
on:scrollToTop="onScrollToTop()"
|
on:scrollToTop="onScrollToTop()"
|
||||||
on:scrollTopChanged="onScrollTopChanged(event)"
|
on:scrollTopChanged="onScrollTopChanged(event)"
|
||||||
on:initialized="initialize()"
|
on:initialized="initialize()"
|
||||||
on:noNeedToScroll="onNoNeedToScroll()"
|
on:noNeedToScroll="onNoNeedToScroll()"
|
||||||
/>
|
/>
|
||||||
{{catch error}}
|
{:catch error}
|
||||||
<div>Error: component failed to load! Try reloading. {{error}}</div>
|
<div>Error: component failed to load! Try reloading. {error}</div>
|
||||||
{{/await}}
|
{/await}
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
import { store } from '../../_store/store'
|
import { store } from '../../_store/store'
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
// due to need to scroll to the right item and thus calculate all item heights up-front.
|
// due to need to scroll to the right item and thus calculate all item heights up-front.
|
||||||
// Here we lazy-load both the virtual list component itself as well as the component
|
// Here we lazy-load both the virtual list component itself as well as the component
|
||||||
// it renders.
|
// it renders.
|
||||||
componentsPromise: (timelineType) => {
|
componentsPromise: ({ timelineType }) => {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
timelineType === 'status'
|
timelineType === 'status'
|
||||||
? importPseudoVirtualList()
|
? importPseudoVirtualList()
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
listItemComponent: results[1]
|
listItemComponent: results[1]
|
||||||
}))
|
}))
|
||||||
},
|
},
|
||||||
makeProps: ($currentInstance, timelineType, timelineValue) => async (itemId) => {
|
makeProps: ({ $currentInstance, timelineType, timelineValue }) => async (itemId) => {
|
||||||
let res = {
|
let res = {
|
||||||
timelineType,
|
timelineType,
|
||||||
timelineValue
|
timelineValue
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
},
|
},
|
||||||
label: (timeline, $currentInstance, timelineType, timelineValue) => {
|
label: ({ timeline, $currentInstance, timelineType, timelineValue }) => {
|
||||||
if (timelines[timeline]) {
|
if (timelines[timeline]) {
|
||||||
return `${timelines[timeline].label} timeline for ${$currentInstance}`
|
return `${timelines[timeline].label} timeline for ${$currentInstance}`
|
||||||
}
|
}
|
||||||
|
@ -125,20 +125,20 @@
|
||||||
return `Notifications for ${$currentInstance}`
|
return `Notifications for ${$currentInstance}`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
timelineType: (timeline) => {
|
timelineType: ({ timeline }) => {
|
||||||
return timeline.split('/')[0]
|
return timeline.split('/')[0]
|
||||||
},
|
},
|
||||||
timelineValue: (timeline) => {
|
timelineValue: ({ timeline }) => {
|
||||||
return timeline.split('/').slice(-1)[0]
|
return timeline.split('/').slice(-1)[0]
|
||||||
},
|
},
|
||||||
// Scroll to the first item if this is a "status in own thread" timeline.
|
// Scroll to the first item if this is a "status in own thread" timeline.
|
||||||
// Don't scroll to the first item because it obscures the "back" button.
|
// Don't scroll to the first item because it obscures the "back" button.
|
||||||
scrollToItem: (timelineType, timelineValue, $firstTimelineItemId) => (
|
scrollToItem: ({ timelineType, timelineValue, $firstTimelineItemId }) => (
|
||||||
timelineType === 'status' && $firstTimelineItemId &&
|
timelineType === 'status' && $firstTimelineItemId &&
|
||||||
timelineValue !== $firstTimelineItemId && timelineValue
|
timelineValue !== $firstTimelineItemId && timelineValue
|
||||||
),
|
),
|
||||||
itemIdsToAdd: ($itemIdsToAdd) => $itemIdsToAdd,
|
itemIdsToAdd: ({ $itemIdsToAdd }) => $itemIdsToAdd,
|
||||||
headerProps: (itemIdsToAdd) => {
|
headerProps: ({ itemIdsToAdd }) => {
|
||||||
return {
|
return {
|
||||||
count: itemIdsToAdd ? itemIdsToAdd.length : 0,
|
count: itemIdsToAdd ? itemIdsToAdd.length : 0,
|
||||||
onClick: showMoreItemsForCurrentTimeline
|
onClick: showMoreItemsForCurrentTimeline
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
<VirtualListContainer :realm :containerQuery on:initialized on:noNeedToScroll >
|
<VirtualListContainer {realm} {containerQuery} on:initialized on:noNeedToScroll >
|
||||||
<div class="virtual-list"
|
<div class="virtual-list"
|
||||||
style="height: {{$height}}px;"
|
style="height: {$height}px;"
|
||||||
ref:node >
|
ref:node >
|
||||||
<VirtualListHeader component={{headerComponent}} virtualProps={{headerProps}} shown={{$showHeader}}/>
|
<VirtualListHeader component={headerComponent} virtualProps={headerProps} shown={$showHeader}/>
|
||||||
{{#if $visibleItems}}
|
{#if $visibleItems}
|
||||||
{{#each $visibleItems as visibleItem @key}}
|
{#each $visibleItems as visibleItem (visibleItem.key)}
|
||||||
<VirtualListLazyItem :component
|
<VirtualListLazyItem {component}
|
||||||
offset={{visibleItem.offset}}
|
offset={visibleItem.offset}
|
||||||
:makeProps
|
{makeProps}
|
||||||
key={{visibleItem.key}}
|
key={visibleItem.key}
|
||||||
index={{visibleItem.index}}
|
index={visibleItem.index}
|
||||||
/>
|
/>
|
||||||
{{/each}}
|
{/each}
|
||||||
{{/if}}
|
{/if}
|
||||||
{{#if $showFooter}}
|
{#if $showFooter}
|
||||||
<VirtualListFooter component={{footerComponent}} />
|
<VirtualListFooter component={footerComponent} />
|
||||||
{{/if}}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</VirtualListContainer>
|
</VirtualListContainer>
|
||||||
<style>
|
<style>
|
||||||
|
@ -101,12 +101,12 @@
|
||||||
VirtualListHeader
|
VirtualListHeader
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
distanceFromBottom: ($scrollHeight, $scrollTop, $offsetHeight) => {
|
distanceFromBottom: ({ $scrollHeight, $scrollTop, $offsetHeight }) => {
|
||||||
return $scrollHeight - $scrollTop - $offsetHeight
|
return $scrollHeight - $scrollTop - $offsetHeight
|
||||||
},
|
},
|
||||||
scrollTop: ($scrollTop) => $scrollTop,
|
scrollTop: ({ $scrollTop }) => $scrollTop,
|
||||||
// TODO: bug in svelte store, shouldn't need to do this
|
// TODO: bug in svelte store, shouldn't need to do this
|
||||||
allVisibleItemsHaveHeight: ($allVisibleItemsHaveHeight) => $allVisibleItemsHaveHeight
|
allVisibleItemsHaveHeight: ({ $allVisibleItemsHaveHeight }) => $allVisibleItemsHaveHeight
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
observe,
|
observe,
|
||||||
|
|
|
@ -115,7 +115,7 @@
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// TODO: bug in svelte/store – the observer in oncreate() never get removed without this hack
|
// TODO: bug in svelte/store – the observer in oncreate() never get removed without this hack
|
||||||
allVisibleItemsHaveHeight: ($allVisibleItemsHaveHeight) => $allVisibleItemsHaveHeight
|
allVisibleItemsHaveHeight: ({ $allVisibleItemsHaveHeight }) => $allVisibleItemsHaveHeight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="virtual-list-footer"
|
<div class="virtual-list-footer"
|
||||||
ref:node
|
ref:node
|
||||||
style="transform: translateY({{$heightWithoutFooter}}px);" >
|
style="transform: translateY({$heightWithoutFooter}px);" >
|
||||||
<:Component {component} />
|
<svelte:component this={component} />
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.virtual-list-footer {
|
.virtual-list-footer {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="virtual-list-header {{shown ? 'shown' : ''}} {{fadedIn ? 'faded-in' : ''}}"
|
<div class="virtual-list-header {shown ? 'shown' : ''} {fadedIn ? 'faded-in' : ''}"
|
||||||
ref:node >
|
ref:node >
|
||||||
<:Component {component} :virtualProps />
|
<svelte:component this={component} {virtualProps} />
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
.virtual-list-header {
|
.virtual-list-header {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<div class="virtual-list-item {{shown ? 'shown' : ''}}"
|
<div class="virtual-list-item {shown ? 'shown' : ''}"
|
||||||
aria-hidden={{!shown}}
|
aria-hidden={!shown}
|
||||||
virtual-list-key={{key}}
|
virtual-list-key={key}
|
||||||
ref:node
|
ref:node
|
||||||
style="transform: translateY({{offset}}px);" >
|
style="transform: translateY({offset}px);" >
|
||||||
<:Component {component}
|
<svelte:component this={component}
|
||||||
virtualProps={{props}}
|
virtualProps={props}
|
||||||
virtualIndex={{index}}
|
virtualIndex={index}
|
||||||
virtualLength={{$length}}
|
virtualLength={$length}
|
||||||
on:recalculateHeight="doRecalculateHeight()"/>
|
on:recalculateHeight="doRecalculateHeight()"/>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
},
|
},
|
||||||
store: () => virtualListStore,
|
store: () => virtualListStore,
|
||||||
computed: {
|
computed: {
|
||||||
'shown': ($itemHeights, key) => $itemHeights[key] > 0
|
'shown': ({ $itemHeights, key }) => $itemHeights[key] > 0
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
doRecalculateHeight () {
|
doRecalculateHeight () {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
{{#if props}}
|
{#if props}
|
||||||
<VirtualListItem :component
|
<VirtualListItem {component}
|
||||||
:offset
|
{offset}
|
||||||
:props
|
{props}
|
||||||
:key
|
{key}
|
||||||
:index
|
{index}
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{/if}
|
||||||
<script>
|
<script>
|
||||||
import VirtualListItem from './VirtualListItem'
|
import VirtualListItem from './VirtualListItem'
|
||||||
import { mark, stop } from '../../_utils/marks'
|
import { mark, stop } from '../../_utils/marks'
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
{{#if $isUserLoggedIn}}
|
{#if $isUserLoggedIn}
|
||||||
<TimelinePage timeline="account/{{params.accountId}}">
|
<TimelinePage timeline="account/{params.accountId}">
|
||||||
<DynamicPageBanner title="" />
|
<DynamicPageBanner title="" />
|
||||||
{{#if $currentAccountProfile && $currentVerifyCredentials}}
|
{#if $currentAccountProfile && $currentVerifyCredentials}
|
||||||
<AccountProfile account={{$currentAccountProfile}}
|
<AccountProfile account={$currentAccountProfile}
|
||||||
relationship={{$currentAccountRelationship}}
|
relationship={$currentAccountRelationship}
|
||||||
verifyCredentials={{$currentVerifyCredentials}}
|
verifyCredentials={$currentVerifyCredentials}
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{/if}
|
||||||
<PinnedStatuses accountId={{params.accountId}} />
|
<PinnedStatuses accountId={params.accountId} />
|
||||||
</TimelinePage>
|
</TimelinePage>
|
||||||
{{else}}
|
{:else}
|
||||||
<HiddenFromSSR>
|
<HiddenFromSSR>
|
||||||
<FreeTextLayout>
|
<FreeTextLayout>
|
||||||
<h1>Profile</h1>
|
<h1>Profile</h1>
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
<p>A user timeline will appear here when logged in.</p>
|
<p>A user timeline will appear here when logged in.</p>
|
||||||
</FreeTextLayout>
|
</FreeTextLayout>
|
||||||
</HiddenFromSSR>
|
</HiddenFromSSR>
|
||||||
{{/if}}
|
{/if}
|
||||||
<script>
|
<script>
|
||||||
import TimelinePage from '../../_components/TimelinePage.html'
|
import TimelinePage from '../../_components/TimelinePage.html'
|
||||||
import FreeTextLayout from '../../_components/FreeTextLayout.html'
|
import FreeTextLayout from '../../_components/FreeTextLayout.html'
|
||||||
|
@ -37,10 +37,10 @@
|
||||||
},
|
},
|
||||||
store: () => store,
|
store: () => store,
|
||||||
computed: {
|
computed: {
|
||||||
profileName: ($currentAccountProfile) => {
|
profileName: ({ $currentAccountProfile }) => {
|
||||||
return ($currentAccountProfile && ('@' + $currentAccountProfile.acct)) || ''
|
return ($currentAccountProfile && ('@' + $currentAccountProfile.acct)) || ''
|
||||||
},
|
},
|
||||||
shortProfileName: ($currentAccountProfile) => {
|
shortProfileName: ({ $currentAccountProfile }) => {
|
||||||
return ($currentAccountProfile && ('@' + $currentAccountProfile.username)) || ''
|
return ($currentAccountProfile && ('@' + $currentAccountProfile.username)) || ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<DynamicPageBanner title="Followers" />
|
<DynamicPageBanner title="Followers" />
|
||||||
<AccountsListPage :accountsFetcher />
|
<AccountsListPage {accountsFetcher} />
|
||||||
<script>
|
<script>
|
||||||
import { getFollowers } from '../../../_api/followsAndFollowers'
|
import { getFollowers } from '../../../_api/followsAndFollowers'
|
||||||
import AccountsListPage from '../../../_components/AccountsListPage.html'
|
import AccountsListPage from '../../../_components/AccountsListPage.html'
|
||||||
|
@ -8,8 +8,8 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
accountId: params => params.accountId,
|
accountId: ({ params }) => params.accountId,
|
||||||
accountsFetcher: ($currentInstance, $accessToken, accountId) => () => getFollowers($currentInstance, $accessToken, accountId)
|
accountsFetcher: ({ $currentInstance, $accessToken, accountId }) => () => getFollowers($currentInstance, $accessToken, accountId)
|
||||||
},
|
},
|
||||||
store: () => store,
|
store: () => store,
|
||||||
components: {
|
components: {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<DynamicPageBanner title="Follows" />
|
<DynamicPageBanner title="Follows" />
|
||||||
<AccountsListPage :accountsFetcher />
|
<AccountsListPage {accountsFetcher} />
|
||||||
<script>
|
<script>
|
||||||
import { getFollows } from '../../../_api/followsAndFollowers'
|
import { getFollows } from '../../../_api/followsAndFollowers'
|
||||||
import AccountsListPage from '../../../_components/AccountsListPage.html'
|
import AccountsListPage from '../../../_components/AccountsListPage.html'
|
||||||
|
@ -8,8 +8,8 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
accountId: params => params.accountId,
|
accountId: ({ params }) => params.accountId,
|
||||||
accountsFetcher: ($currentInstance, $accessToken, accountId) => () => getFollows($currentInstance, $accessToken, accountId)
|
accountsFetcher: ({ $currentInstance, $accessToken, accountId }) => () => getFollows($currentInstance, $accessToken, accountId)
|
||||||
},
|
},
|
||||||
store: () => store,
|
store: () => store,
|
||||||
components: {
|
components: {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<DynamicPageBanner title="Blocked users" icon="#fa-ban" />
|
<DynamicPageBanner title="Blocked users" icon="#fa-ban" />
|
||||||
<AccountsListPage :accountsFetcher :accountActions />
|
<AccountsListPage {accountsFetcher} {accountActions} />
|
||||||
<script>
|
<script>
|
||||||
import AccountsListPage from '.././_components/AccountsListPage.html'
|
import AccountsListPage from '.././_components/AccountsListPage.html'
|
||||||
import { store } from '.././_store/store'
|
import { store } from '.././_store/store'
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
accountsFetcher: ($currentInstance, $accessToken) => () => getBlockedAccounts($currentInstance, $accessToken)
|
accountsFetcher: ({ $currentInstance, $accessToken }) => () => getBlockedAccounts($currentInstance, $accessToken)
|
||||||
},
|
},
|
||||||
store: () => store,
|
store: () => store,
|
||||||
components: {
|
components: {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{{#if $isUserLoggedIn}}
|
{#if $isUserLoggedIn}
|
||||||
<div class="community-page">
|
<div class="community-page">
|
||||||
|
|
||||||
<h2 class="community-header">
|
<h2 class="community-header">
|
||||||
|
@ -23,35 +23,35 @@
|
||||||
/>
|
/>
|
||||||
</PageList>
|
</PageList>
|
||||||
|
|
||||||
{{#if $lists.length}}
|
{#if $lists.length}
|
||||||
|
|
||||||
<h2 class="community-header">
|
<h2 class="community-header">
|
||||||
Lists
|
Lists
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<PageList label="Lists">
|
<PageList label="Lists">
|
||||||
{{#each $lists as list}}
|
{#each $lists as list}
|
||||||
<PageListItem href="/lists/{{list.id}}"
|
<PageListItem href="/lists/{list.id}"
|
||||||
label={{list.title}}
|
label={list.title}
|
||||||
icon="#fa-bars"
|
icon="#fa-bars"
|
||||||
pinnable="true"
|
pinnable="true"
|
||||||
/>
|
/>
|
||||||
{{/each}}
|
{/each}
|
||||||
</PageList>
|
</PageList>
|
||||||
|
|
||||||
{{/if}}
|
{/if}
|
||||||
|
|
||||||
<h2 class="community-header">
|
<h2 class="community-header">
|
||||||
Instance settings
|
Instance settings
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<PageList label="Instance settings">
|
<PageList label="Instance settings">
|
||||||
{{#if isLockedAccount}}
|
{#if isLockedAccount}
|
||||||
<PageListItem href="/requests"
|
<PageListItem href="/requests"
|
||||||
label="Follow requests"
|
label="Follow requests"
|
||||||
icon="#fa-user-plus"
|
icon="#fa-user-plus"
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{/if}
|
||||||
<PageListItem href="/muted"
|
<PageListItem href="/muted"
|
||||||
label="Muted users"
|
label="Muted users"
|
||||||
icon="#fa-volume-off"
|
icon="#fa-volume-off"
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
</PageList>
|
</PageList>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{:else}
|
||||||
<HiddenFromSSR>
|
<HiddenFromSSR>
|
||||||
<FreeTextLayout>
|
<FreeTextLayout>
|
||||||
<h1>Community</h1>
|
<h1>Community</h1>
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
<p>Community options appear here when logged in.</p>
|
<p>Community options appear here when logged in.</p>
|
||||||
</FreeTextLayout>
|
</FreeTextLayout>
|
||||||
</HiddenFromSSR>
|
</HiddenFromSSR>
|
||||||
{{/if}}
|
{/if}
|
||||||
<style>
|
<style>
|
||||||
.community-page {
|
.community-page {
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
PageListItem
|
PageListItem
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isLockedAccount: ($currentVerifyCredentials) => $currentVerifyCredentials && $currentVerifyCredentials.locked
|
isLockedAccount: ({ $currentVerifyCredentials }) => $currentVerifyCredentials && $currentVerifyCredentials.locked
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -1,10 +1,10 @@
|
||||||
{{#if $isUserLoggedIn}}
|
{#if $isUserLoggedIn}
|
||||||
<TimelinePage timeline="favorites">
|
<TimelinePage timeline="favorites">
|
||||||
{{#if $pinnedPage !== '/favorites'}}
|
{#if $pinnedPage !== '/favorites'}
|
||||||
<DynamicPageBanner title="Favorites" icon="#fa-star"/>
|
<DynamicPageBanner title="Favorites" icon="#fa-star"/>
|
||||||
{{/if}}
|
{/if}
|
||||||
</TimelinePage>
|
</TimelinePage>
|
||||||
{{else}}
|
{:else}
|
||||||
<HiddenFromSSR>
|
<HiddenFromSSR>
|
||||||
<FreeTextLayout>
|
<FreeTextLayout>
|
||||||
<h1>Favorites</h1>
|
<h1>Favorites</h1>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<p>Your favorites will appear here when logged in.</p>
|
<p>Your favorites will appear here when logged in.</p>
|
||||||
</FreeTextLayout>
|
</FreeTextLayout>
|
||||||
</HiddenFromSSR>
|
</HiddenFromSSR>
|
||||||
{{/if}}
|
{/if}
|
||||||
<script>
|
<script>
|
||||||
import TimelinePage from '.././_components/TimelinePage.html'
|
import TimelinePage from '.././_components/TimelinePage.html'
|
||||||
import FreeTextLayout from '.././_components/FreeTextLayout.html'
|
import FreeTextLayout from '.././_components/FreeTextLayout.html'
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
{{#if $isUserLoggedIn}}
|
{#if $isUserLoggedIn}
|
||||||
<TimelinePage timeline="federated">
|
<TimelinePage timeline="federated">
|
||||||
{{#if $pinnedPage !== '/federated'}}
|
{#if $pinnedPage !== '/federated'}
|
||||||
<DynamicPageBanner title="Federated Timeline" icon="#fa-globe"/>
|
<DynamicPageBanner title="Federated Timeline" icon="#fa-globe"/>
|
||||||
{{/if}}
|
{/if}
|
||||||
</TimelinePage>
|
</TimelinePage>
|
||||||
{{else}}
|
{:else}
|
||||||
<HiddenFromSSR>
|
<HiddenFromSSR>
|
||||||
<FreeTextLayout>
|
<FreeTextLayout>
|
||||||
<h1>Federated</h1>
|
<h1>Federated</h1>
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
<p>Your federated timeline will appear here when logged in.</p>
|
<p>Your federated timeline will appear here when logged in.</p>
|
||||||
</FreeTextLayout>
|
</FreeTextLayout>
|
||||||
</HiddenFromSSR>
|
</HiddenFromSSR>
|
||||||
{{/if}}
|
{/if}
|
||||||
<script>
|
<script>
|
||||||
import TimelinePage from '.././_components/TimelinePage.html'
|
import TimelinePage from '.././_components/TimelinePage.html'
|
||||||
import FreeTextLayout from '.././_components/FreeTextLayout.html'
|
import FreeTextLayout from '.././_components/FreeTextLayout.html'
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
{{#if $isUserLoggedIn}}
|
{#if $isUserLoggedIn}
|
||||||
<TimelineHomePage/>
|
<TimelineHomePage/>
|
||||||
{{else}}
|
{:else}
|
||||||
<NotLoggedInHome/>
|
<NotLoggedInHome/>
|
||||||
{{/if}}
|
{/if}
|
||||||
<script>
|
<script>
|
||||||
import NotLoggedInHome from '.././_components/NotLoggedInHome.html'
|
import NotLoggedInHome from '.././_components/NotLoggedInHome.html'
|
||||||
import { store } from '.././_store/store.js'
|
import { store } from '.././_store/store.js'
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue