make statuses robust against duplicates, remove duplicate from test

This commit is contained in:
Nolan Lawson 2018-03-15 20:04:24 -07:00
parent a5ca99c2f0
commit a25dd048b6
14 changed files with 128 additions and 112 deletions

View file

@ -186,10 +186,6 @@ export const actions = times(30, i => ({
privacy: 'unlisted' privacy: 'unlisted'
} }
}, },
{
user: 'admin',
boost: 'notification-of-unlisted-message'
},
{ {
user: 'admin', user: 'admin',
boost: 'foobar-this-is-unlisted' boost: 'foobar-this-is-unlisted'

View file

@ -10,7 +10,8 @@
aria-posinset="{{index}}" aria-setsize="{{length}}" aria-posinset="{{index}}" aria-setsize="{{length}}"
> >
<div class="follow-notification-offset"> <div class="follow-notification-offset">
<StatusHeader :status :notification isStatusInNotification="true" /> <StatusHeader :notification :notificationId :status :statusId :timelineType
:account :accountId :uuid isStatusInNotification="true" />
</div> </div>
</article> </article>
{{/if}} {{/if}}
@ -35,10 +36,23 @@
<script> <script>
import Status from './Status.html' import Status from './Status.html'
import StatusHeader from './StatusHeader.html' import StatusHeader from './StatusHeader.html'
import { store } from '../../_store/store'
export default { export default {
components: { components: {
Status, Status,
StatusHeader StatusHeader
},
store: () => store,
computed: {
account: (notification) => notification.account,
accountId: (account) => account.id,
notificationId: (notification) => notification.id,
status: (notification) => notification.status,
statusId: (status) => status && status.id,
uuid: ($currentInstance, timelineType, timelineValue, notificationId, statusId) => {
return `${$currentInstance}/${timelineType}/${timelineValue}/${notificationId}/${statusId || ''}`
},
} }
} }
</script> </script>

View file

@ -7,29 +7,34 @@
aria-label="{{ariaLabel}}" aria-label="{{ariaLabel}}"
on:recalculateHeight> on:recalculateHeight>
{{#if showHeader}} {{#if showHeader}}
<StatusHeader :notification :status :isStatusInNotification :timelineType /> <StatusHeader :notification :notificationId :status :statusId :timelineType
:account :accountId :uuid :isStatusInNotification />
{{/if}} {{/if}}
<StatusAuthorName status="{{originalStatus}}" :isStatusInOwnThread :isStatusInNotification /> <StatusAuthorName :isStatusInNotification :isStatusInOwnThread :originalAccountId
<StatusAuthorHandle status="{{originalStatus}}" :isStatusInNotification /> :originalAccount :uuid />
<StatusAuthorHandle :isStatusInNotification :originalAccount />
{{#if !isStatusInOwnThread}} {{#if !isStatusInOwnThread}}
<StatusRelativeDate status="{{originalStatus}}" :isStatusInNotification /> <StatusRelativeDate :isStatusInNotification :originalStatus :originalStatusId :uuid />
{{/if}} {{/if}}
<StatusSidebar status="{{originalStatus}}" :isStatusInOwnThread /> <StatusSidebar :isStatusInOwnThread :originalAccount />
{{#if originalStatus.spoiler_text}} {{#if originalStatus.spoiler_text}}
<StatusSpoiler status="{{originalStatus}}" :isStatusInOwnThread :contextualStatusId :isStatusInNotification <StatusSpoiler :isStatusInOwnThread :isStatusInNotification
:originalStatus :uuid
on:recalculateHeight /> on:recalculateHeight />
{{/if}} {{/if}}
{{#if !originalStatus.spoiler_text || spoilerShown}} {{#if !originalStatus.spoiler_text || spoilerShown}}
<StatusContent status="{{originalStatus}}" :isStatusInOwnThread :isStatusInNotification /> <StatusContent :isStatusInOwnThread :isStatusInNotification
:originalStatus :uuid />
{{/if}} {{/if}}
{{#if originalStatus.media_attachments && originalStatus.media_attachments.length}} {{#if originalStatus.media_attachments && originalStatus.media_attachments.length}}
<StatusMediaAttachments status="{{originalStatus}}" :timelineType :timelineValue <StatusMediaAttachments :originalStatus :uuid
on:recalculateHeight :contextualStatusId /> on:recalculateHeight />
{{/if}} {{/if}}
{{#if isStatusInOwnThread}} {{#if isStatusInOwnThread}}
<StatusDetails status="{{originalStatus}}" /> <StatusDetails :originalStatus :originalStatusId />
{{/if}} {{/if}}
<StatusToolbar status="{{originalStatus}}" :isStatusInOwnThread /> <StatusToolbar :originalStatus :originalStatusId :originalAccountId
:isStatusInOwnThread :uuid />
</article> </article>
<style> <style>
@ -147,26 +152,35 @@
parentElement.parentElement.localName !== 'button') { parentElement.parentElement.localName !== 'button') {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
goto(`/statuses/${this.get('statusId')}`) goto(`/statuses/${this.get('originalStatusId')}`)
} }
} }
}, },
computed: { computed: {
originalStatus: (status) => status.reblog ? status.reblog : status, originalStatus: (status) => status.reblog ? status.reblog : status,
statusId: (originalStatus) => originalStatus.id, originalStatusId: (originalStatus) => originalStatus.id,
delegateKey: (statusId) => `status-${statusId}`, statusId: (status) => status.id,
contextualStatusId: ($currentInstance, timelineType, timelineValue, status, notification) => { notificationId: (notification) => notification && notification.id,
return `${$currentInstance}/${timelineType}/${timelineValue}/${notification ? notification.id : ''}/${status.id}` account: (notification, status) => {
return (notification && notification.account) || status.account
}, },
accountId: (account) => account.id,
originalAccount: (originalStatus) => originalStatus.account, originalAccount: (originalStatus) => originalStatus.account,
isStatusInOwnThread: (timelineType, timelineValue, statusId) => { originalAccountId: (originalAccount) => originalAccount.id,
return (timelineType === 'status' || timelineType === 'reply') && timelineValue === statusId uuid: ($currentInstance, timelineType, timelineValue, notificationId, statusId) => {
return `${$currentInstance}/${timelineType}/${timelineValue}/${notificationId || ''}/${statusId}`
}, },
isStatusInNotification: (status, notification) => notification && notification.status && notification.type !== 'mention' && notification.status.id === status.id, delegateKey: (uuid) => `status-${uuid}`,
spoilerShown: ($spoilersShown, contextualStatusId) => !!$spoilersShown[contextualStatusId], isStatusInOwnThread: (timelineType, timelineValue, originalStatusId) => {
visibility: (originalStatus) => originalStatus.visibility, return (timelineType === 'status' || timelineType === 'reply') && timelineValue === originalStatusId
ariaLabel: (originalAccount, visibility) => { },
return (visibility === 'direct' ? 'Direct message' : 'Status') + isStatusInNotification: (originalStatusId, notification) => {
return notification && notification.status &&
notification.type !== 'mention' && notification.status.id === originalStatusId
},
spoilerShown: ($spoilersShown, uuid) => !!$spoilersShown[uuid],
ariaLabel: (originalAccount, originalStatus) => {
return (originalStatus.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) => {

View file

@ -1,5 +1,5 @@
<span class="status-author-handle {{isStatusInNotification ? 'status-in-notification' : '' }}"> <span class="status-author-handle {{isStatusInNotification ? 'status-in-notification' : '' }}">
{{'@' + status.account.acct}} {{'@' + originalAccount.acct}}
</span> </span>
<style> <style>
.status-author-handle { .status-author-handle {

View file

@ -1,8 +1,8 @@
<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/{{status.account.id}}" href="/accounts/{{originalAccountId}}"
focus-key="{{focusKey}}" focus-key="{{focusKey}}"
> >
{{status.account.display_name || status.account.username}} {{originalAccount.display_name || originalAccount.username}}
</a> </a>
<style> <style>
.status-author-name { .status-author-name {
@ -35,8 +35,7 @@
<script> <script>
export default { export default {
computed: { computed: {
statusId: (status) => status.id, focusKey: (uuid) => `status-author-name-${uuid}`
focusKey: (statusId) => `status-author-name-${statusId}`
} }
} }
</script> </script>

View file

@ -66,11 +66,11 @@
}, },
store: () => store, store: () => store,
computed: { computed: {
massagedContent: (status, $autoplayGifs) => { massagedContent: (originalStatus, $autoplayGifs) => {
let content = status.content let content = originalStatus.content
// emojify // emojify
if (status.emojis && status.emojis.length) { if (originalStatus.emojis && originalStatus.emojis.length) {
for (let emoji of status.emojis) { for (let emoji of originalStatus.emojis) {
let { shortcode, url, static_url } = emoji let { shortcode, url, static_url } = emoji
let urlToUse = $autoplayGifs ? url : static_url let urlToUse = $autoplayGifs ? url : static_url
let shortcodeWithColons = `:${shortcode}:` let shortcodeWithColons = `:${shortcode}:`
@ -87,8 +87,7 @@
content = `<p>${content}</p>` content = `<p>${content}</p>`
} }
return content return content
}, }
statusId: (status) => status.id
}, },
methods: { methods: {
hydrateContent() { hydrateContent() {
@ -96,30 +95,30 @@
return return
} }
let node = this.refs.node let node = this.refs.node
let status = this.get('status') let originalStatus = this.get('originalStatus')
let statusId = this.get('statusId') let uuid = this.get('uuid')
let count = 0 let count = 0
mark('hydrateContent') mark('hydrateContent')
if (status.tags && status.tags.length) { if (originalStatus.tags && originalStatus.tags.length) {
let anchorTags = node.querySelectorAll('a[class~=hashtag][href^=http]') let anchorTags = node.querySelectorAll('a[class~=hashtag][href^=http]')
for (let tag of status.tags) { for (let tag of originalStatus.tags) {
for (let anchorTag of anchorTags) { for (let anchorTag of anchorTags) {
if (anchorTag.getAttribute('href').endsWith(`/tags/${tag.name}`)) { if (anchorTag.getAttribute('href').endsWith(`/tags/${tag.name}`)) {
anchorTag.setAttribute('href', `/tags/${tag.name}`) anchorTag.setAttribute('href', `/tags/${tag.name}`)
anchorTag.setAttribute('focus-key', `status-content-link-${statusId}-${++count}`) anchorTag.setAttribute('focus-key', `status-content-link-${uuid}-${++count}`)
anchorTag.removeAttribute('target') anchorTag.removeAttribute('target')
anchorTag.removeAttribute('rel') anchorTag.removeAttribute('rel')
} }
} }
} }
} }
if (status.mentions && status.mentions.length) { if (originalStatus.mentions && originalStatus.mentions.length) {
let anchorTags = node.querySelectorAll('a[class~=mention][href^=http]') let anchorTags = node.querySelectorAll('a[class~=mention][href^=http]')
for (let mention of status.mentions) { for (let mention of originalStatus.mentions) {
for (let anchorTag of anchorTags) { for (let anchorTag of anchorTags) {
if (anchorTag.getAttribute('href') === mention.url) { if (anchorTag.getAttribute('href') === mention.url) {
anchorTag.setAttribute('href', `/accounts/${mention.id}`) anchorTag.setAttribute('href', `/accounts/${mention.id}`)
anchorTag.setAttribute('focus-key', `status-content-link-${statusId}-${++count}`) anchorTag.setAttribute('focus-key', `status-content-link-${uuid}-${++count}`)
anchorTag.removeAttribute('target') anchorTag.removeAttribute('target')
anchorTag.removeAttribute('rel') anchorTag.removeAttribute('rel')
} }

View file

@ -1,14 +1,18 @@
<div class="status-details"> <div class="status-details">
<ExternalLink class="status-absolute-date" href="{{status.url}}" showIcon="true"> <ExternalLink class="status-absolute-date" href="{{originalStatus.url}}" showIcon="true">
<time datetime={{createdAtDate}} title="{{formattedDate}}">{{formattedDate}}</time> <time datetime={{createdAtDate}} title="{{formattedDate}}">{{formattedDate}}</time>
</ExternalLink> </ExternalLink>
<a class="status-favs-reblogs" href="/statuses/{{statusId}}/reblogs" aria-label="{{favoritesLabel}}"> <a class="status-favs-reblogs"
href="/statuses/{{originalStatusId}}/reblogs"
aria-label="{{favoritesLabel}}">
<svg> <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" href="/statuses/{{statusId}}/favorites" aria-label="{{reblogsLabel}}"> <a class="status-favs-reblogs"
href="/statuses/{{originalStatusId}}/favorites"
aria-label="{{reblogsLabel}}">
<svg> <svg>
<use xlink:href="#fa-star" /> <use xlink:href="#fa-star" />
</svg> </svg>
@ -91,10 +95,9 @@
export default { export default {
computed: { computed: {
statusId: (status) => status.id, createdAtDate: (originalStatus) => originalStatus.created_at,
createdAtDate: (status) => status.created_at, numReblogs: (originalStatus) => originalStatus.reblogs_count || 0,
numReblogs: (status) => status.reblogs_count || 0, numFavs: (originalStatus) => originalStatus.favourites_count || 0,
numFavs: (status) => status.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

View file

@ -6,9 +6,9 @@
{{#if timelineType === 'pinned'}} {{#if timelineType === 'pinned'}}
Pinned toot Pinned toot
{{else}} {{else}}
<a href="/accounts/{{account.id}}" <a href="/accounts/{{accountId}}"
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
@ -68,9 +68,7 @@
<script> <script>
export default { export default {
computed: { computed: {
statusId: (status) => status && status.id, focusKey: (uuid) => `status-header-${uuid}`,
notificationId: (notification) => notification && notification.id,
focusKey: (statusId, notificationId) => `status-header-${statusId}-${notificationId}`,
icon: (notification, status, timelineType) => { icon: (notification, status, timelineType) => {
if (timelineType === 'pinned') { if (timelineType === 'pinned') {
return '#fa-thumb-tack' return '#fa-thumb-tack'
@ -80,12 +78,6 @@
return '#fa-user-plus' return '#fa-user-plus'
} }
return '#fa-star' return '#fa-star'
},
account: (notification, status) => {
if (notification && notification.account) {
return notification.account
}
return status.account
} }
} }
} }

View file

@ -1,4 +1,4 @@
{{#if status.sensitive || $markMediaAsSensitive}} {{#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}}
@ -12,7 +12,7 @@
</svg> </svg>
</div> </div>
</button> </button>
<MediaAttachments mediaAttachments="{{mediaAttachments}}" sensitive="{{status.sensitive}}"/> <MediaAttachments :mediaAttachments :sensitive />
{{else}} {{else}}
<button type="button" <button type="button"
class="status-sensitive-media-button" class="status-sensitive-media-button"
@ -31,7 +31,7 @@
{{/if}} {{/if}}
</div> </div>
{{else}} {{else}}
<MediaAttachments mediaAttachments="{{mediaAttachments}}" sensitive="{{status.sensitive}}"/> <MediaAttachments :mediaAttachments :sensitive />
{{/if}} {{/if}}
<style> <style>
.status-sensitive-media-container { .status-sensitive-media-container {
@ -140,16 +140,16 @@
}, },
store: () => store, store: () => store,
computed: { computed: {
mediaAttachments: (status) => status.media_attachments, mediaAttachments: (originalStatus) => originalStatus.media_attachments,
sensitiveShown: ($sensitivesShown, contextualStatusId) => !!$sensitivesShown[contextualStatusId], sensitiveShown: ($sensitivesShown, uuid) => !!$sensitivesShown[uuid],
statusId: (status) => status.id, sensitive: (originalStatus, $markMediaAsSensitive) => originalStatus.sensitive || $markMediaAsSensitive,
delegateKey: (statusId) => `sensitive-${statusId}`, delegateKey: (uuid) => `sensitive-${uuid}`,
}, },
methods: { methods: {
onClickSensitiveMediaButton() { onClickSensitiveMediaButton() {
let contextualStatusId = this.get('contextualStatusId') let uuid = this.get('uuid')
let $sensitivesShown = this.store.get('sensitivesShown') || {} let $sensitivesShown = this.store.get('sensitivesShown') || {}
$sensitivesShown[contextualStatusId] = !$sensitivesShown[contextualStatusId] $sensitivesShown[uuid] = !$sensitivesShown[uuid]
this.store.set({'sensitivesShown': $sensitivesShown}) this.store.set({'sensitivesShown': $sensitivesShown})
this.fire('recalculateHeight') this.fire('recalculateHeight')
} }

View file

@ -1,8 +1,11 @@
<a class="status-relative-date {{isStatusInNotification ? 'status-in-notification' : '' }}" <a class="status-relative-date {{isStatusInNotification ? 'status-in-notification' : '' }}"
href="/statuses/{{status.id}}" href="/statuses/{{originalStatusId}}"
focus-key="{{focusKey}}" focus-key="{{focusKey}}"
> >
<time datetime={{createdAtDate}} title="{{relativeDate}}" aria-label="{{relativeDate}} click to show thread">{{relativeDate}}</time> <time datetime={{createdAtDate}} title="{{relativeDate}}"
aria-label="{{relativeDate}} click to show thread">
{{relativeDate}}
</time>
</a> </a>
<style> <style>
.status-relative-date { .status-relative-date {
@ -32,15 +35,14 @@
export default { export default {
computed: { computed: {
createdAtDate: (status) => status.created_at, createdAtDate: (originalStatus) => originalStatus.created_at,
statusId: (status) => status.id,
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: (statusId) => `status-relative-date-${statusId}` focusKey: (uuid) => `status-relative-date-${uuid}`
} }
} }
</script> </script>

View file

@ -1,4 +1,4 @@
<Avatar account={{status.account}} <Avatar account={{originalAccount}}
className="status-sidebar" className="status-sidebar"
size="{{isStatusInOwnThread ? 'medium' : 'small'}}" /> size="{{isStatusInOwnThread ? 'medium' : 'small'}}" />
<style> <style>

View file

@ -1,5 +1,5 @@
<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>{{status.spoiler_text}}</p> <p>{{originalStatus.spoiler_text}}</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}}">
@ -51,15 +51,14 @@
}, },
store: () => store, store: () => store,
computed: { computed: {
spoilerShown: ($spoilersShown, contextualStatusId) => !!$spoilersShown[contextualStatusId], spoilerShown: ($spoilersShown, uuid) => !!$spoilersShown[uuid],
statusId: (status) => status.id, delegateKey: (uuid) => `spoiler-${uuid}`
delegateKey: (statusId) => `spoiler-${statusId}`
}, },
methods: { methods: {
onClickSpoilerButton() { onClickSpoilerButton() {
let contextualStatusId = this.get('contextualStatusId') let uuid = this.get('uuid')
let $spoilersShown = this.store.get('spoilersShown') let $spoilersShown = this.store.get('spoilersShown')
$spoilersShown[contextualStatusId] = !$spoilersShown[contextualStatusId] $spoilersShown[uuid] = !$spoilersShown[uuid]
this.store.set({'spoilersShown': $spoilersShown}) this.store.set({'spoilersShown': $spoilersShown})
this.fire('recalculateHeight') this.fire('recalculateHeight')
} }

View file

@ -65,30 +65,30 @@
store: () => store, store: () => store,
methods: { methods: {
onFavoriteClick() { onFavoriteClick() {
let statusId = this.get('statusId') let originalStatusId = this.get('originalStatusId')
let favorited = this.get('favorited') let favorited = this.get('favorited')
/* no await */ setFavorited(statusId, !favorited) /* no await */ setFavorited(originalStatusId, !favorited)
}, },
onReblogClick() { onReblogClick() {
let statusId = this.get('statusId') let originalStatusId = this.get('originalStatusId')
let reblogged = this.get('reblogged') let reblogged = this.get('reblogged')
/* no await */ setReblogged(statusId, !reblogged) /* no await */ setReblogged(originalStatusId, !reblogged)
}, },
onReplyClick() { onReplyClick() {
let statusId = this.get('statusId') let originalStatusId = this.get('originalStatusId')
goto(`/statuses/${statusId}/reply`) goto(`/statuses/${originalStatusId}/reply`)
}, },
async onOptionsClick() { async onOptionsClick() {
let statusId = this.get('statusId') let originalStatusId = this.get('originalStatusId')
let accountId = this.get('accountId') let originalAccountId = this.get('originalAccountId')
let updateRelationshipPromise = updateProfileAndRelationship(accountId) let updateRelationshipPromise = updateProfileAndRelationship(originalAccountId)
let dialogs = await importDialogs() let dialogs = await importDialogs()
await updateRelationshipPromise await updateRelationshipPromise
dialogs.showStatusOptionsDialog(statusId) dialogs.showStatusOptionsDialog(originalStatusId)
} }
}, },
computed: { computed: {
visibility: (status) => status.visibility, visibility: (originalStatus) => originalStatus.visibility,
reblogLabel: (visibility) => { reblogLabel: (visibility) => {
switch (visibility) { switch (visibility) {
case 'private': case 'private':
@ -112,24 +112,22 @@
reblogDisabled: (visibility) => { reblogDisabled: (visibility) => {
return visibility === 'private' || visibility === 'direct' return visibility === 'private' || visibility === 'direct'
}, },
reblogged: (status, $currentStatusModifications) => { reblogged: (originalStatusId, $currentStatusModifications, originalStatus) => {
if ($currentStatusModifications && status.id in $currentStatusModifications.reblogs) { if ($currentStatusModifications && originalStatusId in $currentStatusModifications.reblogs) {
return $currentStatusModifications.reblogs[status.id] return $currentStatusModifications.reblogs[originalStatusId]
} }
return status.reblogged return originalStatus.reblogged
}, },
favorited: (status, $currentStatusModifications) => { favorited: (originalStatusId, $currentStatusModifications, originalStatus) => {
if ($currentStatusModifications && status.id in $currentStatusModifications.favorites) { if ($currentStatusModifications && originalStatusId in $currentStatusModifications.favorites) {
return $currentStatusModifications.favorites[status.id] return $currentStatusModifications.favorites[originalStatusId]
} }
return status.favourited return originalStatus.favourited
}, },
statusId: (status) => status.id, favoriteKey: (uuid) => `fav-${uuid}`,
accountId: (status) => status.account.id, reblogKey: (uuid) => `reblog-${uuid}`,
favoriteKey: (statusId) => `fav-${statusId}`, replyKey: (uuid) => `reply-${uuid}`,
reblogKey: (statusId) => `reblog-${statusId}`, optionsKey: (uuid) => `options-${uuid}`,
replyKey: (statusId) => `reply-${statusId}`,
optionsKey: (statusId) => `options-${statusId}`,
} }
} }
</script> </script>

View file

@ -244,7 +244,7 @@
if (activeElement) { if (activeElement) {
let focusKey = activeElement.getAttribute('focus-key') let focusKey = activeElement.getAttribute('focus-key')
if (focusKey) { if (focusKey) {
lastFocusedElementSelector = `[focus-key=${focusKey}]` lastFocusedElementSelector = `[focus-key=${JSON.stringify(focusKey)}]`
} }
} }
console.log('saving focus to ', lastFocusedElementSelector) console.log('saving focus to ', lastFocusedElementSelector)