201 lines
		
	
	
		
			No EOL
		
	
	
		
			7.5 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			No EOL
		
	
	
		
			7.5 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <article class="{{className}}"
 | |
|          tabindex="0"
 | |
|          delegate-key="{{delegateKey}}"
 | |
|          focus-key="{{delegateKey}}"
 | |
|          aria-posinset="{{index}}"
 | |
|          aria-setsize="{{length}}"
 | |
|          aria-label="{{ariaLabel}}"
 | |
|          on:recalculateHeight
 | |
|          ref:node >
 | |
|   {{#if showHeader}}
 | |
|     <StatusHeader :notification :notificationId :status :statusId :timelineType
 | |
|                   :account :accountId :uuid :isStatusInNotification />
 | |
|   {{/if}}
 | |
|   <StatusAuthorName :isStatusInNotification :isStatusInOwnThread :originalAccountId
 | |
|                     :originalAccount :uuid />
 | |
|   <StatusAuthorHandle :isStatusInNotification :originalAccount />
 | |
|   {{#if !isStatusInOwnThread}}
 | |
|     <StatusRelativeDate :isStatusInNotification :originalStatus :originalStatusId :uuid />
 | |
|   {{/if}}
 | |
|   <StatusSidebar :isStatusInOwnThread :originalAccount
 | |
|                  :originalAccountId :uuid />
 | |
|   {{#if originalStatus.spoiler_text}}
 | |
|     <StatusSpoiler :isStatusInOwnThread :isStatusInNotification
 | |
|                    :originalStatus :uuid :spoilerShown
 | |
|                    on:recalculateHeight />
 | |
|   {{/if}}
 | |
|   {{#if !originalStatus.spoiler_text || spoilerShown}}
 | |
|     <StatusContent :isStatusInOwnThread :isStatusInNotification
 | |
|                    :originalStatus :uuid />
 | |
|   {{/if}}
 | |
|   {{#if originalStatus.media_attachments && originalStatus.media_attachments.length}}
 | |
|     <StatusMediaAttachments :originalStatus :uuid
 | |
|                             on:recalculateHeight />
 | |
|   {{/if}}
 | |
|   {{#if isStatusInOwnThread}}
 | |
|   <StatusDetails :originalStatus :originalStatusId />
 | |
|   {{/if}}
 | |
|   <StatusToolbar :originalStatus :originalStatusId :originalAccountId
 | |
|                  :isStatusInOwnThread :uuid :visibility />
 | |
| </article>
 | |
| 
 | |
| <style>
 | |
|   .status-article {
 | |
|     cursor: pointer;
 | |
|     max-width: calc(100vw - 40px);
 | |
|     padding: 10px 20px;
 | |
|     display: grid;
 | |
|     grid-template-areas:
 | |
|         "....... header       header        header"
 | |
|         "sidebar author-name  author-handle relative-date"
 | |
|         "sidebar spoiler      spoiler       spoiler"
 | |
|         "sidebar spoiler-btn  spoiler-btn   spoiler-btn"
 | |
|         "sidebar content      content       content"
 | |
|         "media   media        media         media"
 | |
|         "....... toolbar      toolbar       toolbar";
 | |
|     grid-template-columns: min-content minmax(0, max-content) 1fr min-content;
 | |
|   }
 | |
| 
 | |
|   .status-article.status-in-timeline {
 | |
|     width: 560px;
 | |
|     border-bottom: 1px solid var(--main-border);
 | |
|   }
 | |
| 
 | |
|   .status-article.status-direct {
 | |
|     background-color: var(--status-direct-background);
 | |
|   }
 | |
| 
 | |
|   .status-article.status-in-own-thread {
 | |
|     grid-template-areas:
 | |
|       "sidebar     author-name"
 | |
|       "sidebar     author-handle"
 | |
|       "spoiler     spoiler"
 | |
|       "spoiler-btn spoiler-btn"
 | |
|       "content     content"
 | |
|       "media       media"
 | |
|       "details     details"
 | |
|       "toolbar     toolbar";
 | |
|     grid-template-columns: min-content 1fr;
 | |
|   }
 | |
| 
 | |
|   @media (max-width: 767px) {
 | |
|     .status-article {
 | |
|       padding: 10px 10px;
 | |
|       max-width: calc(100vw - 20px);
 | |
|     }
 | |
|     .status-article.status-in-timeline {
 | |
|       width: 580px;
 | |
|     }
 | |
|   }
 | |
| </style>
 | |
| <script>
 | |
|   import StatusSidebar from './StatusSidebar.html'
 | |
|   import StatusHeader from './StatusHeader.html'
 | |
|   import StatusAuthorName from './StatusAuthorName.html'
 | |
|   import StatusAuthorHandle from './StatusAuthorHandle.html'
 | |
|   import StatusRelativeDate from './StatusRelativeDate.html'
 | |
|   import StatusDetails from './StatusDetails.html'
 | |
|   import StatusToolbar from './StatusToolbar.html'
 | |
|   import StatusMediaAttachments from './StatusMediaAttachments.html'
 | |
|   import StatusContent from './StatusContent.html'
 | |
|   import StatusSpoiler from './StatusSpoiler.html'
 | |
|   import { store } from '../../_store/store'
 | |
|   import { goto } from 'sapper/runtime.js'
 | |
|   import { registerClickDelegate, unregisterClickDelegate } from '../../_utils/delegate'
 | |
|   import { classname } from '../../_utils/classname'
 | |
|   import { restoreFocus } from '../../_utils/restoreFocus'
 | |
| 
 | |
|   export default {
 | |
|     oncreate() {
 | |
|       let delegateKey = this.get('delegateKey')
 | |
|       if (!this.get('isStatusInOwnThread')) {
 | |
|         // the whole <article> is clickable in this case
 | |
|         registerClickDelegate(delegateKey, (e) => this.onClickOrKeydown(e))
 | |
|       }
 | |
|       let focusSelector = this.get('focusSelector')
 | |
|       if (this.refs.node && focusSelector &&
 | |
|           this.store.getForCurrentTimeline('shouldRestoreFocus')) {
 | |
|         restoreFocus(this.refs.node, focusSelector)
 | |
|       }
 | |
|     },
 | |
|     ondestroy() {
 | |
|       let delegateKey = this.get('delegateKey')
 | |
|       if (!this.get('isStatusInOwnThread')) {
 | |
|         unregisterClickDelegate(delegateKey)
 | |
|       }
 | |
|     },
 | |
|     components: {
 | |
|       StatusSidebar,
 | |
|       StatusHeader,
 | |
|       StatusAuthorName,
 | |
|       StatusAuthorHandle,
 | |
|       StatusRelativeDate,
 | |
|       StatusDetails,
 | |
|       StatusToolbar,
 | |
|       StatusMediaAttachments,
 | |
|       StatusContent,
 | |
|       StatusSpoiler
 | |
|     },
 | |
|     store: () => store,
 | |
|     methods: {
 | |
|       onClickOrKeydown(e) {
 | |
|         let { type, keyCode } = e
 | |
|         let { localName, parentElement } = e.target
 | |
| 
 | |
|         if ((type === 'click' || (type === 'keydown' && keyCode === 13)) &&
 | |
|             localName !== 'a' &&
 | |
|             localName !== 'button' &&
 | |
|             parentElement.localName !== 'a' &&
 | |
|             parentElement.localName !== 'button' &&
 | |
|             parentElement.parentElement.localName !== 'a' &&
 | |
|             parentElement.parentElement.localName !== 'button') {
 | |
|           e.preventDefault()
 | |
|           e.stopPropagation()
 | |
|           goto(`/statuses/${this.get('originalStatusId')}`)
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     computed: {
 | |
|       originalStatus: (status) => status.reblog ? status.reblog : status,
 | |
|       originalStatusId: (originalStatus) => originalStatus.id,
 | |
|       statusId: (status) => status.id,
 | |
|       notificationId: (notification) => notification && notification.id,
 | |
|       account: (notification, status) => {
 | |
|         return (notification && notification.account) || status.account
 | |
|       },
 | |
|       accountId: (account) => account.id,
 | |
|       originalAccount: (originalStatus) => originalStatus.account,
 | |
|       originalAccountId: (originalAccount) => originalAccount.id,
 | |
|       visibility: (originalStatus) => originalStatus.visibility,
 | |
|       uuid: ($currentInstance, timelineType, timelineValue, notificationId, statusId) => {
 | |
|         return `${$currentInstance}/${timelineType}/${timelineValue}/${notificationId || ''}/${statusId}`
 | |
|       },
 | |
|       delegateKey: (uuid) => `status-${uuid}`,
 | |
|       isStatusInOwnThread: (timelineType, timelineValue, originalStatusId) => {
 | |
|         return (timelineType === 'status' || timelineType === 'reply') && timelineValue === originalStatusId
 | |
|       },
 | |
|       isStatusInNotification: (originalStatusId, notification) => {
 | |
|         return notification && notification.status &&
 | |
|           notification.type !== 'mention' && notification.status.id === originalStatusId
 | |
|       },
 | |
|       spoilerShown: ($spoilersShown, uuid) => !!$spoilersShown[uuid],
 | |
|       ariaLabel: (originalAccount, originalStatus, visibility) => {
 | |
|         return (visibility === 'direct' ? 'Direct message' : 'Status') +
 | |
|           ` by ${originalAccount.display_name || originalAccount.username}`
 | |
|       },
 | |
|       showHeader: (notification, status, timelineType) => {
 | |
|         return (notification && (notification.type === 'reblog' || notification.type === 'favourite'))
 | |
|           || status.reblog
 | |
|           || timelineType === 'pinned'
 | |
|       },
 | |
|       className: (visibility, timelineType, isStatusInOwnThread) => {
 | |
|         return classname(
 | |
|           'status-article',
 | |
|           visibility === 'direct' && 'status-direct',
 | |
|           timelineType !== 'search' && 'status-in-timeline',
 | |
|           isStatusInOwnThread && 'status-in-own-thread'
 | |
|         )
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| </script> |