Mastdon: handle timelines (public, local, home)
This commit is contained in:
parent
35167c283f
commit
539b15437c
|
@ -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>
|
|
@ -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({
|
||||||
|
|
|
@ -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...' : '')
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue