@@ -716,21 +716,58 @@ export function searchSessions(sessions: t.SessionUIListing[], searchQuery: stri
716716 if ( ! searchQueryNorm ) return sessions ;
717717
718718 const tokens = searchQueryNorm . split ( / \s + / ) ;
719- return sessions . filter ( listing => doFieldsIncludeTokens ( getFields ( listing . head ) ) ) ;
719+
720+ let pairs = sessions . map ( listing => ( {
721+ listing,
722+ score :
723+ ( ( getTokensMatchScore ( getFields ( listing . head ) ) *
724+ ( listing . publication ? listing . publication . likes * 20 + listing . publication . views : 1 ) ) /
725+ 10 ) *
726+ ( listing . head . isClip ? 1 : 2 ) ,
727+ } ) ) ;
728+ pairs = _ . filter ( pairs , 'score' ) ;
729+ pairs = _ . orderBy ( pairs , 'score' , 'desc' ) ;
730+ return _ . map ( pairs , 'listing' ) ;
720731
721732 function getFields ( head : t . SessionHead ) : string [ ] {
722733 return [
723734 `@${ head . author ?? '' } /${ head . handle } ` ,
724735 head . title ,
736+ head . toc . map ( item => item . title ) . join ( ' ' ) ,
725737 head . description ,
726- ...head . toc . map ( item => item . title ) ,
727738 ] . map ( str => str ?. toLowerCase ( ) ) ;
728739 }
729740
730- function doFieldsIncludeTokens ( fields : string [ ] ) {
731- return tokens . every ( token => doFieldsIncludeToken ( fields , token ) ) ;
741+ function getTokensMatchScore ( fields : string [ ] ) : number {
742+ let score = 0 ;
743+ for ( const token of tokens ) {
744+ let tokenMatchScore = getTokenMatchScore ( fields , token ) ;
745+ if ( ! tokenMatchScore ) return 0 ; // all tokens must match
746+ score += tokenMatchScore ;
747+ }
748+ return score ;
749+ }
750+ function getTokenMatchScore ( fields : string [ ] , token : string ) : number {
751+ let score = 0 ;
752+ for ( let i = 0 ; i < fields . length ; i ++ ) {
753+ if ( fields [ i ] . includes ( token ) ) {
754+ score += ( fields . length - i ) ** 2 * ( token . length / fields [ i ] . length ) ;
755+ }
756+ }
757+
758+ return score ;
732759 }
733- function doFieldsIncludeToken ( fields : string [ ] , token : string ) {
734- return fields . some ( field => field . includes ( token ) ) ;
760+ }
761+
762+ export function limitRecentSessions ( sessions : t . SessionUIListing [ ] , limit : number ) : t . SessionUIListing [ ] {
763+ let res = [ ] ;
764+ let count = 0 ;
765+ for ( const listing of sessions ) {
766+ if ( listing . group === 'recent' ) {
767+ if ( count >= limit ) continue ;
768+ count ++ ;
769+ }
770+ res . push ( listing ) ;
735771 }
772+ return res ;
736773}
0 commit comments