Browse Source

Implement auto follow in client

Chocobozzz 4 years ago
parent
commit
e1b49ee534

+ 35 - 0
client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html

@@ -221,6 +221,41 @@
           </ng-container>
         </ng-container>
 
+        <div i18n class="inner-form-title">Instance followings</div>
+
+        <ng-container formGroupName="followings">
+          <ng-container formGroupName="instance">
+
+            <ng-container formGroupName="autoFollowBack">
+              <div class="form-group">
+                <my-peertube-checkbox
+                  inputName="followingsInstanceAutoFollowBackEnabled" formControlName="enabled"
+                  i18n-labelText labelText="Automatically follow other instances that follow you"
+                ></my-peertube-checkbox>
+              </div>
+            </ng-container>
+
+            <ng-container formGroupName="autoFollowIndex">
+              <div class="form-group">
+                <my-peertube-checkbox
+                  inputName="followingsInstanceAutoFollowIndexEnabled" formControlName="enabled"
+                  i18n-labelText labelText="Automatically follow instance of the public index (below)"
+                ></my-peertube-checkbox>
+              </div>
+
+              <div class="form-group">
+                <label i18n for="followingsInstanceAutoFollowIndexUrl">Index URL</label>
+                <input
+                  type="text" id="followingsInstanceAutoFollowIndexUrl"
+                  formControlName="indexUrl" [ngClass]="{ 'input-error': formErrors['followings.instance.autoFollowIndex.indexUrl'] }"
+                >
+                <div *ngIf="formErrors.followings.instance.autoFollowIndex.indexUrl" class="form-error">{{ formErrors.followings.instance.autoFollowIndex.indexUrl }}</div>
+              </div>
+
+            </ng-container>
+          </ng-container>
+        </ng-container>
+
 
         <div i18n class="inner-form-title">Administrator</div>
 

+ 11 - 0
client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts

@@ -158,6 +158,17 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
           enabled: null,
           manualApproval: null
         }
+      },
+      followings: {
+        instance: {
+          autoFollowBack: {
+            enabled: null
+          },
+          autoFollowIndex: {
+            enabled: null,
+            indexUrl: this.customConfigValidatorsService.INDEX_URL
+          }
+        }
       }
     }
 

+ 4 - 2
client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts

@@ -43,7 +43,8 @@ export class MyAccountNotificationPreferencesComponent implements OnInit {
       newUserRegistration: this.i18n('A new user registered on your instance'),
       newFollow: this.i18n('You or your channel(s) has a new follower'),
       commentMention: this.i18n('Someone mentioned you in video comments'),
-      newInstanceFollower: this.i18n('Your instance has a new follower')
+      newInstanceFollower: this.i18n('Your instance has a new follower'),
+      autoInstanceFollowing: this.i18n('Your instance auto followed another instance')
     }
     this.notificationSettingKeys = Object.keys(this.labelNotifications) as (keyof UserNotificationSetting)[]
 
@@ -51,7 +52,8 @@ export class MyAccountNotificationPreferencesComponent implements OnInit {
       videoAbuseAsModerator: UserRight.MANAGE_VIDEO_ABUSES,
       videoAutoBlacklistAsModerator: UserRight.MANAGE_VIDEO_BLACKLIST,
       newUserRegistration: UserRight.MANAGE_USERS,
-      newInstanceFollower: UserRight.MANAGE_SERVER_FOLLOW
+      newInstanceFollower: UserRight.MANAGE_SERVER_FOLLOW,
+      autoInstanceFollowing: UserRight.MANAGE_CONFIGURATION
     }
 
     this.emailEnabled = this.serverService.getConfig().email.enabled

+ 9 - 0
client/src/app/shared/forms/form-validators/custom-config-validators.service.ts

