add status context
This commit is contained in:
		
							parent
							
								
									8b282de973
								
							
						
					
					
						commit
						6b2f16f3bf
					
				
					 11 changed files with 90 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -17,5 +17,6 @@ module.exports = [
 | 
			
		|||
  {id:'fa-lock', src:'node_modules/font-awesome-svg-png/white/svg/lock.svg', title: 'Locked'},
 | 
			
		||||
  {id:'fa-envelope', src:'node_modules/font-awesome-svg-png/white/svg/envelope.svg', title: 'Sealed Envelope'},
 | 
			
		||||
  {id:'fa-user-times', src:'node_modules/font-awesome-svg-png/white/svg/user-times.svg', title: 'Stop Following'},
 | 
			
		||||
  {id:'fa-user-plus', src:'node_modules/font-awesome-svg-png/white/svg/user-plus.svg', title: 'Follow'}
 | 
			
		||||
  {id:'fa-user-plus', src:'node_modules/font-awesome-svg-png/white/svg/user-plus.svg', title: 'Follow'},
 | 
			
		||||
  {id:'fa-comments', src:'node_modules/font-awesome-svg-png/white/svg/comments.svg', title: 'Statuses'},
 | 
			
		||||
]
 | 
			
		||||
| 
						 | 
				
			
			@ -31,6 +31,8 @@ async function fetchStatuses(instanceName, accessToken, timelineName, lastStatus
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
async function addStatuses(instanceName, timelineName, newStatuses) {
 | 
			
		||||
  console.log('addStatuses, length:', newStatuses.length)
 | 
			
		||||
  debugger
 | 
			
		||||
  mark('addStatuses')
 | 
			
		||||
  let newStatusIds = newStatuses.map(status => status.id)
 | 
			
		||||
  let oldStatusIds = store.getForTimeline(instanceName, timelineName, 'statusIds') || []
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,7 @@
 | 
			
		|||
    <span class="status-author-handle">
 | 
			
		||||
      {{'@' + originalAccount.acct}}
 | 
			
		||||
    </span>
 | 
			
		||||
    <a class="status-author-date" rel="noopener" target="_blank" href="{{originalStatus.uri}}">
 | 
			
		||||
    <a class="status-author-date" href="/statuses/{{originalStatus.id}}">
 | 
			
		||||
      <time datetime={{createdAtDate}} title="{{relativeDate}}">{{relativeDate}}</time>
 | 
			
		||||
    </a>
 | 
			
		||||
  </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,16 +34,25 @@
 | 
			
		|||
    }),
 | 
			
		||||
    computed: {
 | 
			
		||||
      makeProps: ($currentInstance) => (statusId) => database.getStatus($currentInstance, statusId),
 | 
			
		||||
      label: (timeline, $currentInstance) => {
 | 
			
		||||
      label: (timeline, $currentInstance, timelineType, timelineValue) => {
 | 
			
		||||
        if (timelines[timeline]) {
 | 
			
		||||
          `${timelines[timeline].label} timeline for ${$currentInstance}`
 | 
			
		||||
        } else if (timeline.startsWith('tag/')) {
 | 
			
		||||
          let tag = timeline.split('/').slice(-1)[0]
 | 
			
		||||
          return `#${tag} timeline for ${$currentInstance}`
 | 
			
		||||
        } else if (timeline.startsWith('account/')) {
 | 
			
		||||
          let account = timeline.split('/').slice(-1)[0]
 | 
			
		||||
          return `Account #${account} on ${$currentInstance}`
 | 
			
		||||
          return `${timelines[timeline].label} timeline for ${$currentInstance}`
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        switch (timelineType) {
 | 
			
		||||
          case 'tag':
 | 
			
		||||
            return `#${timelineValue} timeline for ${$currentInstance}`
 | 
			
		||||
          case 'status':
 | 
			
		||||
            return 'Status context'
 | 
			
		||||
          case 'account':
 | 
			
		||||
            return `Account #${timelineValue} on ${$currentInstance}`
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      timelineType: (timeline) => {
 | 
			
		||||
        return timeline.split('/')[0]
 | 
			
		||||
      },
 | 
			
		||||
      timelineValue: (timeline) => {
 | 
			
		||||
        return timeline.split('/').slice(-1)[0]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    store: () => store,
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +67,9 @@
 | 
			
		|||
        initializeTimeline()
 | 
			
		||||
      },
 | 
			
		||||
      onScrollToBottom() {
 | 
			
		||||
        if (!this.store.get('initialized') || this.store.get('runningUpdate')) {
 | 
			
		||||
        if (!this.store.get('initialized') ||
 | 
			
		||||
            this.store.get('runningUpdate') ||
 | 
			
		||||
            this.get('timelineType') === 'status') { // for status contexts, we've already fetched the whole thread
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
        fetchStatusesOnScrollToBottom()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ export function instanceComputations(store) {
 | 
			
		|||
  store.compute(
 | 
			
		||||
    'accessToken',
 | 
			
		||||
    ['currentInstanceData'],
 | 
			
		||||
    (currentInstanceData) => currentInstanceData.access_token
 | 
			
		||||
    (currentInstanceData) => currentInstanceData && currentInstanceData.access_token
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  store.compute(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,8 @@ import { updateVerifyCredentialsForInstance } from '../settings/instances/_actio
 | 
			
		|||
 | 
			
		||||
export function observers(store) {
 | 
			
		||||
  store.observe('currentInstance', (currentInstance) => {
 | 
			
		||||
    if (currentInstance) {
 | 
			
		||||
      updateVerifyCredentialsForInstance(currentInstance)
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -18,6 +18,7 @@ export function mergeArrays(leftArray, rightArray) {
 | 
			
		|||
    let left = leftArray[leftIndex]
 | 
			
		||||
    let right = rightArray[rightIndex]
 | 
			
		||||
    if (right === left) {
 | 
			
		||||
      merged.push(left)
 | 
			
		||||
      rightIndex++
 | 
			
		||||
      leftIndex++
 | 
			
		||||
    } else if (parseInt(right, 10) > parseInt(left, 10)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,8 @@ function getTimelineUrlPath(timeline) {
 | 
			
		|||
  }
 | 
			
		||||
  if (timeline.startsWith('tag/')) {
 | 
			
		||||
    return 'timelines/tag'
 | 
			
		||||
  } else if (timeline.startsWith('status/')) {
 | 
			
		||||
    return 'statuses'
 | 
			
		||||
  } else if (timeline.startsWith('account/')) {
 | 
			
		||||
    return 'accounts'
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +24,8 @@ export function getTimeline(instanceName, accessToken, timeline, maxId, since) {
 | 
			
		|||
 | 
			
		||||
  if (timeline.startsWith('tag/')) {
 | 
			
		||||
    url += '/' + timeline.split('/').slice(-1)[0]
 | 
			
		||||
  } else if (timeline.startsWith('status/')) {
 | 
			
		||||
    url += '/' + timeline.split('/').slice(-1)[0] + '/context'
 | 
			
		||||
  } else if (timeline.startsWith('account/')) {
 | 
			
		||||
    url += '/' + timeline.split('/').slice(-1)[0] +'/statuses'
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +45,17 @@ export function getTimeline(instanceName, accessToken, timeline, maxId, since) {
 | 
			
		|||
 | 
			
		||||
  url += '?' + paramsString(params)
 | 
			
		||||
 | 
			
		||||
  if (timeline.startsWith('status/')) {
 | 
			
		||||
    // special case - this is a list of descendents and ancestors
 | 
			
		||||
    let statusUrl = `${basename(instanceName)}/api/v1/statuses/${timeline.split('/').slice(-1)[0]}}`
 | 
			
		||||
    return Promise.all([
 | 
			
		||||
      get(url, {'Authorization': `Bearer ${accessToken}`}),
 | 
			
		||||
      get(statusUrl, {'Authorization': `Bearer ${accessToken}`})
 | 
			
		||||
    ]).then(res => {
 | 
			
		||||
      return [].concat(res[0].ancestors).concat([res[1]]).concat(res[0].descendants)
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return get(url, {
 | 
			
		||||
    'Authorization': `Bearer ${accessToken}`
 | 
			
		||||
  })
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										43
									
								
								routes/statuses/[statusId].html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								routes/statuses/[statusId].html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
<:Head>
 | 
			
		||||
  <title>Pinafore</title>
 | 
			
		||||
</:Head>
 | 
			
		||||
 | 
			
		||||
<Layout page='statuses'
 | 
			
		||||
        virtual="true"
 | 
			
		||||
        virtualRealm='status/{{params.statusId}}'
 | 
			
		||||
        dynamicPage="Status"
 | 
			
		||||
        dynamicHref="/statuses/{{params.statusId}}"
 | 
			
		||||
        dynamicLabel="Status"
 | 
			
		||||
        dynamicIcon="#fa-comments" >
 | 
			
		||||
  {{#if $isUserLoggedIn}}
 | 
			
		||||
  <DynamicPageBanner title="Status"/>
 | 
			
		||||
  <LazyTimeline timeline='status/{{params.statusId}}' />
 | 
			
		||||
  {{else}}
 | 
			
		||||
  <HiddenFromSSR>
 | 
			
		||||
    <FreeTextLayout>
 | 
			
		||||
      <h1>Status</h1>
 | 
			
		||||
 | 
			
		||||
      <p>A status thread will appear here when logged in.</p>
 | 
			
		||||
    </FreeTextLayout>
 | 
			
		||||
  </HiddenFromSSR>
 | 
			
		||||
  {{/if}}
 | 
			
		||||
</Layout>
 | 
			
		||||
<script>
 | 
			
		||||
  import Layout from '../_components/Layout.html'
 | 
			
		||||
  import LazyTimeline from '../_components/timeline/LazyTimeline.html'
 | 
			
		||||
  import FreeTextLayout from '../_components/FreeTextLayout.html'
 | 
			
		||||
  import { store } from '../_store/store.js'
 | 
			
		||||
  import HiddenFromSSR from '../_components/HiddenFromSSR'
 | 
			
		||||
  import DynamicPageBanner from '../_components/DynamicPageBanner.html'
 | 
			
		||||
 | 
			
		||||
  export default {
 | 
			
		||||
    store: () => store,
 | 
			
		||||
    components: {
 | 
			
		||||
      Layout,
 | 
			
		||||
      LazyTimeline,
 | 
			
		||||
      FreeTextLayout,
 | 
			
		||||
      HiddenFromSSR,
 | 
			
		||||
      DynamicPageBanner
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +83,7 @@ body.offline,body.theme-hotpants.offline,body.theme-majesty.offline,body.theme-o
 | 
			
		|||
<symbol id="fa-envelope" viewBox="0 0 1792 1792"><title>Sealed Envelope</title><path d="M1792 710v794q0 66-47 113t-113 47H160q-66 0-113-47T0 1504V710q44 49 101 87 362 246 497 345 57 42 92.5 65.5t94.5 48 110 24.5h2q51 0 110-24.5t94.5-48 92.5-65.5q170-123 498-345 57-39 100-87zm0-294q0 79-49 151t-122 123q-376 261-468 325-10 7-42.5 30.5t-54 38-52 32.5-57.5 27-50 9h-2q-23 0-50-9t-57.5-27-52-32.5-54-38T639 1015q-91-64-262-182.5T172 690q-62-42-117-115.5T0 438q0-78 41.5-130T160 256h1472q65 0 112.5 47t47.5 113z"></path></symbol>
 | 
			
		||||
<symbol id="fa-user-times" viewBox="0 0 2048 1792"><title>Stop Following</title><path d="M704 896q-159 0-271.5-112.5T320 512t112.5-271.5T704 128t271.5 112.5T1088 512 975.5 783.5 704 896zm1077 320l249 249q9 9 9 23 0 13-9 22l-136 136q-9 9-22 9-14 0-23-9l-249-249-249 249q-9 9-23 9-13 0-22-9l-136-136q-9-9-9-22 0-14 9-23l249-249-249-249q-9-9-9-23 0-13 9-22l136-136q9-9 22-9 14 0 23 9l249 249 249-249q9-9 23-9 13 0 22 9l136 136q9 9 9 22 0 14-9 23zm-498 0l-181 181q-37 37-37 91 0 53 37 90l83 83q-21 3-44 3H267q-121 0-194-69T0 1405q0-53 3.5-103.5t14-109T44 1084t43-97.5 62-81 85.5-53.5T346 832q19 0 39 17 154 122 319 122t319-122q20-17 39-17 28 0 57 6-28 27-41 50t-13 56q0 54 37 91z"></path></symbol>
 | 
			
		||||
<symbol id="fa-user-plus" viewBox="0 0 2048 1792"><title>Follow</title><path d="M704 896q-159 0-271.5-112.5T320 512t112.5-271.5T704 128t271.5 112.5T1088 512 975.5 783.5 704 896zm960 128h352q13 0 22.5 9.5t9.5 22.5v192q0 13-9.5 22.5t-22.5 9.5h-352v352q0 13-9.5 22.5t-22.5 9.5h-192q-13 0-22.5-9.5t-9.5-22.5v-352h-352q-13 0-22.5-9.5t-9.5-22.5v-192q0-13 9.5-22.5t22.5-9.5h352V672q0-13 9.5-22.5t22.5-9.5h192q13 0 22.5 9.5t9.5 22.5v352zm-736 224q0 52 38 90t90 38h256v238q-68 50-171 50H267q-121 0-194-69T0 1405q0-53 3.5-103.5t14-109T44 1084t43-97.5 62-81 85.5-53.5T346 832q19 0 39 17 79 61 154.5 91.5T704 971t164.5-30.5T1023 849q20-17 39-17 132 0 217 96h-223q-52 0-90 38t-38 90v192z"></path></symbol>
 | 
			
		||||
<symbol id="fa-comments" viewBox="0 0 1792 1792"><title>Statuses</title><path d="M1408 768q0 139-94 257t-256.5 186.5T704 1280q-86 0-176-16-124 88-278 128-36 9-86 16h-3q-11 0-20.5-8t-11.5-21q-1-3-1-6.5t.5-6.5 2-6l2.5-5 3.5-5.5 4-5 4.5-5 4-4.5q5-6 23-25t26-29.5 22.5-29 25-38.5 20.5-44q-124-72-195-177T0 768q0-139 94-257t256.5-186.5T704 256t353.5 68.5T1314 511t94 257zm384 256q0 120-71 224.5T1526 1425q10 24 20.5 44t25 38.5 22.5 29 26 29.5 23 25q1 1 4 4.5t4.5 5 4 5 3.5 5.5l2.5 5 2 6 .5 6.5-1 6.5q-3 14-13 22t-22 7q-50-7-86-16-154-40-278-128-90 16-176 16-271 0-472-132 58 4 88 4 161 0 309-45t264-129q125-92 192-212t67-254q0-77-23-152 129 71 204 178t75 230z"></path></symbol>
 | 
			
		||||
</svg><!-- end insert svg here -->
 | 
			
		||||
  </svg>
 | 
			
		||||
	<!-- The application will be rendered inside this element,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue