Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

同一ドメイン内の複数アカウントのストリーミング #1011

Merged
merged 3 commits into from
Nov 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 22 additions & 17 deletions app/js/tl/baseStreaming.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,28 @@ export function mastodonBaseStreaming(acctId: string) {
console.log('start to connect mastodonBaseStreaming of ' + acctId)
notfCommon(acctId, '0', false)
const domain = localStorage.getItem(`domain_${acctId}`) || ''
const mastodonBaseWsStatus: { [key: string]: IWSStatus } = globalThis.mastodonBaseWsStatus
const mastodonBaseWs: { [key: string]: WebSocket | null } = globalThis.mastodonBaseWs
if (mastodonBaseWsStatus[domain]) return
mastodonBaseWsStatus[domain] = 'undetected'
const userId = localStorage.getItem(`user-id_${acctId}`) || ''
const mastodonBaseWsStatus: { [key: string]: { [key: string]: IWSStatus } } = globalThis.mastodonBaseWsStatus
const mastodonBaseWs: { [key: string]: { [key: string]: WebSocket | null } } = globalThis.mastodonBaseWs

if (!mastodonBaseWs[domain]) mastodonBaseWs[domain] = {}
if (!mastodonBaseWsStatus[domain]) mastodonBaseWsStatus[domain] = {}

if (mastodonBaseWsStatus[domain]?.[userId]) return
mastodonBaseWsStatus[domain][userId] = 'undetected'
const at = localStorage.getItem(`acct_${acctId}_at`)
let wss = 'wss://' + domain
if (localStorage.getItem('streaming_' + acctId)) {
wss = localStorage.getItem('streaming_' + acctId)?.replace('https://', 'wss://') || wss
}
const start = `${wss}/api/v1/streaming/?access_token=${at}`
mastodonBaseWs[domain] = new WebSocket(start)
const ws = mastodonBaseWs[domain]
mastodonBaseWs[domain][userId] = new WebSocket(start)
const ws = mastodonBaseWs[domain]?.[userId]
if (!ws) return
ws.onopen = function () {
mastodonBaseWsStatus[domain] = 'connecting'
mastodonBaseWsStatus[domain][userId] = 'connecting'
setTimeout(function () {
mastodonBaseWsStatus[domain] = 'available'
mastodonBaseWsStatus[domain][userId] = 'available'
}, 3000)
ws.send(JSON.stringify({ type: 'subscribe', stream: 'user' }))
$(`.notice_icon_acct_${acctId}`).removeClass('red-text')
Expand Down Expand Up @@ -117,18 +122,18 @@ export function mastodonBaseStreaming(acctId: string) {
notfCommon(acctId, '0', true) //fallback
console.error('Error closing ' + domain)
console.error(error)
if (mastodonBaseWsStatus[domain] === 'available') return parseColumn()
mastodonBaseWsStatus[domain] = 'cannotuse'
if (mastodonBaseWsStatus[domain]?.[userId] === 'available') return parseColumn()
mastodonBaseWsStatus[domain][userId] = 'cannotuse'
setTimeout(function () {
mastodonBaseWsStatus[domain] = 'cannotuse'
mastodonBaseWsStatus[domain][userId] = 'cannotuse'
}, 3000)
mastodonBaseWs[domain] = null
mastodonBaseWs[domain][userId] = null
return false
}
ws.onclose = function () {
notfCommon(acctId, '0', true) //fallback
console.warn('Closing base streaming of ' + domain)
if (mastodonBaseWsStatus[domain] === 'available') {
if (mastodonBaseWsStatus[domain]?.[userId] === 'available') {
/*toast({
html:
`${lang.lang_parse_disconnected}<button class="btn-flat toast-action" onclick="location.reload()">${lang.lang_layout_reconnect}</button>`,
Expand All @@ -138,13 +143,13 @@ export function mastodonBaseStreaming(acctId: string) {
},
displayLength: 3000
})*/
mastodonBaseWsStatus[domain] = 'undetected'
mastodonBaseWsStatus[domain][userId] = 'undetected'
parseColumn()
} else {
mastodonBaseWs[domain] = null
mastodonBaseWsStatus[domain] = 'cannotuse'
mastodonBaseWs[domain][userId] = null
mastodonBaseWsStatus[domain][userId] = 'cannotuse'
setTimeout(function () {
mastodonBaseWsStatus[domain] = 'cannotuse'
mastodonBaseWsStatus[domain][userId] = 'cannotuse'
}, 3000)

}
Expand Down
15 changes: 8 additions & 7 deletions app/js/tl/mix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export async function mixTl(acctId, tlid, type: 'plus' | 'mix', voice?: boolean)
localStorage.setItem('now', type)
todo('Integrated TL Loading...(Local)')
const domain = localStorage.getItem(`domain_${acctId}`) || ''
const userId = localStorage.getItem(`user-id_${acctId}`) || ''
const startLocal = `https://${domain}/api/v1/timelines/public?local=true`
const local = await getTL(startLocal, acctId)
const startHome = `https://${domain}/api/v1/timelines/home`
Expand All @@ -35,20 +36,20 @@ export async function mixTl(acctId, tlid, type: 'plus' | 'mix', voice?: boolean)
additional(acctId, tlid)
timeUpdate()
todc()
if (mastodonBaseWsStatus[domain] === 'cannotuse') {
if (mastodonBaseWsStatus[domain]?.[userId] === 'cannotuse') {
mixre(acctId, tlid, 'mix', mute, voice)
} else if (mastodonBaseWsStatus[domain] === 'undetected' || mastodonBaseWsStatus[domain] === 'connecting') {
} else if (mastodonBaseWsStatus[domain]?.[userId] === 'undetected' || mastodonBaseWsStatus[domain][userId] === 'connecting') {
const mbws = setInterval(function () {
if (mastodonBaseWsStatus[domain] === 'cannotuse') {
if (mastodonBaseWsStatus[domain]?.[userId] === 'cannotuse') {
mixre(acctId, tlid, 'mix', mute, voice)
clearInterval(mbws)
} else if (mastodonBaseWsStatus[domain] === 'available') {
globalThis.mastodonBaseWs[domain].send(JSON.stringify({ type: 'subscribe', stream: 'public:local' }))
} else if (mastodonBaseWsStatus[domain]?.[userId] === 'available') {
globalThis.mastodonBaseWs[domain][userId].send(JSON.stringify({ type: 'subscribe', stream: 'public:local' }))
clearInterval(mbws)
}
}, 1000)
} else if (mastodonBaseWsStatus[domain] === 'available') {
globalThis.mastodonBaseWs[domain].send(JSON.stringify({ type: 'subscribe', stream: 'public:local' }))
} else if (mastodonBaseWsStatus[domain]?.[userId] === 'available') {
globalThis.mastodonBaseWs[domain][userId].send(JSON.stringify({ type: 'subscribe', stream: 'public:local' }))
}

$(window).scrollTop(0)
Expand Down
13 changes: 7 additions & 6 deletions app/js/tl/notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,11 @@ export async function notfCommon(acctId: string, tlid: string, isStreamOnly: boo
todo('Notifications Loading...')
const native = localStorage.getItem('nativenotf') || 'yes'
const domain = localStorage.getItem(`domain_${acctId}`) || ''
const userId = localStorage.getItem(`user-id_${acctId}`) || ''
const at = localStorage.getItem(`acct_${acctId}_at`) || ''
const start = `https://${domain}/api/v1/notifications`
if (isStreamOnly) {
notfWS(acctId, tlid, domain, at)
notfWS(acctId, tlid, domain, userId, at)
return false
}
try {
Expand Down Expand Up @@ -161,14 +162,14 @@ export async function notfCommon(acctId: string, tlid: string, isStreamOnly: boo
}
$('#notf-box').addClass('fetched')
todc()
if (isStreamOnly && domain && at) notfWS(acctId, tlid, domain, at)
if (isStreamOnly && domain && at) notfWS(acctId, tlid, domain, userId, at)
} catch (e: any) {
$('div[data-notf=' + acctId + '] .landing').append(`<div>${escapeHTML(e)}`)
}
}
let errorCt = 0
function notfWS(acctId: string, tlid: string, domain: string, at: string) {
if (globalThis.mastodonBaseWsStatus[domain] === 'available') return false
function notfWS(acctId: string, tlid: string, domain: string, userId: string, at: string) {
if (globalThis.mastodonBaseWsStatus[domain]?.[userId] === 'available') return false
const wss = localStorage.getItem('streaming_' + acctId) || 'wss://' + domain
const start = `${wss}/api/v1/streaming/?stream=user&access_token=${at}`
const websocketNotf: WebSocket[] = globalThis.websocketNotf
Expand Down Expand Up @@ -219,14 +220,14 @@ function notfWS(acctId: string, tlid: string, domain: string, at: string) {
console.error('WebSocket Error ', error)
errorCt++
if (errorCt < 3) {
notfWS(acctId, tlid, domain, at)
notfWS(acctId, tlid, domain, userId, at)
}
}
websocketNotf[acctId].onclose = function (error) {
console.error('WebSocket Close ', error)
errorCt++
if (errorCt < 3) {
notfWS(acctId, tlid, domain, at)
notfWS(acctId, tlid, domain, userId, at)
}
}
}
Expand Down
25 changes: 15 additions & 10 deletions app/js/tl/tl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,24 +154,25 @@ export async function tl(type: IColumnType, data: IColumnData | undefined, acctI
//Streaming接続
function reload(type: IColumnType, acctId: string, tlid: string, data: IColumnData | undefined, mute: string[], voice: boolean) {
const domain = type !== 'noauth' ? localStorage.getItem(`domain_${acctId}`) || '' : ''
const userId = type !== 'noauth' ? localStorage.getItem(`user-id_${acctId}`) || '' : ''
localStorage.setItem('now', type)
const mastodonBaseWsStatus = globalThis.mastodonBaseWsStatus
if (!domain) {
oldStreaming(type, acctId, tlid, data, mute, voice)
} else if (mastodonBaseWsStatus[domain] === 'cannotuse') {
} else if (mastodonBaseWsStatus[domain]?.[userId] === 'cannotuse') {
oldStreaming(type, acctId, tlid, data, mute, voice)
} else if (mastodonBaseWsStatus[domain] === 'undetected' || mastodonBaseWsStatus[domain] === 'connecting') {
} else if (mastodonBaseWsStatus[domain]?.[userId] === 'undetected' || mastodonBaseWsStatus[domain][userId] === 'connecting') {
const mbws = setInterval(function () {
if (mastodonBaseWsStatus[domain] === 'cannotuse') {
if (mastodonBaseWsStatus[domain]?.[userId] === 'cannotuse') {
oldStreaming(type, acctId, tlid, data, mute, voice)
clearInterval(mbws)
} else if (mastodonBaseWsStatus[domain] === 'available') {
} else if (mastodonBaseWsStatus[domain]?.[userId] === 'available') {
$('#notice_icon_' + tlid).removeClass('red-text')
stremaingSubscribe(type, acctId, data)
clearInterval(mbws)
}
}, 1000)
} else if (mastodonBaseWsStatus[domain] === 'available') {
} else if (mastodonBaseWsStatus[domain]?.[userId] === 'available') {
$('#notice_icon_' + tlid).removeClass('red-text')
stremaingSubscribe(type, acctId, data)
}
Expand All @@ -182,7 +183,8 @@ function stremaingSubscribe(type: IColumnType, acctId: string, data?: IColumnDat
if (unsubscribe) command = 'unsubscribe'
let stream
const domain = localStorage.getItem(`domain_${acctId}`) || ''
const targetStreaming = globalThis.mastodonBaseWs[domain]
const userId = localStorage.getItem(`user-id_${acctId}`) || ''
const targetStreaming = globalThis.mastodonBaseWs[domain]?.[userId]
if (type === 'home') return false
if (type === 'local' || type === 'mix') {
stream = 'public:local'
Expand Down Expand Up @@ -441,9 +443,11 @@ export function tlCloser() {
}
globalThis.websocketOld = []
const baseStreaming = globalThis.mastodonBaseWs || {}
for (const acctId of Object.keys(baseStreaming)) {
if (globalThis.mastodonBaseWs[acctId]) {
globalThis.mastodonBaseWs[acctId].close()
for (const domain of Object.keys(baseStreaming)) {
for (const userId of Object.keys(baseStreaming[domain])) {
if (globalThis.mastodonBaseWs[domain][userId]) {
globalThis.mastodonBaseWs[acctId][userId].close()
}
}
}
globalThis.mastodonBaseWs = {}
Expand Down Expand Up @@ -629,7 +633,8 @@ export function columnReload(tlid: string, type: IColumnType) {
const obj = getColumn()
const acctId = obj[tlid].domain
const domain = localStorage.getItem('domain_' + acctId) || ''
if (globalThis.mastodonBaseWsStatus[domain] === 'available') {
const userId = localStorage.getItem(`user-id_${acctId}`) || ''
if (globalThis.mastodonBaseWsStatus[domain]?.[userId] === 'available') {
stremaingSubscribe(type, acctId, obj[tlid].data, true)
parseColumn(tlid, true)
return true
Expand Down