diff --git a/bin/svgs.js b/bin/svgs.js index 13300fde..2b2ffbde 100644 --- a/bin/svgs.js +++ b/bin/svgs.js @@ -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'}, ] \ No newline at end of file diff --git a/routes/_actions/timeline.js b/routes/_actions/timeline.js index 7282f4f4..c8deb8ed 100644 --- a/routes/_actions/timeline.js +++ b/routes/_actions/timeline.js @@ -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') || [] diff --git a/routes/_components/Layout.html b/routes/_components/Layout.html index e68639b0..238af527 100644 --- a/routes/_components/Layout.html +++ b/routes/_components/Layout.html @@ -1,5 +1,5 @@ <:Window bind:online /> - + {{#if virtual}} diff --git a/routes/_components/status/Status.html b/routes/_components/status/Status.html index 54687ddf..4847e5ed 100644 --- a/routes/_components/status/Status.html +++ b/routes/_components/status/Status.html @@ -20,7 +20,7 @@ {{'@' + originalAccount.acct}} - + {{relativeDate}} diff --git a/routes/_components/timeline/Timeline.html b/routes/_components/timeline/Timeline.html index 627e38ef..61c30bd3 100644 --- a/routes/_components/timeline/Timeline.html +++ b/routes/_components/timeline/Timeline.html @@ -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() diff --git a/routes/_store/instanceComputations.js b/routes/_store/instanceComputations.js index 55c350d7..831a9ebe 100644 --- a/routes/_store/instanceComputations.js +++ b/routes/_store/instanceComputations.js @@ -30,7 +30,7 @@ export function instanceComputations(store) { store.compute( 'accessToken', ['currentInstanceData'], - (currentInstanceData) => currentInstanceData.access_token + (currentInstanceData) => currentInstanceData && currentInstanceData.access_token ) store.compute( diff --git a/routes/_store/obsevers.js b/routes/_store/obsevers.js index 4309e3bd..7d2af2bf 100644 --- a/routes/_store/obsevers.js +++ b/routes/_store/obsevers.js @@ -2,6 +2,8 @@ import { updateVerifyCredentialsForInstance } from '../settings/instances/_actio export function observers(store) { store.observe('currentInstance', (currentInstance) => { - updateVerifyCredentialsForInstance(currentInstance) + if (currentInstance) { + updateVerifyCredentialsForInstance(currentInstance) + } }) } \ No newline at end of file diff --git a/routes/_utils/arrays.js b/routes/_utils/arrays.js index f29a0df7..c63d27a0 100644 --- a/routes/_utils/arrays.js +++ b/routes/_utils/arrays.js @@ -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)) { diff --git a/routes/_utils/mastodon/timelines.js b/routes/_utils/mastodon/timelines.js index 0e307372..d6eae0d8 100644 --- a/routes/_utils/mastodon/timelines.js +++ b/routes/_utils/mastodon/timelines.js @@ -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}` }) diff --git a/routes/statuses/[statusId].html b/routes/statuses/[statusId].html new file mode 100644 index 00000000..2477029d --- /dev/null +++ b/routes/statuses/[statusId].html @@ -0,0 +1,43 @@ +<:Head> + Pinafore + + + + {{#if $isUserLoggedIn}} + + + {{else}} + + + Status + + A status thread will appear here when logged in. + + + {{/if}} + + \ No newline at end of file diff --git a/templates/2xx.html b/templates/2xx.html index fb59b732..736daa2e 100644 --- a/templates/2xx.html +++ b/templates/2xx.html @@ -83,6 +83,7 @@ body.offline,body.theme-hotpants.offline,body.theme-majesty.offline,body.theme-o Sealed Envelope Stop Following Follow +Statuses
A status thread will appear here when logged in.