Better structure + channel home in LitElement format
This commit is contained in:
parent
687c4742f7
commit
de974eae22
8
client/common/configuration/contexts/channel.ts
Normal file
8
client/common/configuration/contexts/channel.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { createContext } from "@lit/context";
|
||||
import type { RegisterClientOptions } from "@peertube/peertube-types/client/types";
|
||||
import type { ChannelConfiguration } from "shared/lib/types";
|
||||
import { ChannelDetailsService } from "../services/channel-details";
|
||||
|
||||
export const registerClientOptionsContext = createContext<RegisterClientOptions | undefined>(Symbol('register-client-options'));
|
||||
export const channelConfigurationContext = createContext<ChannelConfiguration | undefined>(Symbol('channel-configuration'));
|
||||
export const channelDetailsServiceContext = createContext<ChannelDetailsService | undefined>(Symbol('channel-configuration-service'));
|
@ -1,9 +1,8 @@
|
||||
import { PartInfo, PartType, directive } from 'lit/directive.js'
|
||||
import { PartInfo, directive } from 'lit/directive.js'
|
||||
import { AsyncDirective } from 'lit/async-directive.js'
|
||||
import { RegisterClientHelpers } from '@peertube/peertube-types/client';
|
||||
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
||||
import { html } from 'lit';
|
||||
import { unsafeStatic } from 'lit/static-html.js';
|
||||
|
||||
export class TranslationDirective extends AsyncDirective {
|
||||
|
||||
@ -34,7 +33,7 @@ export class TranslationDirective extends AsyncDirective {
|
||||
this._translatedValue = locId
|
||||
}
|
||||
|
||||
this._asyncUpdateTranslation()
|
||||
this._asyncUpdateTranslation().then(() => {}, () => {})
|
||||
|
||||
return this._internalRender()
|
||||
}
|
@ -1,22 +1,16 @@
|
||||
import { RegisterClientOptions } from '@peertube/peertube-types/client'
|
||||
import { css, html, LitElement } from 'lit'
|
||||
import { repeat } from 'lit-html/directives/repeat.js'
|
||||
import type { RegisterClientOptions } from '@peertube/peertube-types/client'
|
||||
import { html, LitElement } from 'lit'
|
||||
import { customElement, property, state } from 'lit/decorators.js'
|
||||
import { ptTr } from './TranslationDirective'
|
||||
import { localizedHelpUrl } from '../../../utils/help'
|
||||
import './DynamicTableFormElement'
|
||||
import './PluginConfigurationRow'
|
||||
import './HelpButtonElement'
|
||||
import { until } from 'async'
|
||||
import { ptTr } from '../directives/translation'
|
||||
import './dynamic-table-form'
|
||||
import './plugin-configuration-row'
|
||||
import './help-button'
|
||||
import { Task } from '@lit/task';
|
||||
import { ChannelConfiguration } from 'shared/lib/types'
|
||||
import { ChannelConfigurationService } from './ChannelConfigurationService'
|
||||
import { createContext, provide } from '@lit/context'
|
||||
import type { ChannelConfiguration } from 'shared/lib/types'
|
||||
import { ChannelDetailsService } from '../services/channel-details'
|
||||
import { provide } from '@lit/context'
|
||||
import { getGlobalStyleSheets } from '../../global-styles'
|
||||
|
||||
export const registerClientOptionsContext = createContext<RegisterClientOptions | undefined>(Symbol('register-client-options'));
|
||||
export const channelConfigurationContext = createContext<ChannelConfiguration | undefined>(Symbol('channel-configuration'));
|
||||
export const channelConfigurationServiceContext = createContext<ChannelConfigurationService | undefined>(Symbol('channel-configuration-service'));
|
||||
import { channelConfigurationContext, channelDetailsServiceContext, registerClientOptionsContext } from '../contexts/channel'
|
||||
|
||||
@customElement('channel-configuration')
|
||||
export class ChannelConfigurationElement extends LitElement {
|
||||
@ -32,8 +26,8 @@ export class ChannelConfigurationElement extends LitElement {
|
||||
@state()
|
||||
public _channelConfiguration: ChannelConfiguration | undefined
|
||||
|
||||
@provide({ context: channelConfigurationServiceContext })
|
||||
private _configurationService: ChannelConfigurationService | undefined
|
||||
@provide({ context: channelDetailsServiceContext })
|
||||
private _channelDetailsService: ChannelDetailsService | undefined
|
||||
|
||||
static styles = [
|
||||
...getGlobalStyleSheets()
|
||||
@ -46,8 +40,8 @@ export class ChannelConfigurationElement extends LitElement {
|
||||
|
||||
task: async ([registerClientOptions], {signal}) => {
|
||||
if (this.registerClientOptions) {
|
||||
this._configurationService = new ChannelConfigurationService(this.registerClientOptions)
|
||||
this._channelConfiguration = await this._configurationService.fetchConfiguration(this.channelId ?? 0)
|
||||
this._channelDetailsService = new ChannelDetailsService(this.registerClientOptions)
|
||||
this._channelConfiguration = await this._channelDetailsService.fetchConfiguration(this.channelId ?? 0)
|
||||
}
|
||||
},
|
||||
|
||||
@ -56,8 +50,8 @@ export class ChannelConfigurationElement extends LitElement {
|
||||
});
|
||||
|
||||
private _saveConfig = () => {
|
||||
if(this._configurationService && this._channelConfiguration) {
|
||||
this._configurationService.saveOptions(this._channelConfiguration.channel.id, this._channelConfiguration.configuration)
|
||||
if(this._channelDetailsService && this._channelConfiguration) {
|
||||
this._channelDetailsService.saveOptions(this._channelConfiguration.channel.id, this._channelConfiguration.configuration)
|
||||
.then((value) => {
|
||||
this._formStatus = { success: true }
|
||||
console.log(`Configuration has been updated`)
|
||||
@ -326,7 +320,7 @@ export class ChannelConfigurationElement extends LitElement {
|
||||
: ''
|
||||
}
|
||||
</form>
|
||||
</div>${JSON.stringify(this._channelConfiguration)}`
|
||||
</div>`
|
||||
})
|
||||
}
|
||||
}
|
86
client/common/configuration/elements/channel-home.ts
Normal file
86
client/common/configuration/elements/channel-home.ts
Normal file
@ -0,0 +1,86 @@
|
||||
import type { RegisterClientOptions } from '@peertube/peertube-types/client'
|
||||
import { html, LitElement } from 'lit'
|
||||
import { customElement, property, state } from 'lit/decorators.js'
|
||||
import { ptTr } from '../directives/translation'
|
||||
import './help-button'
|
||||
import { Task } from '@lit/task';
|
||||
import type { ChannelLiveChatInfos } from 'shared/lib/types'
|
||||
import { ChannelDetailsService } from '../services/channel-details'
|
||||
import { provide } from '@lit/context'
|
||||
import { getGlobalStyleSheets } from '../../global-styles'
|
||||
import { channelDetailsServiceContext, registerClientOptionsContext } from '../contexts/channel'
|
||||
|
||||
@customElement('channel-home')
|
||||
export class ChannelHomeElement extends LitElement {
|
||||
|
||||
@provide({ context: registerClientOptionsContext })
|
||||
@property({ attribute: false })
|
||||
public registerClientOptions: RegisterClientOptions | undefined
|
||||
|
||||
@state()
|
||||
public _channels: ChannelLiveChatInfos[] | undefined
|
||||
|
||||
@provide({ context: channelDetailsServiceContext })
|
||||
private _channelDetailsService: ChannelDetailsService | undefined
|
||||
|
||||
static styles = [
|
||||
...getGlobalStyleSheets()
|
||||
];
|
||||
|
||||
@state()
|
||||
public _formStatus: boolean | any = undefined
|
||||
|
||||
private _asyncTaskRender = new Task(this, {
|
||||
|
||||
task: async ([registerClientOptions], {signal}) => {
|
||||
// Getting the current username in localStorage. Don't know any cleaner way to do.
|
||||
const username = window.localStorage.getItem('username')
|
||||
if (!username) {
|
||||
throw new Error('Can\'t get the current username.')
|
||||
}
|
||||
|
||||
if (this.registerClientOptions) {
|
||||
this._channelDetailsService = new ChannelDetailsService(this.registerClientOptions)
|
||||
this._channels = await this._channelDetailsService.fetchUserChannels(username)
|
||||
}
|
||||
},
|
||||
|
||||
args: () => [this.registerClientOptions]
|
||||
|
||||
});
|
||||
|
||||
render = () => {
|
||||
return this._asyncTaskRender.render({
|
||||
complete: () => html`
|
||||
<div class="margin-content peertube-plugin-livechat-configuration peertube-plugin-livechat-configuration-home">
|
||||
<h1>
|
||||
${ptTr(LOC_LIVECHAT_CONFIGURATION_TITLE)}
|
||||
<help-button .page="documentation/user/streamers/channel">
|
||||
</help-button>
|
||||
</h1>
|
||||
<p>${ptTr(LOC_LIVECHAT_CONFIGURATION_DESC)}</p>
|
||||
<p>${ptTr(LOC_LIVECHAT_CONFIGURATION_PLEASE_SELECT)}</p>
|
||||
<ul class="peertube-plugin-livechat-configuration-home-channels">
|
||||
${this._channels?.map((channel) => html`
|
||||
<li>
|
||||
<a href="${channel.livechatConfigurationUri}">
|
||||
${channel.avatar ?
|
||||
html`<img class="avatar channel" src="${channel.avatar.path}">`
|
||||
:
|
||||
html`<div class="avatar channel initial gray"></div>`
|
||||
}
|
||||
</a>
|
||||
<div class="peertube-plugin-livechat-configuration-home-info">
|
||||
<a href="${channel.livechatConfigurationUri}">
|
||||
<div>${channel.displayName}</div>
|
||||
<div>${channel.name}</div>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
`)}
|
||||
</ul>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
}
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
import { css, html, LitElement } from 'lit'
|
||||
import { html, LitElement } from 'lit'
|
||||
import { customElement, property, state } from 'lit/decorators.js'
|
||||
import { unsafeHTML } from 'lit/directives/unsafe-html.js'
|
||||
import { helpButtonSVG } from '../../../videowatch/buttons'
|
||||
import { consume } from '@lit/context'
|
||||
import { registerClientOptionsContext } from './ChannelConfigurationElement'
|
||||
import { RegisterClientOptions } from '@peertube/peertube-types/client'
|
||||
import { registerClientOptionsContext } from '../contexts/channel'
|
||||
import type { RegisterClientOptions } from '@peertube/peertube-types/client'
|
||||
import { Task } from '@lit/task'
|
||||
import { localizedHelpUrl } from '../../../utils/help'
|
||||
import { ptTr } from './TranslationDirective'
|
||||
import { ptTr } from '../directives/translation'
|
||||
import { DirectiveResult } from 'lit/directive'
|
||||
import { getGlobalStyleSheets } from '../../global-styles'
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { css, html, LitElement } from 'lit'
|
||||
import { html, LitElement } from 'lit'
|
||||
import { customElement, property } from 'lit/decorators.js'
|
||||
import './HelpButtonElement'
|
||||
import './help-button'
|
||||
import { getGlobalStyleSheets } from '../../global-styles'
|
||||
|
||||
@customElement('plugin-configuration-row')
|
||||
export class PluginConfigurationRow extends LitElement {
|
||||
export class PluginConfigurationRowElement extends LitElement {
|
||||
|
||||
@property({ attribute: false })
|
||||
public title: string = `title`
|
@ -3,8 +3,8 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { RegisterClientOptions } from '@peertube/peertube-types/client'
|
||||
import { renderConfigurationHome } from './templates/home'
|
||||
import './templates/ChannelConfigurationElement'
|
||||
import './elements/channel-home'
|
||||
import './elements/channel-configuration'
|
||||
import { html, render } from 'lit'
|
||||
|
||||
/**
|
||||
@ -20,7 +20,7 @@ async function registerConfiguration (clientOptions: RegisterClientOptions): Pro
|
||||
registerClientRoute({
|
||||
route: 'livechat/configuration',
|
||||
onMount: async ({ rootEl }) => {
|
||||
render(await renderConfigurationHome(clientOptions), rootEl)
|
||||
render(html`<channel-home .registerClientOptions=${clientOptions}></channel-home>`, rootEl)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { RegisterClientOptions } from "@peertube/peertube-types/client"
|
||||
import { ChannelConfiguration, ChannelConfigurationOptions } from "shared/lib/types"
|
||||
import type { RegisterClientOptions } from "@peertube/peertube-types/client"
|
||||
import { ChannelLiveChatInfos, ChannelConfiguration, ChannelConfigurationOptions } from "shared/lib/types"
|
||||
import { getBaseRoute } from "../../../utils/uri"
|
||||
|
||||
|
||||
export class ChannelConfigurationService {
|
||||
export class ChannelDetailsService {
|
||||
|
||||
public _registerClientOptions: RegisterClientOptions
|
||||
|
||||
@ -42,6 +42,37 @@ export class ChannelConfigurationService {
|
||||
return await response.json()
|
||||
}
|
||||
|
||||
fetchUserChannels = async (username: string): Promise<ChannelLiveChatInfos[]> => {
|
||||
// FIXME: if more than 100 channels, loop (or add a pagination)
|
||||
const channels = await (await fetch(
|
||||
'/api/v1/accounts/' + encodeURIComponent(username) + '/video-channels?start=0&count=100&sort=name',
|
||||
{
|
||||
method: 'GET',
|
||||
headers: this._headers
|
||||
}
|
||||
)).json()
|
||||
if (!channels || !('data' in channels) || !Array.isArray(channels.data)) {
|
||||
throw new Error('Can\'t get the channel list.')
|
||||
}
|
||||
|
||||
for (const channel of channels.data) {
|
||||
channel.livechatConfigurationUri = '/p/livechat/configuration/channel?channelId=' + encodeURIComponent(channel.id)
|
||||
|
||||
// Note: since Peertube v6.0.0, channel.avatar is dropped, and we have to use channel.avatars.
|
||||
// So, if !channel.avatar, we will search a suitable one in channel.avatars, and fill channel.avatar.
|
||||
if (!channel.avatar && channel.avatars && Array.isArray(channel.avatars)) {
|
||||
for (const avatar of channel.avatars) {
|
||||
if (avatar.width === 120) {
|
||||
channel.avatar = avatar
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return channels.data
|
||||
}
|
||||
|
||||
fetchConfiguration = async (channelId: number): Promise<ChannelConfiguration> => {
|
||||
const response = await fetch(
|
||||
getBaseRoute(this._registerClientOptions) + '/api/configuration/channel/' + encodeURIComponent(channelId),
|
@ -1,132 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { RegisterClientOptions } from '@peertube/peertube-types/client'
|
||||
import { localizedHelpUrl } from '../../../utils/help'
|
||||
import { helpButtonSVG } from '../../../videowatch/buttons'
|
||||
import { TemplateResult, html } from 'lit'
|
||||
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
||||
|
||||
interface HomeViewData {
|
||||
title: string
|
||||
description: string
|
||||
please_select: string
|
||||
channels: any[]
|
||||
helpButton: TemplateResult
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the livechat configuration setup home page.
|
||||
* @param registerClientOptions Peertube client options
|
||||
* @returns The page content
|
||||
*/
|
||||
async function renderConfigurationHome (registerClientOptions: RegisterClientOptions): Promise<TemplateResult> {
|
||||
const { peertubeHelpers } = registerClientOptions
|
||||
|
||||
try {
|
||||
// Getting the current username in localStorage. Don't know any cleaner way to do.
|
||||
const username = window.localStorage.getItem('username')
|
||||
if (!username) {
|
||||
throw new Error('Can\'t get the current username.')
|
||||
}
|
||||
|
||||
// FIXME: if more than 100 channels, loop (or add a pagination)
|
||||
const channels = await (await fetch(
|
||||
'/api/v1/accounts/' + encodeURIComponent(username) + '/video-channels?start=0&count=100&sort=name',
|
||||
{
|
||||
method: 'GET',
|
||||
headers: peertubeHelpers.getAuthHeader()
|
||||
}
|
||||
)).json()
|
||||
if (!channels || !('data' in channels) || !Array.isArray(channels.data)) {
|
||||
throw new Error('Can\'t get the channel list.')
|
||||
}
|
||||
|
||||
for (const channel of channels.data) {
|
||||
channel.livechatConfigurationUri = '/p/livechat/configuration/channel?channelId=' + encodeURIComponent(channel.id)
|
||||
|
||||
// Note: since Peertube v6.0.0, channel.avatar is dropped, and we have to use channel.avatars.
|
||||
// So, if !channel.avatar, we will search a suitable one in channel.avatars, and fill channel.avatar.
|
||||
if (!channel.avatar && channel.avatars && Array.isArray(channel.avatars)) {
|
||||
for (const avatar of channel.avatars) {
|
||||
if (avatar.width === 120) {
|
||||
channel.avatar = avatar
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const view : HomeViewData = {
|
||||
title: await peertubeHelpers.translate(LOC_LIVECHAT_CONFIGURATION_TITLE),
|
||||
description: await peertubeHelpers.translate(LOC_LIVECHAT_CONFIGURATION_DESC),
|
||||
please_select: await peertubeHelpers.translate(LOC_LIVECHAT_CONFIGURATION_PLEASE_SELECT),
|
||||
channels: channels.data,
|
||||
helpButton: await _fillViewHelpButtons(registerClientOptions)
|
||||
}
|
||||
|
||||
|
||||
return renderConfigurationHomeFromTemplate(view)
|
||||
} catch (err: any) {
|
||||
peertubeHelpers.notifier.error(err.toString())
|
||||
return html``
|
||||
}
|
||||
}
|
||||
|
||||
async function _fillViewHelpButtons ( // TODO: refactor with the similar function in channel.ts
|
||||
registerClientOptions: RegisterClientOptions
|
||||
): Promise<TemplateResult> {
|
||||
const title = await registerClientOptions.peertubeHelpers.translate(LOC_ONLINE_HELP)
|
||||
|
||||
const button = async (page: string): Promise<TemplateResult> => {
|
||||
const helpUrl = await localizedHelpUrl(registerClientOptions, {
|
||||
page
|
||||
})
|
||||
const helpIcon = helpButtonSVG()
|
||||
return html`<a
|
||||
href="${helpUrl}"
|
||||
target=_blank
|
||||
title="${title}"
|
||||
class="orange-button peertube-button-link"
|
||||
>${unsafeHTML(helpIcon)}</a>`
|
||||
}
|
||||
|
||||
return button('documentation/user/streamers/channel')
|
||||
}
|
||||
|
||||
function renderConfigurationHomeFromTemplate(view: HomeViewData) {
|
||||
return html`
|
||||
<div class="margin-content peertube-plugin-livechat-configuration peertube-plugin-livechat-configuration-home">
|
||||
<h1>
|
||||
${view.title}
|
||||
${view.helpButton}
|
||||
</h1>
|
||||
<p>${view.description}</p>
|
||||
<p>${view.please_select}</p>
|
||||
<ul class="peertube-plugin-livechat-configuration-home-channels">
|
||||
${view.channels.map((channel) => html`
|
||||
<li>
|
||||
<a href="${channel.livechatConfigurationUri}">
|
||||
${channel.avatar ?
|
||||
html`<img class="avatar channel" src="${channel.avatar.path}">`
|
||||
:
|
||||
html`<div class="avatar channel initial gray"></div>`
|
||||
}
|
||||
</a>
|
||||
<div class="peertube-plugin-livechat-configuration-home-info">
|
||||
<a href="${channel.livechatConfigurationUri}">
|
||||
<div>${channel.displayName}</div>
|
||||
<div>${channel.name}</div>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
`)}
|
||||
</ul>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
export {
|
||||
renderConfigurationHome
|
||||
}
|
@ -2,25 +2,25 @@
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
"module": "es2022",
|
||||
"moduleResolution": "node",
|
||||
"moduleResolution": "node",
|
||||
"target": "es2022",
|
||||
"allowJs": true,
|
||||
"sourceMap": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"alwaysStrict": true, // should already be true because of strict:true
|
||||
"noImplicitAny": true, // should already be true because of strict:true
|
||||
"noImplicitThis": true, // should already be true because of strict:true
|
||||
"noImplicitReturns": true,
|
||||
"strictBindCallApply": true, // should already be true because of strict:true
|
||||
"noUnusedLocals": false,
|
||||
"allowSyntheticDefaultImports": true, // Seems necessary for peertube types to work
|
||||
"isolatedModules": true, // Needed by esbuild https://esbuild.github.io/content-types/#isolated-modules
|
||||
"esModuleInterop": true, // Needed by esbuild https://esbuild.github.io/content-types/#es-module-interop
|
||||
"sourceMap": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"alwaysStrict": true, // should already be true because of strict:true
|
||||
"noImplicitAny": true, // should already be true because of strict:true
|
||||
"noImplicitThis": true, // should already be true because of strict:true
|
||||
"noImplicitReturns": true,
|
||||
"strictBindCallApply": true, // should already be true because of strict:true
|
||||
"noUnusedLocals": true,
|
||||
"allowSyntheticDefaultImports": true, // Seems necessary for peertube types to work
|
||||
"isolatedModules": true, // Needed by esbuild https://esbuild.github.io/content-types/#isolated-modules
|
||||
"esModuleInterop": true, // Needed by esbuild https://esbuild.github.io/content-types/#es-module-interop
|
||||
"outDir": "../dist/client",
|
||||
"paths": {
|
||||
"shared/*": ["../shared/*"]
|
||||
}
|
||||
"paths": {
|
||||
"shared/*": ["../shared/*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
|
29
package-lock.json
generated
29
package-lock.json
generated
@ -20,7 +20,6 @@
|
||||
"lit": "^3.1.3",
|
||||
"log-rotate": "^0.2.8",
|
||||
"openid-client": "^5.6.5",
|
||||
"rxjs": "^7.8.1",
|
||||
"validate-color": "^2.2.1",
|
||||
"xmppjs-chat-bot": "^0.3.0"
|
||||
},
|
||||
@ -10535,19 +10534,6 @@
|
||||
"integrity": "sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/rxjs": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
|
||||
"integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rxjs/node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/safe-array-concat": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz",
|
||||
@ -20337,21 +20323,6 @@
|
||||
"integrity": "sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==",
|
||||
"dev": true
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "7.8.1",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
|
||||
"integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
|
||||
"requires": {
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"safe-array-concat": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz",
|
||||
|
@ -44,7 +44,6 @@
|
||||
"lit": "^3.1.3",
|
||||
"log-rotate": "^0.2.8",
|
||||
"openid-client": "^5.6.5",
|
||||
"rxjs": "^7.8.1",
|
||||
"validate-color": "^2.2.1",
|
||||
"xmppjs-chat-bot": "^0.3.0"
|
||||
},
|
||||
|
@ -2,6 +2,17 @@
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
// Not working for some reason
|
||||
// import type { ActorImage } from '@peertube/peertube-types'
|
||||
|
||||
interface ActorImage {
|
||||
width: number
|
||||
path: string
|
||||
url?: string
|
||||
createdAt: Date | string
|
||||
updatedAt: Date | string
|
||||
}
|
||||
|
||||
type ConverseJSTheme = 'peertube' | 'default' | 'concord'
|
||||
|
||||
interface InitConverseJSParams {
|
||||
@ -71,6 +82,12 @@ interface ChannelInfos {
|
||||
displayName: string
|
||||
}
|
||||
|
||||
interface ChannelLiveChatInfos extends ChannelInfos {
|
||||
avatar: ActorImage
|
||||
avatars: ActorImage[]
|
||||
livechatConfigurationUri: string
|
||||
}
|
||||
|
||||
interface ChannelConfigurationOptions {
|
||||
bot: {
|
||||
enabled: boolean
|
||||
@ -134,6 +151,7 @@ export type {
|
||||
ProsodyListRoomsResult,
|
||||
ProsodyListRoomsResultRoom,
|
||||
ChannelInfos,
|
||||
ChannelLiveChatInfos,
|
||||
ChannelConfigurationOptions,
|
||||
ChannelConfiguration,
|
||||
ChatIncludeMode,
|
||||
|
Loading…
x
Reference in New Issue
Block a user