Add ability to unfollow a server

pull/128/head
Chocobozzz 2017-11-20 11:19:23 +01:00
parent 892211e849
commit 7e9334c34d
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
13 changed files with 85 additions and 26 deletions

View File

@ -7,9 +7,9 @@
sortField="createdAt" (onLazyLoad)="loadLazy($event)"
>
<p-column field="id" header="ID"></p-column>
<p-column field="host" header="Host"></p-column>
<p-column field="follower.host" header="Host"></p-column>
<p-column field="email" header="Email"></p-column>
<p-column field="score" header="Score"></p-column>
<p-column field="follower.score" header="Score"></p-column>
<p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
</p-dataTable>
</div>

View File

@ -7,10 +7,15 @@
sortField="createdAt" (onLazyLoad)="loadLazy($event)"
>
<p-column field="id" header="ID"></p-column>
<p-column field="host" header="Host"></p-column>
<p-column field="following.host" header="Host"></p-column>
<p-column field="email" header="Email"></p-column>
<p-column field="score" header="Score"></p-column>
<p-column field="following.score" header="Score"></p-column>
<p-column field="createdAt" header="Created date" [sortable]="true"></p-column>
<p-column header="Unfollow" styleClass="action-cell">
<ng-template pTemplate="body" let-following="rowData">
<span (click)="removeFollowing(following)" class="glyphicon glyphicon-remove glyphicon-black" title="Unfollow"></span>
</ng-template>
</p-column>
</p-dataTable>
</div>
</div>

View File

