mirror of https://github.com/FreeTubeApp/FreeTube
140 lines
3.7 KiB
JavaScript
140 lines
3.7 KiB
JavaScript
import store from '../../store/index'
|
|
import { stripHTML, toLocalePublicationString } from '../utils'
|
|
import autolinker from 'autolinker'
|
|
|
|
function getCurrentInstance() {
|
|
return store.getters.getCurrentInvidiousInstance
|
|
}
|
|
|
|
export function invidiousAPICall({ resource, id = '', params = {}, doLogError = true }) {
|
|
return new Promise((resolve, reject) => {
|
|
const requestUrl = getCurrentInstance() + '/api/v1/' + resource + '/' + id + '?' + new URLSearchParams(params).toString()
|
|
|
|
fetch(requestUrl)
|
|
.then((response) => response.json())
|
|
.then((json) => {
|
|
if (json.error !== undefined) {
|
|
throw new Error(json.error)
|
|
}
|
|
resolve(json)
|
|
})
|
|
.catch((error) => {
|
|
if (doLogError) {
|
|
console.error('Invidious API error', requestUrl, error)
|
|
}
|
|
reject(error)
|
|
})
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Gets the channel ID for a channel URL
|
|
* used to get the ID for channel usernames and handles
|
|
* @param {string} url
|
|
*/
|
|
export async function invidiousGetChannelId(url) {
|
|
try {
|
|
const response = await invidiousAPICall({
|
|
resource: 'resolveurl',
|
|
params: {
|
|
url
|
|
},
|
|
doLogError: false
|
|
})
|
|
|
|
if (response.pageType === 'WEB_PAGE_TYPE_CHANNEL') {
|
|
return response.ucid
|
|
} else {
|
|
return null
|
|
}
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
export async function invidiousGetChannelInfo(channelId) {
|
|
return await invidiousAPICall({
|
|
resource: 'channels',
|
|
id: channelId,
|
|
})
|
|
}
|
|
|
|
export async function invidiousGetPlaylistInfo(playlistId) {
|
|
return await invidiousAPICall({
|
|
resource: 'playlists',
|
|
id: playlistId,
|
|
})
|
|
}
|
|
|
|
export async function invidiousGetVideoInformation(videoId) {
|
|
return await invidiousAPICall({
|
|
resource: 'videos',
|
|
id: videoId,
|
|
})
|
|
}
|
|
export async function invidiousGetComments({ id, nextPageToken = '', sortNewest = true }) {
|
|
const payload = {
|
|
resource: 'comments',
|
|
id: id,
|
|
params: {
|
|
continuation: nextPageToken ?? '',
|
|
sort_by: sortNewest ? 'new' : 'top'
|
|
}
|
|
}
|
|
const response = await invidiousAPICall(payload)
|
|
|
|
const commentData = parseInvidiousCommentData(response)
|
|
|
|
return { response, commentData }
|
|
}
|
|
|
|
export async function invidiousGetCommentReplies({ id, replyToken }) {
|
|
const payload = {
|
|
resource: 'comments',
|
|
id: id,
|
|
params: {
|
|
continuation: replyToken
|
|
}
|
|
}
|
|
|
|
const response = await invidiousAPICall(payload)
|
|
return { commentData: parseInvidiousCommentData(response), continuation: response.continuation ?? null }
|
|
}
|
|
|
|
export function youtubeImageUrlToInvidious(url, currentInstance = null) {
|
|
if (currentInstance === null) {
|
|
currentInstance = getCurrentInstance()
|
|
}
|
|
// Can be prefixed with `https://` or `//` (protocol relative)
|
|
if (url.startsWith('//')) {
|
|
url = 'https:' + url
|
|
}
|
|
|
|
return url.replace('https://yt3.ggpht.com', `${currentInstance}/ggpht`)
|
|
}
|
|
|
|
export function invidiousImageUrlToInvidious(url, currentInstance = null) {
|
|
return url.replace(/^.+(ggpht.+)/, currentInstance)
|
|
}
|
|
|
|
function parseInvidiousCommentData(response) {
|
|
return response.comments.map((comment) => {
|
|
comment.showReplies = false
|
|
comment.authorLink = comment.authorId
|
|
comment.authorThumb = youtubeImageUrlToInvidious(comment.authorThumbnails[1].url)
|
|
comment.likes = comment.likeCount
|
|
comment.text = autolinker.link(stripHTML(comment.content))
|
|
comment.dataType = 'invidious'
|
|
comment.isOwner = comment.authorIsChannelOwner
|
|
comment.numReplies = comment.replies?.replyCount ?? 0
|
|
comment.replyToken = comment.replies?.continuation ?? ''
|
|
comment.isHearted = comment.creatorHeart !== undefined
|
|
comment.replies = []
|
|
comment.time = toLocalePublicationString({
|
|
publishText: comment.publishedText
|
|
})
|
|
|
|
return comment
|
|
})
|
|
}
|