Use bus and constants icons

This commit is contained in:
May B. 2019-05-31 11:03:25 +02:00
parent 95fa082b94
commit 271dd81d9e
10 changed files with 211 additions and 95 deletions

View File

@ -0,0 +1,14 @@
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
export interface IEmit {
$emit: (name: string, arg: any) => void
}
@Component
export default class LocalBusMixin<O, B extends O & IEmit> extends Vue {
@Prop(Object)
readonly bus!: B
}

View File

@ -8,16 +8,20 @@ a.account(target="_blank" :href="account.url")
<script lang="ts"> <script lang="ts">
import { Component, Mixins, Prop } from 'vue-property-decorator' import { Component, Mixins, Prop } from 'vue-property-decorator'
import ShowMediaMixin from '@/components/ShowMediaMixin' import BusMixin from './BusMixin'
import { ParseEmojisMixin } from './ParseEmojisMixin' import { ParseEmojisMixin } from './ParseEmojisMixin'
import { Account as IAccount } from './Types' import { Account as IAccount } from './Types'
@Component @Component
export default class Account extends Mixins(ParseEmojisMixin, ShowMediaMixin) { export default class Account extends Mixins(ParseEmojisMixin, BusMixin) {
@Prop(Object) @Prop(Object)
readonly account!: IAccount readonly account!: IAccount
get showMedia() {
return this.bus.showMedia
}
avatarStyle(avatar: string) { avatarStyle(avatar: string) {
return { return {
'background-image': `url(${avatar})` 'background-image': `url(${avatar})`

View File

@ -0,0 +1,13 @@
import { Component } from 'vue-property-decorator'
import LocalBusMixin from '@/components/LocalBusMixin'
import { BusOptions } from './Types'
@Component
export default class BusMixin extends LocalBusMixin<BusOptions, any> { }
export const LocalEvents = {
Mark: 'mark',
Vote: 'vote',
Context: 'context'
}

View File

@ -4,34 +4,34 @@
.header(v-if="hasNotifications") Accueil .header(v-if="hasNotifications") Accueil
success-loadable.list(:loadable="statues") success-loadable.list(:loadable="statues")
template(v-for="status in statues.get()") template(v-for="status in statues.get()")
status(v-if="showStatus(status)" :key="status.id" :status="status" :showMedia="options.showMedia" @mark="onStatusMark" @vote="onPollVote" @context="onShowContext") status(v-if="showStatus(status)" :key="status.id" :status="status" :bus="bus")
.status(v-show="statues.loadingMore") .status(v-show="statues.loadingMore")
.service-loader .service-loader
.context(v-if="hasContext") .context(v-if="hasContext")
.header(@click="closeContext") .header(@click="closeContext")
| Context | Context
span.date(@click.stop.prevent="closeContext") span.date(@click.stop.prevent="closeContext") {{ icons.close }}
.list .list
.ancestors .ancestors
template(v-if="targetContext.isSuccess") template(v-if="targetContext.isSuccess")
status(v-for="status in targetContext.get().ancestors" :key="status.id" :status="status" :showMedia="options.showMedia" @mark="onStatusMark" @vote="onPollVote" @context="onShowContext") status(v-for="status in targetContext.get().ancestors" :key="status.id" :status="status" :bus="bus")
.service-loader(v-else) .service-loader(v-else)
status.selected(:status="targetStatus" :showMedia="options.showMedia" @mark="onStatusMark" @vote="onPollVote" @context="closeContext") status.selected(:status="targetStatus" :bus="bus")
.descendants .descendants
template(v-if="targetContext.isSuccess") template(v-if="targetContext.isSuccess")
status(v-for="status in targetContext.get().descendants" :key="status.id" :status="status" :showMedia="options.showMedia" @mark="onStatusMark" @vote="onPollVote" @context="onShowContext") status(v-for="status in targetContext.get().descendants" :key="status.id" :status="status" :bus="bus")
.service-loader(v-else) .service-loader(v-else)
.notifications(v-if="hasNotifications") .notifications(v-if="hasNotifications")
.header .header
| Notifications | Notifications
span.date(@click.stop.prevent="onNotificationsClear") span.date(@click.stop.prevent="onNotificationsClear") {{ icons.close }}
.list .list
notification(v-for="notification in notifications.get()" :key="notification.id" :notification="notification" notification(v-for="notification in notifications.get()" :key="notification.id" :notification="notification"
:showMedia="options.showMedia" @dismiss="onNotificationDismiss" @mark="onStatusMark" @vote="onPollVote" @context="onShowContext") @dismiss="onNotificationDismiss" :bus="bus")
.compose-toggle(@click="showCompose = !showCompose") 🖉 .compose-toggle(@click="showCompose = !showCompose") {{ icons.compose }}
.emoji-list(v-if="options.showMedia" v-show="showCompose && showEmojis") .emoji-list(v-if="options.showMedia" v-show="showCompose && showEmojis")
img.emoji(v-for="emoji in emojis.get()" @click="addEmoji(emoji.shortcode)" :src="emoji.static_url" :alt="emoji.shortcode" :title="emoji.shortcode") img.emoji(v-for="emoji in emojis.get()" @click="addEmoji(emoji.shortcode)" :src="emoji.static_url" :alt="emoji.shortcode" :title="emoji.shortcode")
.compose(v-show="showCompose") .compose(v-show="showCompose")
@ -48,26 +48,26 @@
input(v-show="compose.sensitive" v-model="compose.spoiler_text" placeholder="content warning") input(v-show="compose.sensitive" v-model="compose.spoiler_text" placeholder="content warning")
.visibility .visibility
select(v-model="compose.visibility") select(v-model="compose.visibility")
option(value="public") option(v-for="(icon, value) in visibilities" :value="value") {{ icon }}
option(value="unlisted") 👁
option(value="private")
option(value="direct")
span.note {{ compose.visibility }} span.note {{ compose.visibility }}
button(@click="sendStatus") Toot button(@click="sendStatus") Toot
</template> </template>
<script lang="ts"> <script lang="ts">
import axios, { AxiosResponse } from 'axios' import axios, { AxiosResponse } from 'axios'
import { Component, Mixins, Prop } from 'vue-property-decorator' import { Component, Mixins, Prop, Vue, Watch } from 'vue-property-decorator'
import LocalBusMixin from '@/components/LocalBusMixin'
import ServiceClient from '@/components/ServiceClient' import ServiceClient from '@/components/ServiceClient'
import Lists from '@/helpers/lists/Lists' import Lists from '@/helpers/lists/Lists'
import AxiosLoadable from '@/helpers/loadable/AxiosLoadable' import AxiosLoadable from '@/helpers/loadable/AxiosLoadable'
import AxiosLoadableMore from '@/helpers/loadable/AxiosLoadableMore' import AxiosLoadableMore from '@/helpers/loadable/AxiosLoadableMore'
import { LocalEvents } from './BusMixin'
import { Icons, Visibility } from './Icons'
import { AUTH, getHeaders, getRest } from './Mastodon.vue' import { AUTH, getHeaders, getRest } from './Mastodon.vue'
import Notification from './Notification.vue' import Notification from './Notification.vue'
import Status from './Status.vue' import Status from './Status.vue'
import { Context, Emoji, MarkStatus, Notification as INotification, Options, Poll, PollVote, Status as IStatus, StatusPost, TimelineType } from './Types' import { BusOptions, Context, Emoji, MarkStatus, Notification as INotification, Options, Poll, PollVote, Status as IStatus, StatusPost, TimelineType } from './Types'
const STREAMS = { const STREAMS = {
home: 'user', home: 'user',
@ -97,6 +97,11 @@ export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient
} }
showEmojis = false // MAYBE: show tabs with unicode emoticons showEmojis = false // MAYBE: show tabs with unicode emoticons
bus = new Vue({ data: {
showMedia: this.options.showMedia,
showCounts: this.options.showCounts
} })
get hasNotifications() { get hasNotifications() {
if(!this.notifications.isSuccess) { if(!this.notifications.isSuccess) {
return false return false
@ -114,12 +119,31 @@ export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient
return this.targetStatus && !this.targetContext.hasError return this.targetStatus && !this.targetContext.hasError
} }
get visibilities() {
return Visibility
}
get icons() {
return Icons
}
created() { created() {
this.$watch('options.timeline', this.init, { immediate: true }) new Map<string, (arg: any) => void>([
[ LocalEvents.Mark, this.onStatusMark ],
[ LocalEvents.Vote, this.onPollVote ],
[ LocalEvents.Context, this.onHandleContext ]
]).forEach((handler, name) => this.bus.$on(name, handler))
this.notifications.load(this.get<INotification[]>('/notifications')) this.notifications.load(this.get<INotification[]>('/notifications'))
this.emojis.load(this.get<Emoji[]>('/custom_emojis'), res => Lists.sort(res.data, e => e.shortcode, Lists.stringCompare)) this.emojis.load(this.get<Emoji[]>('/custom_emojis'), res => Lists.sort(res.data, e => e.shortcode, Lists.stringCompare))
} }
@Watch('options', { deep: true })
change(o: any) {
Object.keys(this.bus.$data).forEach(key => this.bus.$data[key] = o[key])
}
@Watch('options.timeline', { immediate: true })
init() { init() {
this.statues.load(this.getTimeline()) this.statues.load(this.getTimeline())
this.setupStream() this.setupStream()
@ -190,7 +214,12 @@ export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient
)) ))
} }
onShowContext(status: IStatus) { onHandleContext(status: IStatus) {
if(this.targetStatus && this.targetStatus.id === status.id) {
this.closeContext()
return
}
this.statues.with(sts => { this.statues.with(sts => {
this.targetStatus = status this.targetStatus = status
this.targetContext.load(this.get(`/statuses/${status.id}/context`), undefined, true) this.targetContext.load(this.get(`/statuses/${status.id}/context`), undefined, true)

View File

@ -0,0 +1,25 @@
export const Visibility = {
public: '◍',
unlisted: '👁',
private: '⚿',
direct: '✉'
}
export const Notification = {
mention: '✉',
reblog: '⟳',
favourite: '⚝',
follow: '👁'
}
export const Icons = {
compose: '🖉',
close: '❌',
}
export const Context = {
full: '⮃',
up: '⮥',
down: '⮦',
no: '⭿'
}

View File

@ -5,13 +5,14 @@
| {{ serviceName }}: | {{ serviceName }}:
loadable-inline(:loadable="account") loadable-inline(:loadable="account")
template(#success) template(#success)
span(v-html="parseEmojis(account.data.display_name, account.data.emojis, params.showMedia) + '@' + server", params.showMedia) span(v-html="parseEmojis(account.data.display_name, account.data.emojis, params.showMedia) + '@' + server")
template(#settings) template(#settings)
setting-boolean(:id="'reconnect'" :title="'Reconnect'" :value="params.reconnect" @change="saveOptionCouple") setting-boolean(:id="'reconnect'" :title="'Reconnect'" :value="params.reconnect" @change="saveOptionCouple")
setting-boolean(:id="'reblog'" :title="'Show reblogs'" :value="params.reblog" @change="saveOptionCouple") setting-boolean(:id="'reblog'" :title="'Show reblogs'" :value="params.reblog" @change="saveOptionCouple")
setting-boolean(:id="'reply'" :title="'Show replies'" :value="params.reply" @change="saveOptionCouple") setting-boolean(:id="'reply'" :title="'Show replies'" :value="params.reply" @change="saveOptionCouple")
setting-int(:id="'buffer'" :title="'Buffer size'" :value="params.buffer" @change="saveOptionCouple") setting-int(:id="'buffer'" :title="'Buffer size'" :value="params.buffer" @change="saveOptionCouple")
setting-boolean(:id="'showMedia'" :title="'Show medias'" :value="params.showMedia" @change="saveOptionCouple") setting-boolean(:id="'showMedia'" :title="'Show medias'" :value="params.showMedia" @change="saveOptionCouple")
setting-boolean(:id="'showCounts'" :title="'Show counts'" :value="params.showCounts" @change="saveOptionCouple")
setting-select(:id="'timeline'" :title="'Timeline'" :value="params.timeline" @change="saveOptionCouple" :options="['home', 'local', 'public']") setting-select(:id="'timeline'" :title="'Timeline'" :value="params.timeline" @change="saveOptionCouple" :options="['home', 'local', 'public']")
loadable-block.service-content(:loadable="account") loadable-block.service-content(:loadable="account")
template(#success) template(#success)
@ -58,7 +59,7 @@ export default class Mastodon extends Mixins<AccountService<Account, object>>(Ac
get params(): Options { get params(): Options {
return { timeout: 5000, reconnect: false, buffer: 20, reblog: true, reply: false, return { timeout: 5000, reconnect: false, buffer: 20, reblog: true, reply: false,
showMedia: true, timeline: 'home', ...this.options } showMedia: true, showCounts: true, timeline: 'home', ...this.options }
} }
get isSetup() { get isSetup() {

View File

@ -1,55 +1,46 @@
<template lang="pug"> <template lang="pug">
.notification .notification
account(:account="notification.account" :showMedia="showMedia") account(:account="notification.account" :bus="bus")
span.colored.text-icon.letter(v-if="notification.type == 'mention'")
span.colored.text-icon.letter(v-if="notification.type == 'reblog'")
span.colored.text-icon.letter(v-if="notification.type == 'favourite'")
span.colored.text-icon.letter {{ notificationTypeIcon }}
span.date {{ fromNow(notification.created_at) }} span.date {{ fromNow(notification.created_at) }}
.content .content
template(v-if="notification.type == 'follow'") Vous suit template(v-if="notification.type == 'follow'") Vous suit
status.reblog(v-else-if="notification.status" :status="notification.status" status.reblog(v-else-if="notification.status" :status="notification.status"
:showMedia="showMedia" :withAccount="notification.type != 'mention'" @mark="passMark" @vote="passVote" @context="passContext") :withAccount="notification.type != 'mention'" :bus="bus")
a.date(@click.stop.prevent="makeDismiss" style="margin-top: -1em") a.date(@click.stop.prevent="makeDismiss" style="margin-top: -1em") {{ closeIcon }}
</template> </template>
<script lang="ts"> <script lang="ts">
import { Component, Emit, Mixins, Prop } from 'vue-property-decorator' import { Component, Emit, Mixins, Prop } from 'vue-property-decorator'
import FromNowMixin from '@/components/FromNowMixin' import FromNowMixin from '@/components/FromNowMixin'
import ShowMediaMixin from '@/components/ShowMediaMixin'
import Account from './Account.vue' import Account from './Account.vue'
import BusMixin from './BusMixin'
import { Icons, Notification as NotificationIcons } from './Icons'
import Status from './Status.vue' import Status from './Status.vue'
import { MarkStatus, Notification as INotification, PollVote, Status as IStatus } from './Types' import { MarkStatus, Notification as INotification, PollVote, Status as IStatus } from './Types'
@Component({ components: { Account, Status } }) @Component({ components: { Account, Status } })
export default class Notification extends Mixins(ShowMediaMixin, FromNowMixin) { export default class Notification extends Mixins(FromNowMixin, BusMixin) {
@Prop(Object) @Prop(Object)
readonly notification!: INotification readonly notification!: INotification
get notificationTypeIcon() {
return NotificationIcons[this.notification.type] || '?'
}
get closeIcon() {
return Icons.close
}
@Emit('dismiss') @Emit('dismiss')
makeDismiss() { makeDismiss() {
return this.notification.id return this.notification.id
} }
@Emit('mark')
passMark(action: MarkStatus) {
return action
}
@Emit('vote')
passVote(action: PollVote) {
return action
}
@Emit('context')
passContext(status: IStatus) {
return status
}
} }
</script> </script>

View File

@ -1,8 +1,8 @@
<template lang="pug"> <template lang="pug">
.status .status
account(v-if="withAccount" :account="status.account" :showMedia="showMedia") account(v-if="withAccount" :account="status.account" :bus="bus")
span.text-icon.letter(v-if="status.reblog") span.text-icon.letter(v-if="status.reblog") {{ reblogIcon }}
a.date(target="_blank" :href="status.uri") {{ fromNow(status.created_at) }} a.date(target="_blank" :href="status.uri") {{ fromNow(status.created_at) }}
@ -12,9 +12,10 @@
{{ status.spoiler_text || 'Spoiler' }} {{ status.sensitive ? '&rarr;' : '&darr;' }} {{ status.spoiler_text || 'Spoiler' }} {{ status.sensitive ? '&rarr;' : '&darr;' }}
div(v-if="!status.spoiler_text || !status.sensitive") div(v-if="!status.spoiler_text || !status.sensitive")
.text(v-html="parseEmojis(status.content, status.emojis, showMedia)") .text(v-html="parseEmojis(status.content, status.emojis, showMedia)")
.poll(v-if="status.poll") .poll(v-if="status.poll")
.date {{ fromNow(status.poll.expires_at) }} .date {{ fromNow(status.poll.expires_at) }}
form.options(@submit.prevent="makeVote(status, $event.target.elements)") form.options(@submit.prevent="makeVote($event.target.elements)")
.option(v-for="option in status.poll.options") .option(v-for="option in status.poll.options")
input(v-if="!status.poll.expired && !status.poll.voted" :type="status.poll.multiple ? 'checkbox' : 'radio'" :id="status.poll.id + option.title" :value="option.title" :name="status.poll.id") input(v-if="!status.poll.expired && !status.poll.voted" :type="status.poll.multiple ? 'checkbox' : 'radio'" :id="status.poll.id + option.title" :value="option.title" :name="status.poll.id")
label(:for="status.poll.id + option.title") label(:for="status.poll.id + option.title")
@ -23,12 +24,14 @@
button(v-if="status.poll.voted") voted button(v-if="status.poll.voted") voted
button(v-else-if="status.poll.expired") expired button(v-else-if="status.poll.expired") expired
input(v-else type="submit" value="vote") input(v-else type="submit" value="vote")
a.media(v-for="media in status.media_attachments" :href="media.url" target="_blank") a.media(v-for="media in status.media_attachments" :href="media.url" target="_blank")
template(v-if="showMedia") template(v-if="bus.showMedia")
img(v-if="media.type == 'image' || media.type == 'gifv'" :src="media.preview_url" :alt="media.description" :title="media.description") img(v-if="media.type == 'image' || media.type == 'gifv'" :src="media.preview_url" :alt="media.description" :title="media.description")
template(v-else) Wrong type template(v-else) Wrong type
.gif(v-if="media.type == 'gifv'") GIF .gif(v-if="media.type == 'gifv'") GIF
template(v-else) Hidden media {{ media.description }} template(v-else) Hidden media {{ media.description }}
a.card(v-if="status.card" :href="status.card.url" target="_blank") a.card(v-if="status.card" :href="status.card.url" target="_blank")
a.provider(v-if="status.card.provider_name" :src="status.card.provider_url" target="_blank") {{ status.card.provider_name }} a.provider(v-if="status.card.provider_name" :src="status.card.provider_url" target="_blank") {{ status.card.provider_name }}
.title {{ status.card.title }} .title {{ status.card.title }}
@ -36,38 +39,29 @@
template(v-if="status.card.image") template(v-if="status.card.image")
img(v-if="showMedia" :src="status.card.image") img(v-if="showMedia" :src="status.card.image")
a(v-else-if="status.card.type == 'photo'" :src="status.card.image" target="_blank") Hidden media a(v-else-if="status.card.type == 'photo'" :src="status.card.image" target="_blank") Hidden media
status.reblog(v-else :status="status.reblog" :showMedia="showMedia" @mark="passMark" @vote="passVote" @context="passContext")
status.reblog(v-else :status="status.reblog" :bus="bus")
.meta(v-if="!status.reblog") .meta(v-if="!status.reblog")
a.replies(@click.stop.prevent="makeReply(status)") status-meta(v-for="meta in metas" :key="meta.name" :meta="meta" :bus="bus")
span.text-icon a {{ statusVisibilityIcon }}
| {{ status.replies_count }} a.fil(@click.stop.prevent="showContext")
a.reblogs(:class="{ colored: status.reblogged }" @click.stop.prevent="makeReblog(status)") | {{ contextIcon }}
span.text-icon
| {{ status.reblogs_count }}
a.favourites(:class="{ colored: status.favourited }" @click.stop.prevent="makeFav(status)")
span.text-icon
| {{ status.favourites_count }}
a.visibility
template(v-if="status.visibility == 'public'")
template(v-else-if="status.visibility == 'unlisted'") 👁
template(v-else-if="status.visibility == 'private'")
template(v-else-if="status.visibility == 'direct'")
a.fil(@click.stop.prevent="passContext(status)")
span.text-icon
</template> </template>
<script lang="ts"> <script lang="ts">
import { Component, Emit, Mixins, Prop } from 'vue-property-decorator' import { Component, Emit, Mixins, Prop } from 'vue-property-decorator'
import FromNowMixin from '@/components/FromNowMixin' import FromNowMixin from '@/components/FromNowMixin'
import ShowMediaMixin from '@/components/ShowMediaMixin'
import Account from './Account.vue' import Account from './Account.vue'
import BusMixin, { LocalEvents } from './BusMixin'
import { Context, Notification, Visibility } from './Icons'
import { ParseEmojisMixin } from './ParseEmojisMixin' import { ParseEmojisMixin } from './ParseEmojisMixin'
import StatusMeta from './StatusMeta.vue'
import { Card, MarkStatus, MarkStatusType, Poll, PollVote, Status as IStatus } from './Types' import { Card, MarkStatus, MarkStatusType, Poll, PollVote, Status as IStatus } from './Types'
@Component({ components: { Account } }) @Component({ components: { Account, StatusMeta } })
export default class Status extends Mixins(ParseEmojisMixin, ShowMediaMixin, FromNowMixin) { export default class Status extends Mixins(ParseEmojisMixin, FromNowMixin, BusMixin) {
@Prop(Object) @Prop(Object)
readonly status!: IStatus readonly status!: IStatus
@ -75,44 +69,61 @@ export default class Status extends Mixins(ParseEmojisMixin, ShowMediaMixin, Fro
@Prop({ type: Boolean, default: true }) @Prop({ type: Boolean, default: true })
readonly withAccount!: boolean readonly withAccount!: boolean
@Emit('mark') get statusVisibilityIcon() {
passMark(action: MarkStatus) { return Visibility[this.status.visibility] || '?'
return action
} }
@Emit('vote') get reblogIcon() {
passVote(action: PollVote) { return Notification.reblog
return action
} }
@Emit('context') get contextIcon() {
passContext(status: IStatus) { if(this.status.in_reply_to_id) {
return status return Context[this.status.replies_count ? 'full' : 'up']
} } else {
return Context[this.status.replies_count ? 'down' : 'no']
makeVote(status: IStatus, elements: HTMLInputElement[]) {
const choices = Object.values(elements).filter(e => e.checked).map(e => e.value)
if(choices.length > 0) {
this.passVote({ id: status.id, poll: status.poll!.id, choices })
} }
} }
makeMark(status: IStatus, action: string, undo: boolean) { get showMedia() {
this.passMark({ return this.bus.$data.showMedia
id: status.id, type: (undo ? 'un' : '') + action as MarkStatusType }
get metas() {
return [
{ name: 'reply', click: this.makeReply, active: false, icon: Notification.mention, count: this.status.replies_count },
{ name: 'reblog', click: this.makeReblog, active: this.status.reblogged, icon: Notification.reblog, count: this.status.reblogs_count },
{ name: 'fav', click: this.makeFav, active: this.status.favourited, icon: Notification.favourite, count: this.status.favourites_count }
]
}
makeVote(elements: HTMLInputElement[]) {
const choices = Object.values(elements).filter(e => e.checked).map(e => e.value)
if(choices.length > 0) {
this.bus.$emit(LocalEvents.Vote, { id: this.status.id, poll: this.status.poll!.id, choices })
}
}
makeMark(action: string, undo: boolean) {
this.bus.$emit(LocalEvents.Mark, {
id: this.status.id, type: (undo ? 'un' : '') + action as MarkStatusType
}) })
} }
makeReblog(status: IStatus) { makeReblog() {
this.makeMark(status, 'reblog', status.reblogged) this.makeMark('reblog', this.status.reblogged)
} }
makeFav(status: IStatus) { makeFav() {
this.makeMark(status, 'favourite', status.favourited) this.makeMark('favourite', this.status.favourited)
} }
makeReply(status: IStatus) { showContext() {
throw status.id // TODO: this.bus.$emit(LocalEvents.Context, this.status)
}
makeReply() {
throw this // TODO:
} }
} }

View File

@ -0,0 +1,23 @@
<template lang="pug">
a(:class="{ colored: meta.active }" @click.stop.prevent="meta.click")
span.text-icon {{ meta.icon }}
template(v-if="showCounts") {{ meta.count }}
</template>
<script lang="ts">
import { Component, Mixins, Prop } from 'vue-property-decorator'
import BusMixin from './BusMixin'
@Component
export default class StatusMeta extends Mixins(BusMixin) {
@Prop(Object)
readonly meta!: object
get showCounts() {
return this.bus.$data.showCounts
}
}
</script>

View File

@ -11,13 +11,17 @@ export interface Account {
export type TimelineType = 'home' | 'local' | 'public' export type TimelineType = 'home' | 'local' | 'public'
export interface Options { export interface BusOptions {
showMedia: boolean
showCounts: boolean
}
export interface Options extends BusOptions {
timeout: number timeout: number
reconnect: boolean reconnect: boolean
buffer: number buffer: number
reblog: boolean reblog: boolean
reply: boolean reply: boolean
showMedia: boolean
timeline: TimelineType timeline: TimelineType
} }
@ -99,10 +103,11 @@ export interface Context {
descendants: Status[] descendants: Status[]
} }
export type NotificationType = 'follow' | 'mention' | 'reblog' | 'favourite'
export interface Notification { export interface Notification {
id: number id: number
account: Account account: Account
type: string type: NotificationType
created_at: string created_at: string
status?: Status status?: Status
} }