@ -2,6 +2,7 @@ import { Component } from '@angular/core'
import { NotificationsService } from 'angular2-notifications'
import { SortMeta } from 'primeng/primeng'
import { AccountFollow } from '../../../../../../shared/models/accounts/follow.model'
import { ConfirmService } from '../../../core/confirm/confirm.service'
import { RestPagination, RestTable } from '../../../shared'
import { FollowService } from '../shared'
@ -18,11 +19,29 @@ export class FollowingListComponent extends RestTable {
constructor (
private notificationsService: NotificationsService,
private confirmService: ConfirmService,
private followService: FollowService
) {
super()
}
removeFollowing (follow: AccountFollow) {
this.confirmService.confirm(`Do you really want to unfollow ${follow.following.host}?`, 'Unfollow').subscribe(
res => {
if (res === false) return
this.followService.unfollow(follow).subscribe(
() => {
this.notificationsService.success('Success', `You are not following ${follow.following.host} anymore.`)
this.loadData()
},
err => this.notificationsService.error('Error', err.message)
)
}
)
}
protected loadData () {
this.followService.getFollowing(this.pagination, this.sort)
.subscribe(

View File

@ -37,7 +37,7 @@ export class FollowService {
.catch(res => this.restExtractor.handleError(res))
}
follow (notEmptyHosts: String[]) {
follow (notEmptyHosts: string[]) {
const body = {
hosts: notEmptyHosts
}
@ -46,4 +46,10 @@ export class FollowService {
.map(this.restExtractor.extractDataBool)
.catch(res => this.restExtractor.handleError(res))
}
unfollow (follow: AccountFollow) {
return this.authHttp.delete(FollowService.BASE_APPLICATION_URL + '/following/' + follow.following.id)
.map(this.restExtractor.extractDataBool)
.catch(res => this.restExtractor.handleError(res))
}
}

View File

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core'
import { Component } from '@angular/core'
import { SortMeta } from 'primeng/components/common/sortmeta'
import { NotificationsService } from 'angular2-notifications'
@ -12,7 +12,7 @@ import { UserService } from '../shared'
templateUrl: './user-list.component.html',
styleUrls: [ './user-list.component.scss' ]
})
export class UserListComponent extends RestTable implements OnInit {
export class UserListComponent extends RestTable {
users: User[] = []
totalRecords = 0
rowsPerPage = 10
@ -27,10 +27,6 @@ export class UserListComponent extends RestTable implements OnInit {
super()
}
ngOnInit () {
this.loadData()
}
removeUser (user: User) {
if (user.username === 'root') {
this.notificationsService.error('Error', 'You cannot delete root.')

View File

@ -134,7 +134,7 @@ const CONSTRAINTS_FIELDS = {
VIEWS: { min: 0 },
LIKES: { min: 0 },
DISLIKES: { min: 0 },
FILE_SIZE: { min: 10, max: 1024 * 1024 * 1024 * 3 /* 3Go */ },
FILE_SIZE: { min: 10, max: 1024 * 1024 * 1024 * 10 /* 10Go */ },
URL: { min: 3, max: 2000 } // Length
},
ACCOUNTS: {

View File

@ -10,7 +10,7 @@ async function processUndoActivity (activity: ActivityUndo) {
const following = await db.Account.loadByUrl(activityToUndo.object)
const accountFollow = await db.AccountFollow.loadByAccountAndTarget(follower.id, following.id)
if (!accountFollow) throw new Error(`'Unknown account follow (${follower.id} -> ${following.id}.`)
if (!accountFollow) throw new Error(`'Unknown account follow ${follower.id} -> ${following.id}.`)
await accountFollow.destroy()

View File

@ -1,12 +1,12 @@
import * as express from 'express'
import { body } from 'express-validator/check'
import { body, param } from 'express-validator/check'
import { isTestInstance } from '../../helpers/core-utils'
import { isAccountIdValid } from '../../helpers/custom-validators/activitypub/account'
import { isEachUniqueHostValid } from '../../helpers/custom-validators/servers'
import { logger } from '../../helpers/logger'
import { CONFIG, database as db } from '../../initializers'
import { checkErrors } from './utils'
import { getServerAccount } from '../../helpers/utils'
import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
const followValidator = [
body('hosts').custom(isEachUniqueHostValid).withMessage('Should have an array of unique hosts'),
@ -28,7 +28,7 @@ const followValidator = [
]
const removeFollowingValidator = [
body('accountId').custom(isAccountIdValid).withMessage('Should have a valid account id'),
param('accountId').custom(isIdOrUUIDValid).withMessage('Should have a valid account id'),
(req: express.Request, res: express.Response, next: express.NextFunction) => {
logger.debug('Checking follow parameters', { parameters: req.body })

View File

@ -1,18 +1,19 @@
import * as Sequelize from 'sequelize'
import * as Bluebird from 'bluebird'
import { FollowState } from '../../../shared/models/accounts/follow.model'
import * as Sequelize from 'sequelize'
import { AccountFollow, FollowState } from '../../../shared/models/accounts/follow.model'
import { ResultList } from '../../../shared/models/result-list.model'
import { AccountInstance } from './account-interface'
export namespace AccountFollowMethods {
export type LoadByAccountAndTarget = (accountId: number, targetAccountId: number) => Bluebird<AccountFollowInstance>
export type ListFollowingForApi = (id: number, start: number, count: number, sort: string) => Bluebird< ResultList<AccountInstance> >
export type ListFollowersForApi = (id: number, start: number, count: number, sort: string) => Bluebird< ResultList<AccountInstance> >
export type ListFollowingForApi = (id: number, start: number, count: number, sort: string) => Bluebird< ResultList<AccountFollowInstance>>
export type ListFollowersForApi = (id: number, start: number, count: number, sort: string) => Bluebird< ResultList<AccountFollowInstance>>
export type ListAcceptedFollowerUrlsForApi = (accountId: number[], start?: number, count?: number) => Promise< ResultList<string> >
export type ListAcceptedFollowingUrlsForApi = (accountId: number[], start?: number, count?: number) => Promise< ResultList<string> >
export type ListAcceptedFollowerSharedInboxUrls = (accountId: number[]) => Promise< ResultList<string> >
export type ToFormattedJSON = (this: AccountFollowInstance) => AccountFollow
}
export interface AccountFollowClass {
@ -38,6 +39,8 @@ export interface AccountFollowInstance extends AccountFollowClass, AccountFollow
AccountFollower?: AccountInstance
AccountFollowing?: AccountInstance
toFormattedJSON: AccountFollowMethods.ToFormattedJSON
}
export interface AccountFollowModel extends AccountFollowClass, Sequelize.Model<AccountFollowInstance, AccountFollowAttributes> {}

View File

@ -12,6 +12,7 @@ let listFollowersForApi: AccountFollowMethods.ListFollowersForApi
let listAcceptedFollowerUrlsForApi: AccountFollowMethods.ListAcceptedFollowerUrlsForApi
let listAcceptedFollowingUrlsForApi: AccountFollowMethods.ListAcceptedFollowingUrlsForApi
let listAcceptedFollowerSharedInboxUrls: AccountFollowMethods.ListAcceptedFollowerSharedInboxUrls
let toFormattedJSON: AccountFollowMethods.ToFormattedJSON
export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
AccountFollow = sequelize.define<AccountFollowInstance, AccountFollowAttributes>('AccountFollow',
@ -46,7 +47,10 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
listAcceptedFollowingUrlsForApi,
listAcceptedFollowerSharedInboxUrls
]
addMethodsToModel(AccountFollow, classMethods)
const instanceMethods = [
toFormattedJSON
]
addMethodsToModel(AccountFollow, classMethods, instanceMethods)
return AccountFollow
}
@ -73,6 +77,22 @@ function associate (models) {
})
}
toFormattedJSON = function (this: AccountFollowInstance) {
const follower = this.AccountFollower.toFormattedJSON()
const following = this.AccountFollowing.toFormattedJSON()
const json = {
id: this.id,
follower,
following,
state: this.state,
createdAt: this.createdAt,
updatedAt: this.updatedAt
}
return json
}
loadByAccountAndTarget = function (accountId: number, targetAccountId: number) {
const query = {
where: {
@ -122,7 +142,7 @@ listFollowingForApi = function (id: number, start: number, count: number, sort:
return AccountFollow.findAndCountAll(query).then(({ rows, count }) => {
return {
data: rows.map(r => r.AccountFollowing),
data: rows,
total: count
}
})
@ -154,7 +174,7 @@ listFollowersForApi = function (id: number, start: number, count: number, sort:
return AccountFollow.findAndCountAll(query).then(({ rows, count }) => {
return {
data: rows.map(r => r.AccountFollower),
data: rows,
total: count
}
})

View File

@ -1,8 +1,12 @@
import { Account } from './account.model'
export type FollowState = 'pending' | 'accepted'
export interface AccountFollow {
id: number
name: string
score?: number // Used for followers
host: string
follower: Account
following: Account
state: FollowState
createdAt: Date
updatedAt: Date
}

View File

@ -10,6 +10,9 @@ server {
# For the video upload
client_max_body_size 2G;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
}
# Bypass PeerTube webseed route for better performances

View File

@ -23,6 +23,9 @@ server {
# For the video upload
client_max_body_size 2G;
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
}
# Bypass PeerTube webseed route for better performances