diff --git a/routes/_components/Layout.html b/routes/_components/Layout.html
index 59ea249..6c0fad4 100644
--- a/routes/_components/Layout.html
+++ b/routes/_components/Layout.html
@@ -1,5 +1,5 @@
<:Window bind:innerHeight />
-
+
+
{{{status.content}}}
{{/if}}
@@ -286,6 +286,9 @@
const relativeFormat = new IntlRelativeFormat('en-US');
export default {
+ oncreate() {
+ this.hydrateHtml()
+ },
components: {
Avatar,
Media,
@@ -306,11 +309,26 @@
methods: {
onClickSpoilerButton() {
this.set({spoilerShown: !this.get('spoilerShown')})
+ this.hydrateHtml()
this.fire('recalculateHeight')
},
onClickSensitiveMediaButton() {
this.set({sensitiveShown: !this.get('sensitiveShown')})
this.fire('recalculateHeight')
+ },
+ hydrateHtml() {
+ let status = this.get('originalStatus')
+ if (status.tags && status.tags.length && this.refs.contentNode) {
+ let anchorTags = this.refs.contentNode.querySelectorAll('a[rel=tag]')
+ for (let tag of status.tags) {
+ let {name, url} = tag
+ for (let anchorTag of anchorTags) {
+ if (anchorTag.getAttribute('href') === url) {
+ anchorTag.setAttribute('href', `/tags/${name}`)
+ }
+ }
+ }
+ }
}
}
}
diff --git a/routes/_components/Timeline.html b/routes/_components/Timeline.html
index 6774302..76d3118 100644
--- a/routes/_components/Timeline.html
+++ b/routes/_components/Timeline.html
@@ -52,7 +52,14 @@
key: status.id
})),
lastStatusId: (statuses) => statuses.length && statuses[statuses.length - 1].id,
- label: (timeline, $currentInstance) => `${timelines[timeline].label} timeline for ${$currentInstance}`
+ label: (timeline, $currentInstance) => {
+ 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}`
+ }
+ }
},
store: () => store,
components: {
diff --git a/routes/_utils/mastodon/timelines.js b/routes/_utils/mastodon/timelines.js
index eae4666..f37ca1c 100644
--- a/routes/_utils/mastodon/timelines.js
+++ b/routes/_utils/mastodon/timelines.js
@@ -1,10 +1,26 @@
import { get, paramsString } from '../ajax'
import { basename } from './utils'
+function getTimelineUrlName(timeline) {
+ switch (timeline) {
+ case 'local':
+ case 'federated':
+ return 'public'
+ case 'home':
+ return 'home'
+ default:
+ return 'tag'
+ }
+}
+
export function getTimeline(instanceName, accessToken, timeline, maxId, since) {
- let timelineUrlName = timeline === 'local' || timeline === 'federated' ? 'public' : timeline
+ let timelineUrlName = getTimelineUrlName(timeline)
let url = `${basename(instanceName)}/api/v1/timelines/${timelineUrlName}`
+ if (timeline.startsWith('tag/')) {
+ url += '/' + timeline.split('/').slice(-1)[0]
+ }
+
let params = {}
if (since) {
params.since = since
diff --git a/routes/tags/[tagName].html b/routes/tags/[tagName].html
new file mode 100644
index 0000000..e3e365f
--- /dev/null
+++ b/routes/tags/[tagName].html
@@ -0,0 +1,66 @@
+<:Head>
+
Pinafore – #{{params.tagName}}
+
+
+
+ {{#if $isUserLoggedIn}}
+
+
{{'#' + params.tagName}}
+
Back
+
+
+ {{else}}
+
+
+ #{{params.tagName}}
+
+ A hashtag timeline will appear here when logged in.
+
+
+ {{/if}}
+
+
+
\ No newline at end of file
diff --git a/templates/2xx.html b/templates/2xx.html
index c5b0303..16bc5bb 100644
--- a/templates/2xx.html
+++ b/templates/2xx.html
@@ -134,6 +134,12 @@ body.offline,body.theme-hotpants.offline,body.theme-majesty.offline,body.theme-o
+
+ Hashtag
+
+
+
+