]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/models/video/video-playlist.ts
Search typeahead initial design
[github/Chocobozzz/PeerTube.git] / server / models / video / video-playlist.ts
index ef87a7ee9586f757d7dc6ca9a67d9c1d8c7a3550..4ca17ebec0126f49ace0f97be84c932f5f2e19ea 100644 (file)
@@ -13,11 +13,10 @@ import {
   Model,
   Scopes,
   Table,
-  UpdatedAt,
-  Sequelize
+  UpdatedAt
 } from 'sequelize-typescript'
 import { VideoPlaylistPrivacy } from '../../../shared/models/videos/playlist/video-playlist-privacy.model'
-import { buildServerIdsFollowedBy, buildWhereIdOrUUID, getSort, isOutdated, throwIfNotValid, createSimilarityAttribute } from '../utils'
+import { buildServerIdsFollowedBy, buildWhereIdOrUUID, getSort, isOutdated, throwIfNotValid } from '../utils'
 import {
   isVideoPlaylistDescriptionValid,
   isVideoPlaylistNameValid,
@@ -46,7 +45,8 @@ import { ActivityIconObject } from '../../../shared/models/activitypub/objects'
 import { FindOptions, literal, Op, ScopeOptions, Transaction, WhereOptions } from 'sequelize'
 import * as Bluebird from 'bluebird'
 import {
-  MVideoPlaylistAccountThumbnail, MVideoPlaylistAP,
+  MVideoPlaylistAccountThumbnail,
+  MVideoPlaylistAP,
   MVideoPlaylistFormattable,
   MVideoPlaylistFull,
   MVideoPlaylistFullSummary,
@@ -68,12 +68,12 @@ type AvailableForListOptions = {
   type?: VideoPlaylistType
   accountId?: number
   videoChannelId?: number
-  privateAndUnlisted?: boolean,
+  listMyPlaylists?: boolean
   search?: string
 }
 
 @Scopes(() => ({
-  [ ScopeNames.WITH_THUMBNAIL ]: {
+  [ScopeNames.WITH_THUMBNAIL]: {
     include: [
       {
         model: ThumbnailModel,
@@ -81,7 +81,7 @@ type AvailableForListOptions = {
       }
     ]
   },
-  [ ScopeNames.WITH_VIDEOS_LENGTH ]: {
+  [ScopeNames.WITH_VIDEOS_LENGTH]: {
     attributes: {
       include: [
         [
@@ -91,7 +91,7 @@ type AvailableForListOptions = {
       ]
     }
   } as FindOptions,
-  [ ScopeNames.WITH_ACCOUNT ]: {
+  [ScopeNames.WITH_ACCOUNT]: {
     include: [
       {
         model: AccountModel,
@@ -99,7 +99,7 @@ type AvailableForListOptions = {
       }
     ]
   },
-  [ ScopeNames.WITH_ACCOUNT_AND_CHANNEL_SUMMARY ]: {
+  [ScopeNames.WITH_ACCOUNT_AND_CHANNEL_SUMMARY]: {
     include: [
       {
         model: AccountModel.scope(AccountScopeNames.SUMMARY),
@@ -111,7 +111,7 @@ type AvailableForListOptions = {
       }
     ]
   },
-  [ ScopeNames.WITH_ACCOUNT_AND_CHANNEL ]: {
+  [ScopeNames.WITH_ACCOUNT_AND_CHANNEL]: {
     include: [
       {
         model: AccountModel,
@@ -123,28 +123,32 @@ type AvailableForListOptions = {
       }
     ]
   },
-  [ ScopeNames.AVAILABLE_FOR_LIST ]: (options: AvailableForListOptions) => {
-    // Only list local playlists OR playlists that are on an instance followed by actorId
-    const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId)
-    const whereActor = {
-      [ Op.or ]: [
-        {
-          serverId: null
-        },
-        {
-          serverId: {
-            [ Op.in ]: literal(inQueryInstanceFollow)
-          }
-        }
-      ]
-    }
+  [ScopeNames.AVAILABLE_FOR_LIST]: (options: AvailableForListOptions) => {
+
+    let whereActor: WhereOptions = {}
 
     const whereAnd: WhereOptions[] = []
 
-    if (options.privateAndUnlisted !== true) {
+    if (options.listMyPlaylists !== true) {
       whereAnd.push({
         privacy: VideoPlaylistPrivacy.PUBLIC
       })
+
+      // Only list local playlists OR playlists that are on an instance followed by actorId
+      const inQueryInstanceFollow = buildServerIdsFollowedBy(options.followerActorId)
+
+      whereActor = {
+        [Op.or]: [
+          {
+            serverId: null
+          },
+          {
+            serverId: {
+              [Op.in]: literal(inQueryInstanceFollow)
+            }
+          }
+        ]
+      }
     }
 
     if (options.accountId) {
@@ -166,18 +170,9 @@ type AvailableForListOptions = {
     }
 
     if (options.search) {
-      const escapedSearch = VideoPlaylistModel.sequelize.escape(options.search)
-      const escapedLikeSearch = VideoPlaylistModel.sequelize.escape('%' + options.search + '%')
       whereAnd.push({
-        id: {
-          [ Op.in ]: Sequelize.literal(
-            '(' +
-            'SELECT "videoPlaylist"."id" FROM "videoPlaylist" ' +
-            'WHERE ' +
-            'lower(immutable_unaccent("videoPlaylist"."name")) % lower(immutable_unaccent(' + escapedSearch + ')) OR ' +
-            'lower(immutable_unaccent("videoPlaylist"."name")) LIKE lower(immutable_unaccent(' + escapedLikeSearch + '))' +
-            ')'
-          )
+        name: {
+          [Op.iLike]: '%' + options.search + '%'
         }
       })
     }
@@ -304,13 +299,13 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
 
   static listForApi (options: {
     followerActorId: number
-    start: number,
-    count: number,
-    sort: string,
-    type?: VideoPlaylistType,
-    accountId?: number,
-    videoChannelId?: number,
-    privateAndUnlisted?: boolean,
+    start: number
+    count: number
+    sort: string
+    type?: VideoPlaylistType
+    accountId?: number
+    videoChannelId?: number
+    listMyPlaylists?: boolean
     search?: string
   }) {
     const query = {
@@ -328,7 +323,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
             followerActorId: options.followerActorId,
             accountId: options.accountId,
             videoChannelId: options.videoChannelId,
-            privateAndUnlisted: options.privateAndUnlisted,
+            listMyPlaylists: options.listMyPlaylists,
             search: options.search
           } as AvailableForListOptions
         ]
@@ -374,7 +369,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
           model: VideoPlaylistElementModel.unscoped(),
           where: {
             videoId: {
-              [Op.in]: videoIds // FIXME: sequelize ANY seems broken
+              [Op.in]: videoIds
             }
           },
           required: true