mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 16:12:24 -05:00 
			
		
		
		
	[bugfix] Move follow.show_reblogs check further up to avoid showing unwanted reblogs in home timeline (#2234)
This commit is contained in:
		
					parent
					
						
							
								2a9927dfdc
							
						
					
				
			
			
				commit
				
					
						b6b8f82c87
					
				
			
		
					 3 changed files with 53 additions and 27 deletions
				
			
		|  | @ -91,9 +91,13 @@ func (s *surface) timelineAndNotifyStatusForFollowers( | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 	for _, follow := range follows { | 	for _, follow := range follows { | ||||||
| 		// Do an initial rough-grained check to see if the | 		// Check to see if the status is timelineable for this follower, | ||||||
| 		// status is timelineable for this follower at all | 		// taking account of its visibility, who it replies to, and, if | ||||||
| 		// based on its visibility and who it replies to etc. | 		// it's a reblog, whether follower account wants to see reblogs. | ||||||
|  | 		// | ||||||
|  | 		// If it's not timelineable, we can just stop early, since lists | ||||||
|  | 		// are prettymuch subsets of the home timeline, so if it shouldn't | ||||||
|  | 		// appear there, it shouldn't appear in lists either. | ||||||
| 		timelineable, err := s.filter.StatusHomeTimelineable( | 		timelineable, err := s.filter.StatusHomeTimelineable( | ||||||
| 			ctx, follow.Account, status, | 			ctx, follow.Account, status, | ||||||
| 		) | 		) | ||||||
|  | @ -107,17 +111,6 @@ func (s *surface) timelineAndNotifyStatusForFollowers( | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if boost && !*follow.ShowReblogs { |  | ||||||
| 			// Status is a boost, but the owner of |  | ||||||
| 			// this follow doesn't want to see boosts |  | ||||||
| 			// from this account. We can safely skip |  | ||||||
| 			// everything, then, because we also know |  | ||||||
| 			// that the follow owner won't want to be |  | ||||||
| 			// have the status put in any list timelines, |  | ||||||
| 			// or be notified about the status either. |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		// Add status to any relevant lists | 		// Add status to any relevant lists | ||||||
| 		// for this follow, if applicable. | 		// for this follow, if applicable. | ||||||
| 		s.listTimelineStatusForFollow( | 		s.listTimelineStatusForFollow( | ||||||
|  |  | ||||||
|  | @ -19,10 +19,12 @@ package visibility | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/cache" | 	"github.com/superseriousbusiness/gotosocial/internal/cache" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtscontext" | 	"github.com/superseriousbusiness/gotosocial/internal/gtscontext" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
|  | @ -169,24 +171,23 @@ func (f *Filter) isStatusHomeTimelineable(ctx context.Context, owner *gtsmodel.A | ||||||
| 	// a status thread *including* the owner, or a conversation thread between | 	// a status thread *including* the owner, or a conversation thread between | ||||||
| 	// accounts the timeline owner follows. | 	// accounts the timeline owner follows. | ||||||
| 
 | 
 | ||||||
| 	if status.Visibility == gtsmodel.VisibilityFollowersOnly || | 	// Ensure owner follows author. | ||||||
| 		status.Visibility == gtsmodel.VisibilityMutualsOnly { | 	follow, err := f.state.DB.GetFollow(ctx, | ||||||
| 		// Followers/mutuals only post that already passed the status |  | ||||||
| 		// visibility check, (i.e. we follow / mutuals with author). |  | ||||||
| 		return true, nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// Ensure owner follows author of public/unlocked status. |  | ||||||
| 	follow, err := f.state.DB.IsFollowing(ctx, |  | ||||||
| 		owner.ID, | 		owner.ID, | ||||||
| 		status.AccountID, | 		status.AccountID, | ||||||
| 	) | 	) | ||||||
| 	if err != nil { | 	if err != nil && !errors.Is(err, db.ErrNoEntries) { | ||||||
| 		return false, gtserror.Newf("error checking follow %s->%s: %w", owner.ID, status.AccountID, err) | 		return false, gtserror.Newf("error retrieving follow %s->%s: %w", owner.ID, status.AccountID, err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if !follow { | 	if follow == nil { | ||||||
| 		log.Trace(ctx, "ignoring visible status from unfollowed author") | 		log.Trace(ctx, "ignoring status from unfollowed author") | ||||||
|  | 		return false, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if status.BoostOfID != "" && !*follow.ShowReblogs { | ||||||
|  | 		// Status is a boost, but the owner of this follow | ||||||
|  | 		// doesn't want to see boosts from this account. | ||||||
| 		return false, nil | 		return false, nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -55,6 +55,38 @@ func (suite *StatusStatusHomeTimelineableTestSuite) TestFollowingStatusHomeTimel | ||||||
| 	suite.True(timelineable) | 	suite.True(timelineable) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (suite *StatusStatusHomeTimelineableTestSuite) TestFollowingBoostedStatusHomeTimelineable() { | ||||||
|  | 	ctx := context.Background() | ||||||
|  | 
 | ||||||
|  | 	testStatus := suite.testStatuses["admin_account_status_4"] | ||||||
|  | 	testAccount := suite.testAccounts["local_account_1"] | ||||||
|  | 	timelineable, err := suite.filter.StatusHomeTimelineable(ctx, testAccount, testStatus) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	suite.True(timelineable) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (suite *StatusStatusHomeTimelineableTestSuite) TestFollowingBoostedStatusHomeTimelineableNoReblogs() { | ||||||
|  | 	ctx := context.Background() | ||||||
|  | 
 | ||||||
|  | 	// Update follow to indicate that local_account_1 | ||||||
|  | 	// doesn't want to see reblogs by admin_account. | ||||||
|  | 	follow := >smodel.Follow{} | ||||||
|  | 	*follow = *suite.testFollows["local_account_1_admin_account"] | ||||||
|  | 	follow.ShowReblogs = util.Ptr(false) | ||||||
|  | 
 | ||||||
|  | 	if err := suite.db.UpdateFollow(ctx, follow, "show_reblogs"); err != nil { | ||||||
|  | 		suite.FailNow(err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	testStatus := suite.testStatuses["admin_account_status_4"] | ||||||
|  | 	testAccount := suite.testAccounts["local_account_1"] | ||||||
|  | 	timelineable, err := suite.filter.StatusHomeTimelineable(ctx, testAccount, testStatus) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	suite.False(timelineable) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (suite *StatusStatusHomeTimelineableTestSuite) TestNotFollowingStatusHomeTimelineable() { | func (suite *StatusStatusHomeTimelineableTestSuite) TestNotFollowingStatusHomeTimelineable() { | ||||||
| 	testStatus := suite.testStatuses["remote_account_1_status_1"] | 	testStatus := suite.testStatuses["remote_account_1_status_1"] | ||||||
| 	testAccount := suite.testAccounts["local_account_1"] | 	testAccount := suite.testAccounts["local_account_1"] | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue