Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Framasoft
PeerTube
PeerTube
Commits
e3d6c643
Verified
Commit
e3d6c643
authored
Jul 27, 2022
by
Chocobozzz
Browse files
Add bulk action on following/followers
parent
073deef8
Changes
11
Hide whitespace changes
Inline
Side-by-side
client/src/app/+admin/follows/followers-list/followers-list.component.html
View file @
e3d6c643
...
...
@@ -9,9 +9,18 @@
[lazy]=
"true"
(onLazyLoad)=
"loadLazy($event)"
[lazyLoadOnInit]=
"false"
[showCurrentPageReport]=
"true"
i18n-currentPageReportTemplate
currentPageReportTemplate=
"Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} followers"
[(selection)]=
"selectedFollows"
>
<ng-template
pTemplate=
"caption"
>
<div
class=
"caption"
>
<div
class=
"left-buttons"
>
<my-action-dropdown
*ngIf=
"isInSelectionMode()"
i18n-label
label=
"Batch actions"
theme=
"orange"
[actions]=
"bulkFollowsActions"
[entry]=
"selectedFollows"
>
</my-action-dropdown>
</div>
<div
class=
"ms-auto"
>
<my-advanced-input-filter
[filters]=
"searchFilters"
(search)=
"onSearch($event)"
></my-advanced-input-filter>
</div>
...
...
@@ -20,6 +29,9 @@
<ng-template
pTemplate=
"header"
>
<tr>
<th
style=
"width: 40px"
>
<p-tableHeaderCheckbox
ariaLabel=
"Select all rows"
i18n-ariaLabel
></p-tableHeaderCheckbox>
</th>
<th
style=
"width: 150px;"
i18n
>
Actions
</th>
<th
i18n
>
Follower
</th>
<th
style=
"width: 100px;"
i18n
pSortableColumn=
"state"
>
State
<p-sortIcon
field=
"state"
></p-sortIcon></th>
...
...
@@ -30,15 +42,19 @@
<ng-template
pTemplate=
"body"
let-follow
>
<tr>
<td
class=
"checkbox-cell"
>
<p-tableCheckbox
[value]=
"follow"
ariaLabel=
"Select this row"
i18n-ariaLabel
></p-tableCheckbox>
</td>
<td
class=
"action-cell"
>
<my-button
*ngIf=
"follow.state !== 'accepted'"
i18n-title
title=
"Accept"
icon=
"tick"
(click)=
"acceptFollower(follow)"
></my-button>
<my-button
*ngIf=
"follow.state !== 'rejected'"
i18n-title
title=
"Re
fuse
"
icon=
"cross"
(click)=
"rejectFollower(follow)"
></my-button>
<my-button
*ngIf=
"follow.state !== 'accepted'"
i18n-title
title=
"Accept"
icon=
"tick"
(click)=
"acceptFollower(
[
follow
]
)"
></my-button>
<my-button
*ngIf=
"follow.state !== 'rejected'"
i18n-title
title=
"Re
ject
"
icon=
"cross"
(click)=
"rejectFollower(
[
follow
]
)"
></my-button>
<my-delete-button
*ngIf=
"follow.state === 'rejected'"
(click)=
"deleteFollower
(
follow)"
></my-delete-button>
<my-delete-button
*ngIf=
"follow.state === 'rejected'"
(click)=
"deleteFollower
s([
follow
]
)"
></my-delete-button>
</td>
<td>
<a
[href]=
"follow.follower.url"
i18n-title
title=
"Open actor page in a new tab"
target=
"_blank"
rel=
"noopener noreferrer"
>
{{
follow.f
ollower
.n
ame
+ '@' + follow.follower.host
}}
{{
buildF
ollower
N
ame
(follow)
}}
<my-global-icon
iconName=
"external-link"
></my-global-icon>
</a>
</td>
...
...
@@ -56,7 +72,7 @@
<ng-template
pTemplate=
"emptymessage"
>
<tr>
<td
colspan=
"
5
"
>
<td
colspan=
"
6
"
>
<div
class=
"no-results"
>
<ng-container
*ngIf=
"search"
i18n
>
No follower found matching current filters.
</ng-container>
<ng-container
*ngIf=
"!search"
i18n
>
Your instance doesn't have any follower.
</ng-container>
...
...
client/src/app/+admin/follows/followers-list/followers-list.component.ts
View file @
e3d6c643
import
{
SortMeta
}
from
'
primeng/api
'
import
{
Component
,
OnInit
}
from
'
@angular/core
'
import
{
ConfirmService
,
Notifier
,
RestPagination
,
RestTable
}
from
'
@app/core
'
import
{
prepareIcu
}
from
'
@app/helpers
'
import
{
AdvancedInputFilter
}
from
'
@app/shared/shared-forms
'
import
{
InstanceFollowService
}
from
'
@app/shared/shared-instance
'
import
{
DropdownAction
}
from
'
@app/shared/shared-main
'
import
{
ActorFollow
}
from
'
@shared/models
'
@
Component
({
...
...
@@ -16,7 +18,10 @@ export class FollowersListComponent extends RestTable implements OnInit {
sort
:
SortMeta
=
{
field
:
'
createdAt
'
,
order
:
-
1
}
pagination
:
RestPagination
=
{
count
:
this
.
rowsPerPage
,
start
:
0
}
searchFilters
:
AdvancedInputFilter
[]
searchFilters
:
AdvancedInputFilter
[]
=
[]
selectedFollows
:
ActorFollow
[]
=
[]
bulkFollowsActions
:
DropdownAction
<
ActorFollow
[]
>
[]
=
[]
constructor
(
private
confirmService
:
ConfirmService
,
...
...
@@ -24,66 +29,104 @@ export class FollowersListComponent extends RestTable implements OnInit {
private
followService
:
InstanceFollowService
)
{
super
()
this
.
searchFilters
=
this
.
followService
.
buildFollowsListFilters
()
}
ngOnInit
()
{
this
.
initialize
()
this
.
searchFilters
=
this
.
followService
.
buildFollowsListFilters
()
this
.
bulkFollowsActions
=
[
{
label
:
$localize
`Reject`
,
handler
:
follows
=>
this
.
rejectFollower
(
follows
),
isDisplayed
:
follows
=>
follows
.
every
(
f
=>
f
.
state
!==
'
rejected
'
)
},
{
label
:
$localize
`Accept`
,
handler
:
follows
=>
this
.
acceptFollower
(
follows
),
isDisplayed
:
follows
=>
follows
.
every
(
f
=>
f
.
state
!==
'
accepted
'
)
},
{
label
:
$localize
`Delete`
,
handler
:
follows
=>
this
.
deleteFollowers
(
follows
),
isDisplayed
:
follows
=>
follows
.
every
(
f
=>
f
.
state
===
'
rejected
'
)
}
]
}
getIdentifier
()
{
return
'
FollowersListComponent
'
}
acceptFollower
(
follow
:
ActorFollow
)
{
follow
.
state
=
'
accepted
'
this
.
followService
.
acceptFollower
(
follow
)
acceptFollower
(
follows
:
ActorFollow
[])
{
this
.
followService
.
acceptFollower
(
follows
)
.
subscribe
({
next
:
()
=>
{
const
handle
=
follow
.
follower
.
name
+
'
@
'
+
follow
.
follower
.
host
this
.
notifier
.
success
(
$localize
`
${
handle
}
accepted in instance followers`
)
// eslint-disable-next-line max-len
const
message
=
prepareIcu
(
$localize
`Accepted {count, plural, =1 {{followerName} follow request} other {{count} follow requests}}`
)(
{
count
:
follows
.
length
,
followerName
:
this
.
buildFollowerName
(
follows
[
0
])
},
$localize
`Follow requests accepted`
)
this
.
notifier
.
success
(
message
)
this
.
reloadData
()
},
error
:
err
=>
{
follow
.
state
=
'
pending
'
this
.
notifier
.
error
(
err
.
message
)
}
error
:
err
=>
this
.
notifier
.
error
(
err
.
message
)
})
}
async
rejectFollower
(
follow
:
ActorFollow
)
{
const
message
=
$localize
`Do you really want to reject this follower?`
async
rejectFollower
(
follows
:
ActorFollow
[])
{
// eslint-disable-next-line max-len
const
message
=
prepareIcu
(
$localize
`Do you really want to reject {count, plural, =1 {{followerName} follow request?} other {{count} follow requests?}}`
)(
{
count
:
follows
.
length
,
followerName
:
this
.
buildFollowerName
(
follows
[
0
])
},
$localize
`Do you really want to reject these follow requests?`
)
const
res
=
await
this
.
confirmService
.
confirm
(
message
,
$localize
`Reject`
)
if
(
res
===
false
)
return
this
.
followService
.
rejectFollower
(
follow
)
this
.
followService
.
rejectFollower
(
follow
s
)
.
subscribe
({
next
:
()
=>
{
const
handle
=
follow
.
follower
.
name
+
'
@
'
+
follow
.
follower
.
host
this
.
notifier
.
success
(
$localize
`
${
handle
}
rejected from instance followers`
)
// eslint-disable-next-line max-len
const
message
=
prepareIcu
(
$localize
`Rejected {count, plural, =1 {{followerName} follow request} other {{count} follow requests}}`
)(
{
count
:
follows
.
length
,
followerName
:
this
.
buildFollowerName
(
follows
[
0
])
},
$localize
`Follow requests rejected`
)
this
.
notifier
.
success
(
message
)
this
.
reloadData
()
},
error
:
err
=>
{
follow
.
state
=
'
pending
'
this
.
notifier
.
error
(
err
.
message
)
}
error
:
err
=>
this
.
notifier
.
error
(
err
.
message
)
})
}
async
deleteFollower
(
follow
:
ActorFollow
)
{
const
message
=
$localize
`Do you really want to delete this follower? It will be able to send again another follow request.`
async
deleteFollowers
(
follows
:
ActorFollow
[])
{
let
message
=
$localize
`Deleted followers will be able to send again a follow request.`
message
+=
'
<br /><br />
'
// eslint-disable-next-line max-len
message
+=
prepareIcu
(
$localize
`Do you really want to delete {count, plural, =1 {{followerName} follow request?} other {{count} follow requests?}}`
)(
{
count
:
follows
.
length
,
followerName
:
this
.
buildFollowerName
(
follows
[
0
])
},
$localize
`Do you really want to delete these follow requests?`
)
const
res
=
await
this
.
confirmService
.
confirm
(
message
,
$localize
`Delete`
)
if
(
res
===
false
)
return
this
.
followService
.
removeFollower
(
follow
)
this
.
followService
.
removeFollower
(
follow
s
)
.
subscribe
({
next
:
()
=>
{
const
handle
=
follow
.
follower
.
name
+
'
@
'
+
follow
.
follower
.
host
this
.
notifier
.
success
(
$localize
`
${
handle
}
removed from instance followers`
)
// eslint-disable-next-line max-len
const
message
=
prepareIcu
(
$localize
`Removed {count, plural, =1 {{followerName} follow request} other {{count} follow requests}}`
)(
{
count
:
follows
.
length
,
followerName
:
this
.
buildFollowerName
(
follows
[
0
])
},
$localize
`Follow requests removed`
)
this
.
notifier
.
success
(
message
)
this
.
reloadData
()
},
...
...
@@ -92,6 +135,14 @@ export class FollowersListComponent extends RestTable implements OnInit {
})
}
buildFollowerName
(
follow
:
ActorFollow
)
{
return
follow
.
follower
.
name
+
'
@
'
+
follow
.
follower
.
host
}
isInSelectionMode
()
{
return
this
.
selectedFollows
.
length
!==
0
}
protected
reloadData
()
{
this
.
followService
.
getFollowers
({
pagination
:
this
.
pagination
,
sort
:
this
.
sort
,
search
:
this
.
search
})
.
subscribe
({
...
...
client/src/app/+admin/follows/following-list/following-list.component.html
View file @
e3d6c643
...
...
@@ -9,11 +9,18 @@
[lazy]=
"true"
(onLazyLoad)=
"loadLazy($event)"
[lazyLoadOnInit]=
"false"
[showCurrentPageReport]=
"true"
i18n-currentPageReportTemplate
currentPageReportTemplate=
"Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} hosts"
[(selection)]=
"selectedFollows"
>
<ng-template
pTemplate=
"caption"
>
<div
class=
"caption"
>
<div
class=
"left-buttons"
>
<a
class=
"follow-button"
(click)=
"openFollowModal()"
(key.enter)=
"openFollowModal()"
>
<my-action-dropdown
*ngIf=
"isInSelectionMode()"
i18n-label
label=
"Batch actions"
theme=
"orange"
[actions]=
"bulkFollowsActions"
[entry]=
"selectedFollows"
>
</my-action-dropdown>
<a
*ngIf=
"!isInSelectionMode()"
class=
"follow-button"
(click)=
"openFollowModal()"
(key.enter)=
"openFollowModal()"
>
<my-global-icon
iconName=
"following"
aria-hidden=
"true"
></my-global-icon>
<ng-container
i18n
>
Follow
</ng-container>
</a>
...
...
@@ -27,6 +34,9 @@
<ng-template
pTemplate=
"header"
>
<tr>
<th
style=
"width: 40px"
>
<p-tableHeaderCheckbox
ariaLabel=
"Select all rows"
i18n-ariaLabel
></p-tableHeaderCheckbox>
</th>
<th
style=
"width: 150px;"
i18n
>
Action
</th>
<th
i18n
>
Following
</th>
<th
style=
"width: 100px;"
i18n
pSortableColumn=
"state"
>
State
<p-sortIcon
field=
"state"
></p-sortIcon></th>
...
...
@@ -35,14 +45,18 @@
</tr>
</ng-template>
<ng-template
pTemplate=
"body"
let-follow
>
<ng-template
pSelectableRow=
"follow"
pTemplate=
"body"
let-follow
>
<tr>
<td
class=
"checkbox-cell"
>
<p-tableCheckbox
[value]=
"follow"
ariaLabel=
"Select this row"
i18n-ariaLabel
></p-tableCheckbox>
</td>
<td
class=
"action-cell"
>
<my-delete-button
label
(click)=
"removeFollowing(follow)"
></my-delete-button>
<my-delete-button
label
(click)=
"removeFollowing(
[
follow
]
)"
></my-delete-button>
</td>
<td>
<a
[href]=
"follow.following.url"
i18n-title
title=
"Open instance in a new tab"
target=
"_blank"
rel=
"noopener noreferrer"
>
{{
follow.f
ollowing
.n
ame
+ '@' + follow.following.host
}}
{{
buildF
ollowing
N
ame
(follow)
}}
<my-global-icon
iconName=
"external-link"
></my-global-icon>
</a>
</td>
...
...
@@ -65,7 +79,7 @@
<ng-template
pTemplate=
"emptymessage"
>
<tr>
<td
colspan=
"
5
"
>
<td
colspan=
"
6
"
>
<div
class=
"no-results"
>
<ng-container
*ngIf=
"search"
i18n
>
No host found matching current filters.
</ng-container>
<ng-container
*ngIf=
"!search"
i18n
>
Your instance is not following anyone.
</ng-container>
...
...
client/src/app/+admin/follows/following-list/following-list.component.ts
View file @
e3d6c643
...
...
@@ -5,6 +5,8 @@ import { AdvancedInputFilter } from '@app/shared/shared-forms'
import
{
InstanceFollowService
}
from
'
@app/shared/shared-instance
'
import
{
ActorFollow
}
from
'
@shared/models
'
import
{
FollowModalComponent
}
from
'
./follow-modal.component
'
import
{
DropdownAction
}
from
'
@app/shared/shared-main
'
import
{
prepareIcu
}
from
'
@app/helpers
'
@
Component
({
templateUrl
:
'
./following-list.component.html
'
,
...
...
@@ -18,7 +20,10 @@ export class FollowingListComponent extends RestTable implements OnInit {
sort
:
SortMeta
=
{
field
:
'
createdAt
'
,
order
:
-
1
}
pagination
:
RestPagination
=
{
count
:
this
.
rowsPerPage
,
start
:
0
}
searchFilters
:
AdvancedInputFilter
[]
searchFilters
:
AdvancedInputFilter
[]
=
[]
selectedFollows
:
ActorFollow
[]
=
[]
bulkFollowsActions
:
DropdownAction
<
ActorFollow
[]
>
[]
=
[]
constructor
(
private
notifier
:
Notifier
,
...
...
@@ -26,12 +31,19 @@ export class FollowingListComponent extends RestTable implements OnInit {
private
followService
:
InstanceFollowService
)
{
super
()
this
.
searchFilters
=
this
.
followService
.
buildFollowsListFilters
()
}
ngOnInit
()
{
this
.
initialize
()
this
.
searchFilters
=
this
.
followService
.
buildFollowsListFilters
()
this
.
bulkFollowsActions
=
[
{
label
:
$localize
`Delete`
,
handler
:
follows
=>
this
.
removeFollowing
(
follows
)
}
]
}
getIdentifier
()
{
...
...
@@ -46,17 +58,33 @@ export class FollowingListComponent extends RestTable implements OnInit {
return
follow
.
following
.
name
===
'
peertube
'
}
async
removeFollowing
(
follow
:
ActorFollow
)
{
const
res
=
await
this
.
confirmService
.
confirm
(
$localize
`Do you really want to unfollow
${
follow
.
following
.
host
}
?`
,
$localize
`Unfollow`
isInSelectionMode
()
{
return
this
.
selectedFollows
.
length
!==
0
}
buildFollowingName
(
follow
:
ActorFollow
)
{
return
follow
.
following
.
name
+
'
@
'
+
follow
.
following
.
host
}
async
removeFollowing
(
follows
:
ActorFollow
[])
{
const
message
=
prepareIcu
(
$localize
`Do you really want to unfollow {count, plural, =1 {{entryName}?} other {{count} entries?}}`
)(
{
count
:
follows
.
length
,
entryName
:
this
.
buildFollowingName
(
follows
[
0
])
},
$localize
`Do you really want to unfollow these entries?`
)
const
res
=
await
this
.
confirmService
.
confirm
(
message
,
$localize
`Unfollow`
)
if
(
res
===
false
)
return
this
.
followService
.
unfollow
(
follow
)
this
.
followService
.
unfollow
(
follow
s
)
.
subscribe
({
next
:
()
=>
{
this
.
notifier
.
success
(
$localize
`You are not following
${
follow
.
following
.
host
}
anymore.`
)
// eslint-disable-next-line max-len
const
message
=
prepareIcu
(
$localize
`You are not following {count, plural, =1 {{entryName} anymore.} other {these {count} entries anymore.}}`
)(
{
count
:
follows
.
length
,
entryName
:
this
.
buildFollowingName
(
follows
[
0
])
},
$localize
`You are not following them anymore.`
)
this
.
notifier
.
success
(
message
)
this
.
reloadData
()
},
...
...
client/src/app/shared/shared-instance/instance-follow.service.ts
View file @
e3d6c643
import
{
SortMeta
}
from
'
primeng/api
'
import
{
Observable
}
from
'
rxjs
'
import
{
catchError
,
map
}
from
'
rxjs/operators
'
import
{
from
,
Observable
}
from
'
rxjs
'
import
{
catchError
,
concatMap
,
map
,
toArray
}
from
'
rxjs/operators
'
import
{
HttpClient
,
HttpParams
}
from
'
@angular/common/http
'
import
{
Injectable
}
from
'
@angular/core
'
import
{
RestExtractor
,
RestPagination
,
RestService
}
from
'
@app/core
'
import
{
arrayify
}
from
'
@shared/core-utils
'
import
{
ActivityPubActorType
,
ActorFollow
,
FollowState
,
ResultList
,
ServerFollowCreate
}
from
'
@shared/models
'
import
{
environment
}
from
'
../../../environments/environment
'
import
{
AdvancedInputFilter
}
from
'
../shared-forms
'
...
...
@@ -81,32 +82,64 @@ export class InstanceFollowService {
.
pipe
(
catchError
(
res
=>
this
.
restExtractor
.
handleError
(
res
)))
}
unfollow
(
follow
:
ActorFollow
)
{
const
handle
=
follow
.
following
.
name
+
'
@
'
+
follow
.
following
.
host
unfollow
(
follow
sArg
:
ActorFollow
[]
|
ActorFollow
)
{
const
follows
=
arrayify
(
followsArg
)
return
this
.
authHttp
.
delete
(
InstanceFollowService
.
BASE_APPLICATION_URL
+
'
/following/
'
+
handle
)
.
pipe
(
catchError
(
res
=>
this
.
restExtractor
.
handleError
(
res
)))
return
from
(
follows
)
.
pipe
(
concatMap
(
follow
=>
{
const
handle
=
follow
.
following
.
name
+
'
@
'
+
follow
.
following
.
host
return
this
.
authHttp
.
delete
(
InstanceFollowService
.
BASE_APPLICATION_URL
+
'
/following/
'
+
handle
)
}),
toArray
(),
catchError
(
err
=>
this
.
restExtractor
.
handleError
(
err
))
)
}
acceptFollower
(
follow
:
ActorFollow
)
{
const
handle
=
follow
.
follower
.
name
+
'
@
'
+
follow
.
follower
.
host
acceptFollower
(
follow
sArg
:
ActorFollow
[]
|
ActorFollow
)
{
const
follows
=
arrayify
(
followsArg
)
return
this
.
authHttp
.
post
(
`
${
InstanceFollowService
.
BASE_APPLICATION_URL
}
/followers/
${
handle
}
/accept`
,
{})
.
pipe
(
catchError
(
res
=>
this
.
restExtractor
.
handleError
(
res
)))
return
from
(
follows
)
.
pipe
(
concatMap
(
follow
=>
{
const
handle
=
follow
.
follower
.
name
+
'
@
'
+
follow
.
follower
.
host
return
this
.
authHttp
.
post
(
`
${
InstanceFollowService
.
BASE_APPLICATION_URL
}
/followers/
${
handle
}
/accept`
,
{})
}),
toArray
(),
catchError
(
err
=>
this
.
restExtractor
.
handleError
(
err
))
)
}
rejectFollower
(
follow
:
ActorFollow
)
{
const
handle
=
follow
.
follower
.
name
+
'
@
'
+
follow
.
follower
.
host
rejectFollower
(
follow
sArg
:
ActorFollow
[]
|
ActorFollow
)
{
const
follows
=
arrayify
(
followsArg
)
return
this
.
authHttp
.
post
(
`
${
InstanceFollowService
.
BASE_APPLICATION_URL
}
/followers/
${
handle
}
/reject`
,
{})
.
pipe
(
catchError
(
res
=>
this
.
restExtractor
.
handleError
(
res
)))
return
from
(
follows
)
.
pipe
(
concatMap
(
follow
=>
{
const
handle
=
follow
.
follower
.
name
+
'
@
'
+
follow
.
follower
.
host
return
this
.
authHttp
.
post
(
`
${
InstanceFollowService
.
BASE_APPLICATION_URL
}
/followers/
${
handle
}
/reject`
,
{})
}),
toArray
(),
catchError
(
err
=>
this
.
restExtractor
.
handleError
(
err
))
)
}
removeFollower
(
follow
:
ActorFollow
)
{
const
handle
=
follow
.
follower
.
name
+
'
@
'
+
follow
.
follower
.
host
removeFollower
(
follow
sArg
:
ActorFollow
[]
|
ActorFollow
)
{
const
follows
=
arrayify
(
followsArg
)
return
this
.
authHttp
.
delete
(
`
${
InstanceFollowService
.
BASE_APPLICATION_URL
}
/followers/
${
handle
}
`
)
.
pipe
(
catchError
(
res
=>
this
.
restExtractor
.
handleError
(
res
)))
return
from
(
follows
)
.
pipe
(
concatMap
(
follow
=>
{
const
handle
=
follow
.
follower
.
name
+
'
@
'
+
follow
.
follower
.
host
return
this
.
authHttp
.
delete
(
`
${
InstanceFollowService
.
BASE_APPLICATION_URL
}
/followers/
${
handle
}
`
)
}),
toArray
(),
catchError
(
err
=>
this
.
restExtractor
.
handleError
(
err
))
)
}
buildFollowsListFilters
():
AdvancedInputFilter
[]
{
...
...
client/src/app/shared/shared-main/video/video.service.ts
View file @
e3d6c643
...
...
@@ -5,6 +5,7 @@ import { HttpClient, HttpParams, HttpRequest } from '@angular/common/http'
import
{
Injectable
}
from
'
@angular/core
'
import
{
AuthService
,
ComponentPaginationLight
,
RestExtractor
,
RestService
,
ServerService
,
UserService
}
from
'
@app/core
'
import
{
objectToFormData
}
from
'
@app/helpers
'
import
{
arrayify
}
from
'
@shared/core-utils
'
import
{
BooleanBothQuery
,
FeedFormat
,
...
...
@@ -285,7 +286,7 @@ export class VideoService {
}
removeVideo
(
idArg
:
number
|
number
[])
{
const
ids
=
A
rray
.
isArra
y
(
idArg
)
?
idArg
:
[
idArg
]
const
ids
=
a
rray
if
y
(
idArg
)
return
from
(
ids
)
.
pipe
(
...
...
client/src/app/shared/shared-moderation/blocklist.service.ts
View file @
e3d6c643
...
...
@@ -4,6 +4,7 @@ import { catchError, concatMap, map, toArray } from 'rxjs/operators'
import
{
HttpClient
,
HttpParams
}
from
'
@angular/common/http
'
import
{
Injectable
}
from
'
@angular/core
'
import
{
RestExtractor
,
RestPagination
,
RestService
}
from
'
@app/core
'
import
{
arrayify
}
from
'
@shared/core-utils
'
import
{
AccountBlock
as
AccountBlockServer
,
BlockStatus
,
ResultList
,
ServerBlock
}
from
'
@shared/models
'
import
{
environment
}
from
'
../../../environments/environment
'
import
{
Account
}
from
'
../shared-main
'
...
...
@@ -122,7 +123,7 @@ export class BlocklistService {
}
blockAccountByInstance
(
accountsArg
:
Pick
<
Account
,
'
nameWithHost
'
>
|
Pick
<
Account
,
'
nameWithHost
'
>
[])
{
const
accounts
=
A
rray
.
isArra
y
(
accountsArg
)
?
accountsArg
:
[
accountsArg
]
const
accounts
=
a
rray
if
y
(
accountsArg
)
return
from
(
accounts
)
.
pipe
(
...
...
client/src/app/shared/shared-moderation/video-block.service.ts
View file @
e3d6c643
...
...
@@ -4,6 +4,7 @@ import { catchError, concatMap, map, toArray } from 'rxjs/operators'
import
{
HttpClient
,
HttpParams
}
from
'
@angular/common/http
'
import
{
Injectable
}
from
'
@angular/core
'
import
{
RestExtractor
,
RestPagination
,
RestService
}
from
'
@app/core
'
import
{
arrayify
}
from
'
@shared/core-utils
'
import
{
ResultList
,
VideoBlacklist
,
VideoBlacklistType
}
from
'
@shared/models
'
import
{
environment
}
from
'
../../../environments/environment
'
...
...
@@ -53,7 +54,7 @@ export class VideoBlockService {
}
unblockVideo
(
videoIdArgs
:
number
|
number
[])
{
const
videoIds
=
A
rray
.
isArra
y
(
videoIdArgs
)
?
videoIdArgs
:
[
videoIdArgs
]
const
videoIds
=
a
rray
if
y
(
videoIdArgs
)
return
observableFrom
(
videoIds
)
.
pipe
(
...
...
client/src/app/shared/shared-users/user-admin.service.ts
View file @
e3d6c643
...
...
@@ -5,6 +5,7 @@ import { HttpClient, HttpParams } from '@angular/common/http'
import
{
Injectable
}
from
'
@angular/core
'
import
{
RestExtractor
,
RestPagination
,
RestService
,
UserService
}
from
'
@app/core
'
import
{
getBytes
}
from
'
@root-helpers/bytes
'
import
{
arrayify
}
from
'
@shared/core-utils
'
import
{
ResultList
,
User
as
UserServerModel
,
UserCreate
,
UserRole
,
UserUpdate
}
from
'
@shared/models
'
@
Injectable
()
...
...
@@ -65,7 +66,7 @@ export class UserAdminService {
}
removeUser
(
usersArg
:
UserServerModel
|
UserServerModel
[])
{
const
users
=
A
rray
.
isArra
y
(
usersArg
)
?
usersArg
:
[
usersArg
]
const
users
=
a
rray
if
y
(
usersArg
)
return
from
(
users
)
.
pipe
(
...
...
@@ -77,7 +78,7 @@ export class UserAdminService {
banUsers
(
usersArg
:
UserServerModel
|
UserServerModel
[],
reason
?:
string
)
{
const
body
=
reason
?
{
reason
}
:
{}
const
users
=
A
rray
.
isArra
y
(
usersArg
)
?
usersArg
:
[
usersArg
]
const
users
=
a
rray
if
y
(
usersArg
)
return
from
(
users
)
.
pipe
(
...
...
@@ -88,7 +89,7 @@ export class UserAdminService {
}
unbanUsers
(
usersArg
:
UserServerModel
|
UserServerModel
[])
{
const
users
=
A
rray
.
isArra
y
(
usersArg
)
?
usersArg
:
[
usersArg
]
const
users
=
a
rray
if
y
(
usersArg
)
return
from
(
users
)
.
pipe
(
...
...
server/models/actor/actor-follow.ts
View file @
e3d6c643
...
...
@@ -276,7 +276,7 @@ export class ActorFollowModel extends Model<Partial<AttributesOnly<ActorFollowMo
})
}
const
where
:
WhereAttributeHash
<
Attributes
<
ActorFollowModel
>>
=
{
actorId
}
const
where
:
WhereAttributeHash
<
Attributes
<
ActorFollowModel
>>
=
{
actorId
}
if
(
state
)
where
.
state
=
state
const
query
:
FindOptions
<
Attributes
<
ActorFollowModel
>>
=
{
...
...
shared/core-utils/common/array.ts
View file @
e3d6c643
...
...
@@ -8,6 +8,14 @@ function findCommonElement <T> (array1: T[], array2: T[]) {
return
null
}
// Avoid conflict with other toArray() functions
function
arrayify
<
T
>
(
element
:
T
|
T
[])
{
if
(
Array
.
isArray
(
element
))
return
element