@@ -13,6 +13,7 @@ export class CustomConfigValidatorsService {
   readonly SIGNUP_LIMIT: BuildFormValidator
   readonly ADMIN_EMAIL: BuildFormValidator
   readonly TRANSCODING_THREADS: BuildFormValidator
+  readonly INDEX_URL: BuildFormValidator
 
   constructor (private i18n: I18n) {
     this.INSTANCE_NAME = {
@@ -78,5 +79,13 @@ export class CustomConfigValidatorsService {
         'min': this.i18n('Transcoding threads must be greater or equal to 0.')
       }
     }
+
+    this.INDEX_URL = {
+      VALIDATORS: [ Validators.required, Validators.pattern(/^https:\/\//) ],
+      MESSAGES: {
+        'required': this.i18n('Index URL is required.'),
+        'pattern': this.i18n('Index URL should be a URL')
+      }
+    }
   }
 }

+ 6 - 1
client/src/app/shared/users/user-notification.model.ts

@@ -42,9 +42,10 @@ export class UserNotification implements UserNotificationServer {
     state: FollowState
     follower: ActorInfo & { avatarUrl?: string }
     following: {
-      type: 'account' | 'channel'
+      type: 'account' | 'channel' | 'instance'
       name: string
       displayName: string
+      host: string
     }
   }
 
@@ -146,6 +147,10 @@ export class UserNotification implements UserNotificationServer {
         case UserNotificationType.NEW_INSTANCE_FOLLOWER:
           this.instanceFollowUrl = '/admin/follows/followers-list'
           break
+
+        case UserNotificationType.AUTO_INSTANCE_FOLLOWING:
+          this.instanceFollowUrl = '/admin/follows/following-list'
+          break
       }
     } catch (err) {
       this.type = null

+ 9 - 1
client/src/app/shared/users/user-notifications.component.html

@@ -40,7 +40,7 @@
         <my-global-icon iconName="no"></my-global-icon>
 
         <div class="message">
-          The recently added video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.video.name }}</a> has been <a (click)="markAsRead(notification)" [routerLink]="notification.videoAutoBlacklistUrl">auto-blacklisted</a>
+          The recently added video <a (click)="markAsRead(notification)" [routerLink]="notification.videoUrl">{{ notification.videoBlacklist.video.name }}</a> has been <a (click)="markAsRead(notification)" [routerLink]="notification.videoAutoBlacklistUrl">auto-blacklisted</a>
         </div>
       </ng-container>
 
@@ -111,6 +111,14 @@
           <ng-container *ngIf="notification.actorFollow.state === 'pending'"> awaiting your approval</ng-container>
         </div>
       </ng-container>
+
+      <ng-container i18n *ngSwitchCase="UserNotificationType.AUTO_INSTANCE_FOLLOWING">
+        <my-global-icon iconName="users"></my-global-icon>
+
+        <div class="message">
+          Your instance automatically followed <a (click)="markAsRead(notification)" [routerLink]="notification.instanceFollowUrl">{{ notification.actorFollow.following.host }}</a>
+        </div>
+      </ng-container>
     </ng-container>
 
     <div class="from-date">{{ notification.createdAt | myFromNow }}</div>

+ 1 - 1
server/initializers/constants.ts

@@ -14,7 +14,7 @@ import { CONFIG, registerConfigChangedHandler } from './config'
 
 // ---------------------------------------------------------------------------
 
-const LAST_MIGRATION_VERSION = 425
+const LAST_MIGRATION_VERSION = 430
 
 // ---------------------------------------------------------------------------
 

+ 40 - 0
server/initializers/migrations/0430-auto-follow-notification-setting.ts

@@ -0,0 +1,40 @@
+import * as Sequelize from 'sequelize'
+
+async function up (utils: {
+  transaction: Sequelize.Transaction,
+  queryInterface: Sequelize.QueryInterface,
+  sequelize: Sequelize.Sequelize,
+  db: any
+}): Promise<void> {
+  {
+    const data = {
+      type: Sequelize.INTEGER,
+      defaultValue: null,
+      allowNull: true
+    }
+    await utils.queryInterface.addColumn('userNotificationSetting', 'autoInstanceFollowing', data)
+  }
+
+  {
+    const query = 'UPDATE "userNotificationSetting" SET "autoInstanceFollowing" = 1'
+    await utils.sequelize.query(query)
+  }
+
+  {
+    const data = {
+      type: Sequelize.INTEGER,
+      defaultValue: null,
+      allowNull: false
+    }
+    await utils.queryInterface.changeColumn('userNotificationSetting', 'autoInstanceFollowing', data)
+  }
+}
+
+function down (options) {
+  throw new Error('Not implemented.')
+}
+
+export {
+  up,
+  down
+}