Implement auto follow in client
authorChocobozzz <me@florianbigard.com>
Wed, 4 Sep 2019 12:30:34 +0000 (14:30 +0200)
committerChocobozzz <chocobozzz@cpy.re>
Wed, 4 Sep 2019 14:24:58 +0000 (16:24 +0200)
client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts
client/src/app/shared/forms/form-validators/custom-config-validators.service.ts
client/src/app/shared/users/user-notification.model.ts
client/src/app/shared/users/user-notifications.component.html
server/initializers/constants.ts
server/initializers/migrations/0430-auto-follow-notification-setting.ts [new file with mode: 0644]

index fe9d856d050161c5756419129ccd54f06ec9d281..ec6f879d7046a262e65278a607f677c295aaab40 100644 (file)
           </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>
 
index 8bd7f7cf6e3ad12254c7af568067d97f24a71bd9..d5110456908c5c39ac42cc853645b113d6fb7e38 100644 (file)
@@ -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
+          }
+        }
       }
     }
 
index 34febc4577462aa5d62e7a42b370c0e6689422df..76fabb19d905aab08835395878c4ae25c9abe0cb 100644 (file)
@@ -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
index 882e39453c982afd864f0b5f108f48f32963583f..767e3f026844632ae6a786067a7c79196de6e8ec 100644 (file)
@@ -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')
+      }
+    }
   }
 }
index 37fa29ee814e2fdf56fd8136a88f5b9c27c98932..b4ac075c5920cafdc82f816bae83bd0f6eaa279b 100644 (file)
@@ -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
index 29281342607a5d37f75837c01823005f6453c96d..0702d3b5e0f1c7af949437fef8c7cb3f000e48dc 100644 (file)
@@ -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>
 
           <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>
index 7c0c5a87ceaf65c89869344520999a54786f38b8..01d4f1d74aebb8ec61164129a9b987f333e7b54b 100644 (file)
@@ -14,7 +14,7 @@ import { CONFIG, registerConfigChangedHandler } from './config'
 
 // ---------------------------------------------------------------------------
 
-const LAST_MIGRATION_VERSION = 425
+const LAST_MIGRATION_VERSION = 430
 
 // ---------------------------------------------------------------------------
 
diff --git a/server/initializers/migrations/0430-auto-follow-notification-setting.ts b/server/initializers/migrations/0430-auto-follow-notification-setting.ts
new file mode 100644 (file)
index 0000000..034bdd4
--- /dev/null
@@ -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
+}