Mastdon: handle timelines (public, local, home)

This commit is contained in:
May B. 2019-05-27 16:24:42 +02:00
parent 35167c283f
commit 539b15437c
5 changed files with 69 additions and 17 deletions

View File

@ -0,0 +1,24 @@
<template lang="pug">
extends model
block input
select(:id="id" :value="value" @change="sendChange($event.target.value)")
option(v-for="option in options" :value="option") {{ option }}
</template>
<script lang="ts">
import { Component, Prop } from 'vue-property-decorator'
import BaseSetting from './BaseSetting'
@Component
export default class SettingSelect extends BaseSetting {
@Prop(String)
readonly value!: string
@Prop(Array)
readonly options!: string[]
}
</script>

View File

@ -3,11 +3,12 @@ import { Component, Prop, Watch } from 'vue-property-decorator'
import { Auth } from '@/types/App' import { Auth } from '@/types/App'
import SettingBoolean from '../input/SettingBoolean.vue' import SettingBoolean from '../input/SettingBoolean.vue'
import SettingInt from '../input/SettingInt.vue' import SettingInt from '../input/SettingInt.vue'
import SettingSelect from '../input/SettingSelect.vue'
import SettingString from '../input/SettingString.vue' import SettingString from '../input/SettingString.vue'
import ServiceEmiter from '../ServiceEmiter' import ServiceEmiter from '../ServiceEmiter'
import ServiceHeader from '../ServiceHeader.vue' import ServiceHeader from '../ServiceHeader.vue'
@Component({ components: { ServiceHeader, SettingString, SettingInt, SettingBoolean } }) @Component({ components: { ServiceHeader, SettingString, SettingInt, SettingBoolean, SettingSelect } })
export default class BaseService extends ServiceEmiter { export default class BaseService extends ServiceEmiter {
@Prop({ @Prop({

View File

@ -27,7 +27,7 @@
select(v-model="compose.visibility") select(v-model="compose.visibility")
option(value="public") option(value="public")
option(value="unlisted") 👁 option(value="unlisted") 👁
option(selected value="private") option(value="private")
option(value="direct") option(value="direct")
span.note {{ compose.visibility }} span.note {{ compose.visibility }}
button(@click="sendStatus") Toot button(@click="sendStatus") Toot
@ -35,7 +35,7 @@
<script lang="ts"> <script lang="ts">
import axios, { AxiosResponse } from 'axios' import axios, { AxiosResponse } from 'axios'
import { Component, Mixins } from 'vue-property-decorator' import { Component, Mixins, Prop } from 'vue-property-decorator'
import ServiceClient from '@/components/ServiceClient' import ServiceClient from '@/components/ServiceClient'
import Lists from '@/helpers/lists/Lists' import Lists from '@/helpers/lists/Lists'
@ -44,20 +44,33 @@ import AxiosLodableMore from '@/helpers/loadable/AxiosLoadableMore'
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 { MarkMessage, Notification as INotification, Options, Status as IStatus, StatusPost } from './Types' import { MarkMessage, Notification as INotification, Options, Status as IStatus, StatusPost, TimelineType } from './Types'
const STREAMS = {
home: 'user',
local: 'public:local',
public: 'public'
}
@Component({ components: { Status, Notification } }) @Component({ components: { Status, Notification } })
export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient) { export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient) {
/*
home: timelines/home
local: timelines/public?local=true
public: timelines/public?...
*/
rest = getRest(this.auth, this.options.timeout) rest = getRest(this.auth, this.options.timeout)
statues = new AxiosLodableMore<IStatus[], object>() statues = new AxiosLodableMore<IStatus[], object>()
notifications = new AxiosLodable<INotification[], object>() notifications = new AxiosLodable<INotification[], object>()
stream?: WebSocket = undefined
showCompose = false showCompose = false
compose: StatusPost = { compose: StatusPost = {
status: '', status: '',
visibility: 'private', visibility: 'unlisted',
sensitive: false, sensitive: false,
spoiler_text: '' spoiler_text: ''
} }
@ -76,8 +89,12 @@ export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient
} }
created() { created() {
this.statues.load(this.getTimeline()) this.$watch('options.timeline', this.init, { immediate: true })
this.notifications.load(this.get('/notifications')) this.notifications.load(this.get('/notifications'))
}
init() {
this.statues.load(this.getTimeline())
this.setupStream() this.setupStream()
} }
@ -106,8 +123,11 @@ export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient
} }
} }
getTimeline(options = {}) { getTimeline(options: any = {}) {
return this.get('/timelines/home', options) if (this.options.timeline === 'local') {
options.local = true
}
return this.get(`/timelines/${this.options.timeline === 'home' ? 'home' : 'public'}`, options)
} }
onScroll(event: any) { onScroll(event: any) {
@ -140,13 +160,16 @@ export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient
} }
setupStream() { setupStream() {
if(this.stream) {
this.stream.close()
}
this.get('/instance').then(res => { this.get('/instance').then(res => {
const oldAuth = res.data.version < '2.8.4' ? `access_token=${this.auth.get(AUTH.TOKEN)}&` : '' const oldAuth = res.data.version < '2.8.4' ? `access_token=${this.auth.get(AUTH.TOKEN)}&` : ''
const ws = new WebSocket( this.stream = new WebSocket(
`wss://${this.auth.get(AUTH.SERVER)}/api/v1/streaming?${oldAuth}stream=user`, `wss://${this.auth.get(AUTH.SERVER)}/api/v1/streaming?${oldAuth}stream=${STREAMS[this.options.timeline]}`,
this.auth.get(AUTH.TOKEN) this.auth.get(AUTH.TOKEN)
) )
ws.onmessage = event => { this.stream.onmessage = event => {
const data = JSON.parse(event.data) const data = JSON.parse(event.data)
const payload = JSON.parse(data.payload) const payload = JSON.parse(data.payload)
switch (data.event) { switch (data.event) {
@ -163,8 +186,8 @@ export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient
break break
} }
} }
ws.onerror = ev => this.emitError(ev.type) this.stream.onerror = ev => this.emitError(ev.type)
ws.onclose = () => { this.stream.onclose = () => {
this.emitError( this.emitError(
'Mastodon stream disconnected !' + 'Mastodon stream disconnected !' +
(this.options.reconnect ? ' Reconnecting...' : '') (this.options.reconnect ? ' Reconnecting...' : '')

View File

@ -12,6 +12,7 @@
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-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)
client(:auth="auth" :options="params" :emit="emit") client(:auth="auth" :options="params" :emit="emit")
@ -57,7 +58,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, ...this.options } showMedia: true, timeline: 'home', ...this.options }
} }
get isSetup() { get isSetup() {

View File

@ -9,6 +9,8 @@ export interface Account {
emojis: Emoji[] emojis: Emoji[]
} }
export type TimelineType = 'home' | 'local' | 'public'
export interface Options { export interface Options {
timeout: number timeout: number
reconnect: boolean reconnect: boolean
@ -16,6 +18,7 @@ export interface Options {
reblog: boolean reblog: boolean
reply: boolean reply: boolean
showMedia: boolean showMedia: boolean
timeline: TimelineType
} }
export type VisibilityType = 'public' | 'unlisted' | 'private' | 'direct' export type VisibilityType = 'public' | 'unlisted' | 'private' | 'direct'
@ -45,9 +48,9 @@ export interface Status {
replies_count: number replies_count: number
in_reply_to_id?: number in_reply_to_id?: number
reblog?: Status reblog?: Status
spoiler_text?: string, spoiler_text?: string
card?: Card, card?: Card
poll?: Poll, poll?: Poll
visibility: VisibilityType visibility: VisibilityType
} }