add status context
This commit is contained in:
parent
8b282de973
commit
6b2f16f3bf
|
@ -17,5 +17,6 @@ module.exports = [
|
||||||
{id:'fa-lock', src:'node_modules/font-awesome-svg-png/white/svg/lock.svg', title: 'Locked'},
|
{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-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-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) {
|
async function addStatuses(instanceName, timelineName, newStatuses) {
|
||||||
|
console.log('addStatuses, length:', newStatuses.length)
|
||||||
|
debugger
|
||||||
mark('addStatuses')
|
mark('addStatuses')
|
||||||
let newStatusIds = newStatuses.map(status => status.id)
|
let newStatusIds = newStatuses.map(status => status.id)
|
||||||
let oldStatusIds = store.getForTimeline(instanceName, timelineName, 'statusIds') || []
|
let oldStatusIds = store.getForTimeline(instanceName, timelineName, 'statusIds') || []
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<:Window bind:online />
|
<:Window bind:online />
|
||||||
<Nav :page :dynamicPage :dynamicHref :dynamicIcon :dynamicLabel/>
|
<Nav :page :dynamicPage :dynamicHref :dynamicIcon :dynamicLabel />
|
||||||
|
|
||||||
{{#if virtual}}
|
{{#if virtual}}
|
||||||
<VirtualListContainer realm="{{$currentInstance + '/' + virtualRealm}}">
|
<VirtualListContainer realm="{{$currentInstance + '/' + virtualRealm}}">
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<span class="status-author-handle">
|
<span class="status-author-handle">
|
||||||
{{'@' + originalAccount.acct}}
|
{{'@' + originalAccount.acct}}
|
||||||
</span>
|
</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>
|
<time datetime={{createdAtDate}} title="{{relativeDate}}">{{relativeDate}}</time>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -34,16 +34,25 @@
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
makeProps: ($currentInstance) => (statusId) => database.getStatus($currentInstance, statusId),
|
makeProps: ($currentInstance) => (statusId) => database.getStatus($currentInstance, statusId),
|
||||||
label: (timeline, $currentInstance) => {
|
label: (timeline, $currentInstance, timelineType, timelineValue) => {
|
||||||
if (timelines[timeline]) {
|
if (timelines[timeline]) {
|
||||||
`${timelines[timeline].label} timeline for ${$currentInstance}`
|
return `${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}`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
store: () => store,
|
||||||
|
@ -58,7 +67,9 @@
|
||||||
initializeTimeline()
|
initializeTimeline()
|
||||||
},
|
},
|
||||||
onScrollToBottom() {
|
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
|
return
|
||||||
}
|
}
|
||||||
fetchStatusesOnScrollToBottom()
|
fetchStatusesOnScrollToBottom()
|
||||||
|
|
|
@ -30,7 +30,7 @@ export function instanceComputations(store) {
|
||||||
store.compute(
|
store.compute(
|
||||||
'accessToken',
|
'accessToken',
|
||||||
['currentInstanceData'],
|
['currentInstanceData'],
|
||||||
(currentInstanceData) => currentInstanceData.access_token
|
(currentInstanceData) => currentInstanceData && currentInstanceData.access_token
|
||||||
)
|
)
|
||||||
|
|
||||||
store.compute(
|
store.compute(
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { updateVerifyCredentialsForInstance } from '../settings/instances/_actio
|
||||||
|
|
||||||
export function observers(store) {
|
export function observers(store) {
|
||||||
store.observe('currentInstance', (currentInstance) => {
|
store.observe('currentInstance', (currentInstance) => {
|
||||||
updateVerifyCredentialsForInstance(currentInstance)
|
if (currentInstance) {
|
||||||
|
updateVerifyCredentialsForInstance(currentInstance)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
|
@ -18,6 +18,7 @@ export function mergeArrays(leftArray, rightArray) {
|
||||||
let left = leftArray[leftIndex]
|
let left = leftArray[leftIndex]
|
||||||
let right = rightArray[rightIndex]
|
let right = rightArray[rightIndex]
|
||||||
if (right === left) {
|
if (right === left) {
|
||||||
|
merged.push(left)
|
||||||
rightIndex++
|
rightIndex++
|
||||||
leftIndex++
|
leftIndex++
|
||||||
} else if (parseInt(right, 10) > parseInt(left, 10)) {
|
} else if (parseInt(right, 10) > parseInt(left, 10)) {
|
||||||
|
|
|
@ -11,6 +11,8 @@ function getTimelineUrlPath(timeline) {
|
||||||
}
|
}
|
||||||
if (timeline.startsWith('tag/')) {
|
if (timeline.startsWith('tag/')) {
|
||||||
return 'timelines/tag'
|
return 'timelines/tag'
|
||||||
|
} else if (timeline.startsWith('status/')) {
|
||||||
|
return 'statuses'
|
||||||
} else if (timeline.startsWith('account/')) {
|
} else if (timeline.startsWith('account/')) {
|
||||||
return 'accounts'
|
return 'accounts'
|
||||||
}
|
}
|
||||||
|
@ -22,6 +24,8 @@ export function getTimeline(instanceName, accessToken, timeline, maxId, since) {
|
||||||
|
|
||||||
if (timeline.startsWith('tag/')) {
|
if (timeline.startsWith('tag/')) {
|
||||||
url += '/' + timeline.split('/').slice(-1)[0]
|
url += '/' + timeline.split('/').slice(-1)[0]
|
||||||
|
} else if (timeline.startsWith('status/')) {
|
||||||
|
url += '/' + timeline.split('/').slice(-1)[0] + '/context'
|
||||||
} else if (timeline.startsWith('account/')) {
|
} else if (timeline.startsWith('account/')) {
|
||||||
url += '/' + timeline.split('/').slice(-1)[0] +'/statuses'
|
url += '/' + timeline.split('/').slice(-1)[0] +'/statuses'
|
||||||
}
|
}
|
||||||
|
@ -41,6 +45,17 @@ export function getTimeline(instanceName, accessToken, timeline, maxId, since) {
|
||||||
|
|
||||||
url += '?' + paramsString(params)
|
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, {
|
return get(url, {
|
||||||
'Authorization': `Bearer ${accessToken}`
|
'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-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-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-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><!-- end insert svg here -->
|
||||||
</svg>
|
</svg>
|
||||||
<!-- The application will be rendered inside this element,
|
<!-- The application will be rendered inside this element,
|
||||||
|
|
Loading…
Reference in a new issue