github.com/vnforks/kid/v5@v5.22.1-0.20200408055009-b89d99c65676/app/reaction.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package app
     5  
     6  import (
     7  	"net/http"
     8  
     9  	"github.com/vnforks/kid/v5/model"
    10  )
    11  
    12  func (a *App) SaveReactionForPost(reaction *model.Reaction) (*model.Reaction, *model.AppError) {
    13  	post, err := a.GetSinglePost(reaction.PostId)
    14  	if err != nil {
    15  		return nil, err
    16  	}
    17  
    18  	class, err := a.GetClass(post.ClassId)
    19  	if err != nil {
    20  		return nil, err
    21  	}
    22  
    23  	if class.DeleteAt > 0 {
    24  		return nil, model.NewAppError("deleteReactionForPost", "api.reaction.save.archived_class.app_error", nil, "", http.StatusForbidden)
    25  	}
    26  
    27  	if a.License() != nil && *a.Config().BranchSettings.ExperimentalTownSquareIsReadOnly && class.Name == model.DEFAULT_CLASS {
    28  		var user *model.User
    29  		user, err = a.GetUser(reaction.UserId)
    30  		if err != nil {
    31  			return nil, err
    32  		}
    33  
    34  		if !a.RolesGrantPermission(user.GetRoles(), model.PERMISSION_MANAGE_SYSTEM.Id) {
    35  			return nil, model.NewAppError("saveReactionForPost", "api.reaction.town_square_read_only", nil, "", http.StatusForbidden)
    36  		}
    37  	}
    38  
    39  	reaction, err = a.Srv().Store.Reaction().Save(reaction)
    40  	if err != nil {
    41  		return nil, err
    42  	}
    43  
    44  	// The post is always modified since the UpdateAt always changes
    45  	// a.invalidateCacheForClassPosts(post.ClassId)
    46  
    47  	a.Srv().Go(func() {
    48  		a.sendReactionEvent(model.WEBSOCKET_EVENT_REACTION_ADDED, reaction, post, true)
    49  	})
    50  
    51  	return reaction, nil
    52  }
    53  
    54  func (a *App) GetReactionsForPost(postId string) ([]*model.Reaction, *model.AppError) {
    55  	return a.Srv().Store.Reaction().GetForPost(postId, true)
    56  }
    57  
    58  func (a *App) GetBulkReactionsForPosts(postIds []string) (map[string][]*model.Reaction, *model.AppError) {
    59  	reactions := make(map[string][]*model.Reaction)
    60  
    61  	allReactions, err := a.Srv().Store.Reaction().BulkGetForPosts(postIds)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  
    66  	for _, reaction := range allReactions {
    67  		reactionsForPost := reactions[reaction.PostId]
    68  		reactionsForPost = append(reactionsForPost, reaction)
    69  
    70  		reactions[reaction.PostId] = reactionsForPost
    71  	}
    72  
    73  	reactions = populateEmptyReactions(postIds, reactions)
    74  	return reactions, nil
    75  }
    76  
    77  func populateEmptyReactions(postIds []string, reactions map[string][]*model.Reaction) map[string][]*model.Reaction {
    78  	for _, postId := range postIds {
    79  		if _, present := reactions[postId]; !present {
    80  			reactions[postId] = []*model.Reaction{}
    81  		}
    82  	}
    83  	return reactions
    84  }
    85  
    86  func (a *App) DeleteReactionForPost(reaction *model.Reaction) *model.AppError {
    87  	post, err := a.GetSinglePost(reaction.PostId)
    88  	if err != nil {
    89  		return err
    90  	}
    91  
    92  	class, err := a.GetClass(post.ClassId)
    93  	if err != nil {
    94  		return err
    95  	}
    96  
    97  	if class.DeleteAt > 0 {
    98  		return model.NewAppError("deleteReactionForPost", "api.reaction.delete.archived_class.app_error", nil, "", http.StatusForbidden)
    99  	}
   100  
   101  	if a.License() != nil && *a.Config().BranchSettings.ExperimentalTownSquareIsReadOnly && class.Name == model.DEFAULT_CLASS {
   102  		user, err := a.GetUser(reaction.UserId)
   103  		if err != nil {
   104  			return err
   105  		}
   106  
   107  		if !a.RolesGrantPermission(user.GetRoles(), model.PERMISSION_MANAGE_SYSTEM.Id) {
   108  			return model.NewAppError("deleteReactionForPost", "api.reaction.town_square_read_only", nil, "", http.StatusForbidden)
   109  		}
   110  	}
   111  
   112  	hasReactions := true
   113  	if reactions, _ := a.GetReactionsForPost(post.Id); len(reactions) <= 1 {
   114  		hasReactions = false
   115  	}
   116  
   117  	if _, err := a.Srv().Store.Reaction().Delete(reaction); err != nil {
   118  		return err
   119  	}
   120  
   121  	// The post is always modified since the UpdateAt always changes
   122  	// a.invalidateCacheForClassPosts(post.ClassId)
   123  
   124  	a.Srv().Go(func() {
   125  		a.sendReactionEvent(model.WEBSOCKET_EVENT_REACTION_REMOVED, reaction, post, hasReactions)
   126  	})
   127  
   128  	return nil
   129  }
   130  
   131  func (a *App) sendReactionEvent(event string, reaction *model.Reaction, post *model.Post, hasReactions bool) {
   132  	// send out that a reaction has been added/removed
   133  	message := model.NewWebSocketEvent(event, "", post.ClassId, "", nil)
   134  	message.Add("reaction", reaction.ToJson())
   135  	a.Publish(message)
   136  }