Merge branch 'release/4.2.0' into develop
This commit is contained in:
commit
714e33a742
13 changed files with 93 additions and 12 deletions
24
CHANGELOG.md
24
CHANGELOG.md
|
@ -1,5 +1,29 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v4.2.1
|
||||||
|
|
||||||
|
### IMPORTANT NOTES
|
||||||
|
|
||||||
|
* If you upgrade from PeerTube **< 4.2.0**, please follow 4.2.0 IMPORTANT NOTES
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
* Fix live ending job that breaks new live session
|
||||||
|
* Fix search filters counter
|
||||||
|
* Fix upload banner icon margin
|
||||||
|
* Fix button icon margin
|
||||||
|
* Fix my import expander icon that should only be displayed on import error
|
||||||
|
* Fix select components styling inconsistency
|
||||||
|
* Increase max watch section to avoid too much warnings in server
|
||||||
|
* Optimize broadcast job creation
|
||||||
|
* Optimize `View` activities delivery using a dedicated broadcast job queue that can be run in parallel
|
||||||
|
* Fix video selection buttons placement
|
||||||
|
* Fix searching into account blocklist
|
||||||
|
* Fix incorrect instance stats
|
||||||
|
* Fix broken player on ICE error
|
||||||
|
* Relax views federation
|
||||||
|
|
||||||
|
|
||||||
## v4.2.0
|
## v4.2.0
|
||||||
|
|
||||||
### IMPORTANT NOTES
|
### IMPORTANT NOTES
|
||||||
|
|
|
@ -15,6 +15,8 @@ my-actor-avatar {
|
||||||
}
|
}
|
||||||
|
|
||||||
.actor-info-display-name {
|
.actor-info-display-name {
|
||||||
|
@include peertube-word-wrap;
|
||||||
|
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: $font-bold;
|
font-weight: $font-bold;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
.action-selection-mode-child {
|
.action-selection-mode-child {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
.action-button {
|
.action-button {
|
||||||
@include margin-left(55px);
|
@include margin-left(55px);
|
||||||
|
|
|
@ -67,7 +67,12 @@
|
||||||
if (placeholderPreview) placeholderPreview.style.display = 'none'
|
if (placeholderPreview) placeholderPreview.style.display = 'none'
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onerror = function () {
|
window.onerror = function (msg) {
|
||||||
|
if (typeof msg === 'string' && msg.toLowerCase().includes(' ice ')) {
|
||||||
|
console.warn(msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
window.displayIncompatibleBrowser()
|
window.displayIncompatibleBrowser()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -370,7 +370,7 @@ const CONSTRAINTS_FIELDS = {
|
||||||
|
|
||||||
const VIEW_LIFETIME = {
|
const VIEW_LIFETIME = {
|
||||||
VIEW: CONFIG.VIEWS.VIDEOS.IP_VIEW_EXPIRATION,
|
VIEW: CONFIG.VIEWS.VIDEOS.IP_VIEW_EXPIRATION,
|
||||||
VIEWER_COUNTER: 60000 * 1, // 1 minute
|
VIEWER_COUNTER: 60000 * 2, // 2 minutes
|
||||||
VIEWER_STATS: 60000 * 60 // 1 hour
|
VIEWER_STATS: 60000 * 60 // 1 hour
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ export class VideoViewerCounters {
|
||||||
private async federateViewerIfNeeded (video: MVideoImmutable, viewer: Viewer) {
|
private async federateViewerIfNeeded (video: MVideoImmutable, viewer: Viewer) {
|
||||||
// Federate the viewer if it's been a "long" time we did not
|
// Federate the viewer if it's been a "long" time we did not
|
||||||
const now = new Date().getTime()
|
const now = new Date().getTime()
|
||||||
const federationLimit = now - (VIEW_LIFETIME.VIEWER_COUNTER / 2)
|
const federationLimit = now - (VIEW_LIFETIME.VIEWER_COUNTER * 0.75)
|
||||||
|
|
||||||
if (viewer.lastFederation && viewer.lastFederation > federationLimit) return
|
if (viewer.lastFederation && viewer.lastFederation > federationLimit) return
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,20 @@ export class AccountBlocklistModel extends Model<Partial<AttributesOnly<AccountB
|
||||||
as: 'BlockedAccount'
|
as: 'BlockedAccount'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
} else if (search) { // We need some joins when counting with search
|
||||||
|
query.include = [
|
||||||
|
{
|
||||||
|
model: AccountModel.unscoped(),
|
||||||
|
required: true,
|
||||||
|
as: 'BlockedAccount',
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: ActorModel.unscoped(),
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
return query
|
return query
|
||||||
|
|
|
@ -819,10 +819,10 @@ export class UserModel extends Model<Partial<AttributesOnly<UserModel>>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return UserModel.count(query)
|
return UserModel.unscoped().count(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
const totalUsers = await UserModel.count()
|
const totalUsers = await UserModel.unscoped().count()
|
||||||
const totalDailyActiveUsers = await getActiveUsers(1)
|
const totalDailyActiveUsers = await getActiveUsers(1)
|
||||||
const totalWeeklyActiveUsers = await getActiveUsers(7)
|
const totalWeeklyActiveUsers = await getActiveUsers(7)
|
||||||
const totalMonthlyActiveUsers = await getActiveUsers(30)
|
const totalMonthlyActiveUsers = await getActiveUsers(30)
|
||||||
|
|
|
@ -683,11 +683,11 @@ export class VideoCommentModel extends Model<Partial<AttributesOnly<VideoComment
|
||||||
const totalLocalVideoComments = await VideoCommentModel.count({
|
const totalLocalVideoComments = await VideoCommentModel.count({
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: AccountModel,
|
model: AccountModel.unscoped(),
|
||||||
required: true,
|
required: true,
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: ActorModel,
|
model: ActorModel.unscoped(),
|
||||||
required: true,
|
required: true,
|
||||||
where: {
|
where: {
|
||||||
serverId: null
|
serverId: null
|
||||||
|
|
|
@ -617,11 +617,11 @@ export class VideoPlaylistModel extends Model<Partial<AttributesOnly<VideoPlayli
|
||||||
const totalLocalPlaylists = await VideoPlaylistModel.count({
|
const totalLocalPlaylists = await VideoPlaylistModel.count({
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: AccountModel,
|
model: AccountModel.unscoped(),
|
||||||
required: true,
|
required: true,
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
model: ActorModel,
|
model: ActorModel.unscoped(),
|
||||||
required: true,
|
required: true,
|
||||||
where: {
|
where: {
|
||||||
serverId: null
|
serverId: null
|
||||||
|
|
|
@ -256,6 +256,13 @@ describe('Test blocklist', function () {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should search blocked accounts', async function () {
|
||||||
|
const body = await command.listMyAccountBlocklist({ start: 0, count: 10, search: 'user2' })
|
||||||
|
expect(body.total).to.equal(1)
|
||||||
|
|
||||||
|
expect(body.data[0].blockedAccount.name).to.equal('user2')
|
||||||
|
})
|
||||||
|
|
||||||
it('Should get blocked status', async function () {
|
it('Should get blocked status', async function () {
|
||||||
const remoteHandle = 'user2@' + servers[1].host
|
const remoteHandle = 'user2@' + servers[1].host
|
||||||
const localHandle = 'user1@' + servers[0].host
|
const localHandle = 'user1@' + servers[0].host
|
||||||
|
@ -475,6 +482,13 @@ describe('Test blocklist', function () {
|
||||||
expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port)
|
expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should search blocked servers', async function () {
|
||||||
|
const body = await command.listMyServerBlocklist({ start: 0, count: 10, search: servers[1].host })
|
||||||
|
expect(body.total).to.equal(1)
|
||||||
|
|
||||||
|
expect(body.data[0].blockedServer.host).to.equal(servers[1].host)
|
||||||
|
})
|
||||||
|
|
||||||
it('Should get blocklist status', async function () {
|
it('Should get blocklist status', async function () {
|
||||||
const blockedServer = servers[1].host
|
const blockedServer = servers[1].host
|
||||||
const notBlockedServer = 'example.com'
|
const notBlockedServer = 'example.com'
|
||||||
|
@ -645,6 +659,13 @@ describe('Test blocklist', function () {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should search blocked accounts', async function () {
|
||||||
|
const body = await command.listServerAccountBlocklist({ start: 0, count: 10, search: 'user2' })
|
||||||
|
expect(body.total).to.equal(1)
|
||||||
|
|
||||||
|
expect(body.data[0].blockedAccount.name).to.equal('user2')
|
||||||
|
})
|
||||||
|
|
||||||
it('Should get blocked status', async function () {
|
it('Should get blocked status', async function () {
|
||||||
const remoteHandle = 'user2@' + servers[1].host
|
const remoteHandle = 'user2@' + servers[1].host
|
||||||
const localHandle = 'user1@' + servers[0].host
|
const localHandle = 'user1@' + servers[0].host
|
||||||
|
@ -805,6 +826,13 @@ describe('Test blocklist', function () {
|
||||||
expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port)
|
expect(block.blockedServer.host).to.equal('localhost:' + servers[1].port)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should search blocked servers', async function () {
|
||||||
|
const body = await command.listServerServerBlocklist({ start: 0, count: 10, search: servers[1].host })
|
||||||
|
expect(body.total).to.equal(1)
|
||||||
|
|
||||||
|
expect(body.data[0].blockedServer.host).to.equal(servers[1].host)
|
||||||
|
})
|
||||||
|
|
||||||
it('Should get blocklist status', async function () {
|
it('Should get blocklist status', async function () {
|
||||||
const blockedServer = servers[1].host
|
const blockedServer = servers[1].host
|
||||||
const notBlockedServer = 'example.com'
|
const notBlockedServer = 'example.com'
|
||||||
|
|
|
@ -10,6 +10,8 @@ import {
|
||||||
doubleFollow,
|
doubleFollow,
|
||||||
PeerTubeServer,
|
PeerTubeServer,
|
||||||
setAccessTokensToServers,
|
setAccessTokensToServers,
|
||||||
|
setDefaultAccountAvatar,
|
||||||
|
setDefaultChannelAvatar,
|
||||||
waitJobs
|
waitJobs
|
||||||
} from '@shared/server-commands'
|
} from '@shared/server-commands'
|
||||||
|
|
||||||
|
@ -29,6 +31,8 @@ describe('Test stats (excluding redundancy)', function () {
|
||||||
servers = await createMultipleServers(3)
|
servers = await createMultipleServers(3)
|
||||||
|
|
||||||
await setAccessTokensToServers(servers)
|
await setAccessTokensToServers(servers)
|
||||||
|
await setDefaultChannelAvatar(servers)
|
||||||
|
await setDefaultAccountAvatar(servers)
|
||||||
|
|
||||||
await doubleFollow(servers[0], servers[1])
|
await doubleFollow(servers[0], servers[1])
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,10 @@ import { AbstractCommand, OverrideCommandOptions } from '../shared'
|
||||||
type ListBlocklistOptions = OverrideCommandOptions & {
|
type ListBlocklistOptions = OverrideCommandOptions & {
|
||||||
start: number
|
start: number
|
||||||
count: number
|
count: number
|
||||||
sort: string // default -createdAt
|
|
||||||
|
sort?: string // default -createdAt
|
||||||
|
|
||||||
|
search?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BlocklistCommand extends AbstractCommand {
|
export class BlocklistCommand extends AbstractCommand {
|
||||||
|
@ -147,13 +150,13 @@ export class BlocklistCommand extends AbstractCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
private listBlocklist <T> (options: ListBlocklistOptions, path: string) {
|
private listBlocklist <T> (options: ListBlocklistOptions, path: string) {
|
||||||
const { start, count, sort = '-createdAt' } = options
|
const { start, count, search, sort = '-createdAt' } = options
|
||||||
|
|
||||||
return this.getRequestBody<ResultList<T>>({
|
return this.getRequestBody<ResultList<T>>({
|
||||||
...options,
|
...options,
|
||||||
|
|
||||||
path,
|
path,
|
||||||
query: { start, count, sort },
|
query: { start, count, sort, search },
|
||||||
implicitToken: true,
|
implicitToken: true,
|
||||||
defaultExpectedStatus: HttpStatusCode.OK_200
|
defaultExpectedStatus: HttpStatusCode.OK_200
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue