mirror of
https://github.com/discourse/discourse.git
synced 2025-01-22 11:40:06 +08:00
FEATURE: remove star concept from Discourse
This commit is contained in:
parent
fa8493118b
commit
efc717c14a
|
@ -57,7 +57,6 @@
|
|||
{{ render 'admin_report_counts' likes }}
|
||||
{{ render 'admin_report_counts' flags }}
|
||||
{{ render 'admin_report_counts' bookmarks }}
|
||||
{{ render 'admin_report_counts' starred }}
|
||||
{{ render 'admin_report_counts' emails }}
|
||||
{{/unless}}
|
||||
</table>
|
||||
|
|
|
@ -165,7 +165,7 @@ var controllerOpts = {
|
|||
|
||||
var split = this.get('filter').split('/');
|
||||
|
||||
if (split[0] !== 'new' && split[0] !== 'unread' && split[0] !== 'starred') { return; }
|
||||
if (split[0] !== 'new' && split[0] !== 'unread') { return; }
|
||||
|
||||
return I18n.t("topics.none.educate." + split[0], {
|
||||
userPrefsUrl: Discourse.getURL("/users/") + (Discourse.User.currentProp("username_lower")) + "/preferences"
|
||||
|
|
|
@ -3,7 +3,6 @@ var PATH_BINDINGS = {
|
|||
'g l': '/latest',
|
||||
'g n': '/new',
|
||||
'g u': '/unread',
|
||||
'g f': '/starred',
|
||||
'g c': '/categories',
|
||||
'g t': '/top'
|
||||
},
|
||||
|
|
|
@ -74,7 +74,7 @@ Discourse.NavItem.reopenClass({
|
|||
if (!Discourse.Category.list() && testName === "categories") return null;
|
||||
if (!Discourse.Site.currentProp('top_menu_items').contains(testName)) return null;
|
||||
|
||||
var args = { name: name, hasIcon: name === "unread" || name === "starred" };
|
||||
var args = { name: name, hasIcon: name === "unread" };
|
||||
if (opts.category) { args.category = opts.category; }
|
||||
if (opts.noSubcategories) { args.noSubcategories = true; }
|
||||
return Discourse.NavItem.create(args);
|
||||
|
|
|
@ -172,14 +172,6 @@ Discourse.Topic = Discourse.Model.extend({
|
|||
.then(function () { self.set('archetype', 'regular'); });
|
||||
},
|
||||
|
||||
starTooltipKey: function() {
|
||||
return this.get('starred') ? 'starred.help.unstar' : 'starred.help.star';
|
||||
}.property('starred'),
|
||||
|
||||
starTooltip: function() {
|
||||
return I18n.t(this.get('starTooltipKey'));
|
||||
}.property('starTooltipKey'),
|
||||
|
||||
estimatedReadingTime: function() {
|
||||
var wordCount = this.get('word_count');
|
||||
if (!wordCount) return;
|
||||
|
@ -188,15 +180,15 @@ Discourse.Topic = Discourse.Model.extend({
|
|||
return Math.floor(wordCount / 500.0);
|
||||
}.property('word_count'),
|
||||
|
||||
toggleStar: function() {
|
||||
toggleBookmark: function() {
|
||||
var topic = this;
|
||||
topic.toggleProperty('starred');
|
||||
topic.toggleProperty('bookmarked');
|
||||
return Discourse.ajax({
|
||||
url: "" + (this.get('url')) + "/star",
|
||||
url: "" + (this.get('url')) + "/bookmark",
|
||||
type: 'PUT',
|
||||
data: { starred: topic.get('starred') ? true : false }
|
||||
data: { bookmarked: topic.get('bookmarked') ? true : false }
|
||||
}).then(null, function (error) {
|
||||
topic.toggleProperty('starred');
|
||||
topic.toggleProperty('bookmarked');
|
||||
|
||||
if (error && error.responseText) {
|
||||
bootbox.alert($.parseJSON(error.responseText).errors);
|
||||
|
|
|
@ -16,7 +16,6 @@ var UserActionTypes = {
|
|||
replies: 6,
|
||||
mentions: 7,
|
||||
quotes: 9,
|
||||
starred: 10,
|
||||
edits: 11,
|
||||
messages_sent: 12,
|
||||
messages_received: 13
|
||||
|
@ -127,8 +126,6 @@ Discourse.UserAction = Discourse.Model.extend({
|
|||
case UserActionTypes.likes_given:
|
||||
case UserActionTypes.likes_received:
|
||||
return "likes";
|
||||
case UserActionTypes.starred:
|
||||
return "stars";
|
||||
case UserActionTypes.edits:
|
||||
return "edits";
|
||||
case UserActionTypes.bookmarks:
|
||||
|
@ -205,7 +202,6 @@ Discourse.UserAction.reopenClass({
|
|||
TO_COLLAPSE: [
|
||||
UserActionTypes.likes_given,
|
||||
UserActionTypes.likes_received,
|
||||
UserActionTypes.starred,
|
||||
UserActionTypes.edits,
|
||||
UserActionTypes.bookmarks
|
||||
],
|
||||
|
@ -213,7 +209,6 @@ Discourse.UserAction.reopenClass({
|
|||
TO_SHOW: [
|
||||
UserActionTypes.likes_given,
|
||||
UserActionTypes.likes_received,
|
||||
UserActionTypes.starred,
|
||||
UserActionTypes.edits,
|
||||
UserActionTypes.bookmarks,
|
||||
UserActionTypes.messages_sent,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
import UserTopicListRoute from "discourse/routes/user-topic-list";
|
||||
|
||||
export default UserTopicListRoute.extend({
|
||||
userActionType: Discourse.UserAction.TYPES.starred,
|
||||
|
||||
model: function() {
|
||||
return Discourse.TopicList.find('starred', { user_id: this.modelFor('user').get('id') });
|
||||
}
|
||||
});
|
|
@ -7,7 +7,6 @@
|
|||
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.latest'}}}</li>
|
||||
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.new'}}}</li>
|
||||
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.unread'}}}</li>
|
||||
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.starred'}}}</li>
|
||||
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.categories'}}}</li>
|
||||
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.top'}}}</li>
|
||||
</ul>
|
||||
|
|
|
@ -54,7 +54,6 @@ export default Ember.Component.extend(StringBuffer, {
|
|||
case Discourse.UserAction.TYPES.bookmarks: return "bookmark";
|
||||
case Discourse.UserAction.TYPES.edits: return "pencil";
|
||||
case Discourse.UserAction.TYPES.replies: return "reply";
|
||||
case Discourse.UserAction.TYPES.starred: return "star";
|
||||
}
|
||||
}.property("content.action_type")
|
||||
});
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
import ButtonView from 'discourse/views/button';
|
||||
|
||||
export default ButtonView.extend({
|
||||
classNames: ['star'],
|
||||
textKey: 'starred.title',
|
||||
helpKeyBinding: 'controller.starTooltipKey',
|
||||
attributeBindings: ['disabled'],
|
||||
|
||||
rerenderTriggers: ['controller.starred'],
|
||||
|
||||
click: function() {
|
||||
this.get('controller').send('toggleStar');
|
||||
},
|
||||
|
||||
renderIcon: function(buffer) {
|
||||
buffer.push("<i class='fa fa-star " +
|
||||
(this.get('controller.starred') ? ' starred' : '') +
|
||||
"'></i>");
|
||||
}
|
||||
});
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import TopicAdminMenuButton from 'discourse/views/topic-admin-menu-button';
|
||||
import LoginReplyButton from 'discourse/views/login-reply-button';
|
||||
import FlagTopicButton from 'discourse/views/flag-topic-button';
|
||||
import StarButton from 'discourse/views/star-button';
|
||||
import ShareButton from 'discourse/views/share-button';
|
||||
import InviteReplyButton from 'discourse/views/invite-reply-button';
|
||||
import ReplyButton from 'discourse/views/reply-button';
|
||||
|
@ -30,7 +29,6 @@ export default DiscourseContainerView.extend({
|
|||
if (this.get('topic.details.can_invite_to')) {
|
||||
this.attachViewClass(InviteReplyButton);
|
||||
}
|
||||
this.attachViewClass(StarButton);
|
||||
this.attachViewClass(ShareButton);
|
||||
if (this.get('topic.details.can_flag_topic')) {
|
||||
this.attachViewClass(FlagTopicButton);
|
||||
|
|
|
@ -10,9 +10,6 @@
|
|||
margin-right: 4px;
|
||||
font: 1.071em/0.9 "FontAwesome";
|
||||
}
|
||||
.has-icon .starred:before {
|
||||
content: "\f005";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,24 +36,12 @@ body {
|
|||
}
|
||||
}
|
||||
#main {
|
||||
.fa-star.starred {
|
||||
color: $danger;
|
||||
}
|
||||
a.star {
|
||||
color: dark-light-diff($secondary, $primary, 80%, -20%);
|
||||
&:before {
|
||||
font-family: "FontAwesome";
|
||||
content: "\f005";
|
||||
}
|
||||
&.starred {
|
||||
color: $danger;
|
||||
@include hover {
|
||||
opacity: 1;
|
||||
&:before {
|
||||
content: "\f005";
|
||||
}
|
||||
}
|
||||
}
|
||||
@include hover {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
|
|
@ -551,12 +551,6 @@ video {
|
|||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
a.star {
|
||||
margin: 0 7px 20px 2px;
|
||||
color: dark-light-diff($secondary, $primary, 80%, -20%) !important;
|
||||
}
|
||||
a.star.starred {color: $danger !important;}
|
||||
|
||||
.topic-statuses {
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
|
|
@ -18,36 +18,6 @@ body {
|
|||
}
|
||||
}
|
||||
#main {
|
||||
.fa-star.starred {
|
||||
color: $danger;
|
||||
}
|
||||
a.star {
|
||||
display: inline-block;
|
||||
font-size: 1.429em;
|
||||
color: scale-color($primary, $lightness: 75%);
|
||||
margin-right: 8px;
|
||||
margin-top: 4px;
|
||||
&:before {
|
||||
font-family: "FontAwesome";
|
||||
content: "\f005";
|
||||
}
|
||||
&.starred {
|
||||
color: $danger;
|
||||
@include hover {
|
||||
opacity: 1;
|
||||
&:before {
|
||||
content: "\f005";
|
||||
}
|
||||
}
|
||||
}
|
||||
@include hover {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
&:active {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
img.avatar {
|
||||
&.header {
|
||||
width: 45px;
|
||||
|
|
|
@ -166,14 +166,6 @@ class TopicsController < ApplicationController
|
|||
render nothing: true
|
||||
end
|
||||
|
||||
def star
|
||||
@topic = Topic.find_by(id: params[:topic_id].to_i)
|
||||
guardian.ensure_can_see!(@topic)
|
||||
|
||||
@topic.toggle_star(current_user, params[:starred] == 'true')
|
||||
render nothing: true
|
||||
end
|
||||
|
||||
def mute
|
||||
toggle_mute
|
||||
end
|
||||
|
|
|
@ -11,7 +11,6 @@ class AdminDashboardData
|
|||
'users_by_trust_level',
|
||||
'likes',
|
||||
'bookmarks',
|
||||
'starred',
|
||||
'emails',
|
||||
'user_to_user_private_messages',
|
||||
'system_private_messages',
|
||||
|
|
|
@ -91,13 +91,7 @@ class Report
|
|||
end
|
||||
end
|
||||
|
||||
def self.report_starred(report)
|
||||
basic_report_about report, Topic, :starred_counts_per_day, default_days
|
||||
add_counts report, TopicUser.where(starred: true), 'topic_users.starred_at'
|
||||
end
|
||||
|
||||
# Post action counts:
|
||||
|
||||
def self.report_flags(report)
|
||||
basic_report_about report, PostAction, :flag_count_by_date, report.start_date, report.end_date
|
||||
add_counts report, PostAction.where(post_action_type_id: PostActionType.flag_types.values), 'post_actions.created_at'
|
||||
|
|
|
@ -141,13 +141,6 @@ class Topic < ActiveRecord::Base
|
|||
WHERE #{condition[0]})", condition[1])
|
||||
}
|
||||
|
||||
# Helps us limit how many topics can be starred in a day
|
||||
class StarLimiter < RateLimiter
|
||||
def initialize(user)
|
||||
super(user, "starred:#{Date.today}", SiteSetting.max_stars_per_day, 1.day.to_i)
|
||||
end
|
||||
end
|
||||
|
||||
attr_accessor :ignore_category_auto_close
|
||||
attr_accessor :skip_callbacks
|
||||
|
||||
|
@ -612,27 +605,6 @@ class Topic < ActiveRecord::Base
|
|||
@participants_summary ||= TopicParticipantsSummary.new(self, options).summary
|
||||
end
|
||||
|
||||
# Enable/disable the star on the topic
|
||||
def toggle_star(user, starred)
|
||||
Topic.transaction do
|
||||
TopicUser.change(user, id, {starred: starred}.merge( starred ? {starred_at: DateTime.now, unstarred_at: nil} : {unstarred_at: DateTime.now}))
|
||||
|
||||
# Update the star count
|
||||
exec_sql "UPDATE topics
|
||||
SET star_count = (SELECT COUNT(*)
|
||||
FROM topic_users AS ftu
|
||||
WHERE ftu.topic_id = topics.id
|
||||
AND ftu.starred = true)
|
||||
WHERE id = ?", id
|
||||
|
||||
if starred
|
||||
StarLimiter.new(user).performed!
|
||||
else
|
||||
StarLimiter.new(user).rollback!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def make_banner!(user)
|
||||
# only one banner at the same time
|
||||
previous_banner = Topic.where(archetype: Archetype.banner).first
|
||||
|
@ -662,10 +634,6 @@ class Topic < ActiveRecord::Base
|
|||
}
|
||||
end
|
||||
|
||||
def self.starred_counts_per_day(sinceDaysAgo=30)
|
||||
TopicUser.starred_since(sinceDaysAgo).by_date_starred.count
|
||||
end
|
||||
|
||||
# Even if the slug column in the database is null, topic.slug will return something:
|
||||
def slug
|
||||
unless slug = read_attribute(:slug)
|
||||
|
|
|
@ -2,9 +2,6 @@ class TopicUser < ActiveRecord::Base
|
|||
belongs_to :user
|
||||
belongs_to :topic
|
||||
|
||||
scope :starred_since, lambda { |sinceDaysAgo| where('starred_at > ?', sinceDaysAgo.days.ago) }
|
||||
scope :by_date_starred, -> { group('date(starred_at)').order('date(starred_at)') }
|
||||
|
||||
scope :tracking, lambda { |topic_id|
|
||||
where(topic_id: topic_id)
|
||||
.where("COALESCE(topic_users.notification_level, :regular) >= :tracking",
|
||||
|
@ -86,8 +83,6 @@ class TopicUser < ActiveRecord::Base
|
|||
|
||||
TopicUser.transaction do
|
||||
attrs = attrs.dup
|
||||
attrs[:starred_at] = DateTime.now if attrs[:starred_at].nil? && attrs[:starred]
|
||||
|
||||
if attrs[:notification_level]
|
||||
attrs[:notifications_changed_at] ||= DateTime.now
|
||||
attrs[:notifications_reason_id] ||= TopicUser.notification_reasons[:user_changed]
|
||||
|
|
|
@ -14,7 +14,6 @@ class UserAction < ActiveRecord::Base
|
|||
RESPONSE= 6
|
||||
MENTION = 7
|
||||
QUOTE = 9
|
||||
STAR = 10
|
||||
EDIT = 11
|
||||
NEW_PRIVATE_MESSAGE = 12
|
||||
GOT_PRIVATE_MESSAGE = 13
|
||||
|
@ -30,7 +29,6 @@ class UserAction < ActiveRecord::Base
|
|||
MENTION,
|
||||
QUOTE,
|
||||
BOOKMARK,
|
||||
STAR,
|
||||
EDIT
|
||||
].each_with_index.to_a.flatten]
|
||||
|
||||
|
@ -240,35 +238,8 @@ SQL
|
|||
builder.exec
|
||||
end
|
||||
|
||||
def self.synchronize_starred
|
||||
exec_sql("
|
||||
DELETE FROM user_actions ua
|
||||
WHERE action_type = :star
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM topic_users tu
|
||||
WHERE
|
||||
tu.user_id = ua.user_id AND
|
||||
tu.topic_id = ua.target_topic_id AND
|
||||
starred
|
||||
)", star: UserAction::STAR)
|
||||
|
||||
exec_sql("INSERT INTO user_actions
|
||||
(action_type, user_id, target_topic_id, target_post_id, acting_user_id, created_at, updated_at)
|
||||
SELECT :star, tu.user_id, tu.topic_id, -1, tu.user_id, tu.starred_at, tu.starred_at
|
||||
FROM topic_users tu
|
||||
WHERE starred AND NOT EXISTS(
|
||||
SELECT 1 FROM user_actions ua
|
||||
WHERE tu.user_id = ua.user_id AND
|
||||
tu.topic_id = ua.target_topic_id AND
|
||||
ua.action_type = :star
|
||||
)
|
||||
", star: UserAction::STAR)
|
||||
|
||||
end
|
||||
|
||||
def self.ensure_consistency!
|
||||
self.synchronize_target_topic_ids
|
||||
self.synchronize_starred
|
||||
end
|
||||
|
||||
def self.update_like_count(user_id, action_type, delta)
|
||||
|
@ -294,7 +265,7 @@ SQL
|
|||
end
|
||||
|
||||
unless (guardian.user && guardian.user.id == user_id) || guardian.is_staff?
|
||||
builder.where("a.action_type not in (#{BOOKMARK},#{STAR})")
|
||||
builder.where("a.action_type not in (#{BOOKMARK})")
|
||||
builder.where("t.visible")
|
||||
end
|
||||
|
||||
|
|
|
@ -9,27 +9,6 @@ class UserActionObserver < ActiveRecord::Observer
|
|||
log_topic(model)
|
||||
when (model.is_a?(Post))
|
||||
log_post(model)
|
||||
when (model.is_a?(TopicUser))
|
||||
log_topic_user(model)
|
||||
end
|
||||
end
|
||||
|
||||
def log_topic_user(model)
|
||||
action = UserAction::STAR
|
||||
|
||||
row = {
|
||||
action_type: action,
|
||||
user_id: model.user_id,
|
||||
acting_user_id: model.user_id,
|
||||
target_topic_id: model.topic_id,
|
||||
target_post_id: -1,
|
||||
created_at: model.starred_at
|
||||
}
|
||||
|
||||
if model.starred
|
||||
UserAction.log_action!(row)
|
||||
else
|
||||
UserAction.remove_action!(row)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ class TopicListItemSerializer < ListableTopicSerializer
|
|||
|
||||
attributes :views,
|
||||
:like_count,
|
||||
:starred,
|
||||
:has_summary,
|
||||
:archetype,
|
||||
:last_poster_username,
|
||||
|
@ -13,12 +12,6 @@ class TopicListItemSerializer < ListableTopicSerializer
|
|||
has_many :posters, serializer: TopicPosterSerializer, embed: :objects
|
||||
has_many :participants, serializer: TopicPosterSerializer, embed: :objects
|
||||
|
||||
def starred
|
||||
object.user_data.starred?
|
||||
end
|
||||
|
||||
alias :include_starred? :has_user_data
|
||||
|
||||
def posters
|
||||
object.posters || []
|
||||
end
|
||||
|
|
|
@ -29,7 +29,6 @@ class TopicViewSerializer < ApplicationSerializer
|
|||
attributes :draft,
|
||||
:draft_key,
|
||||
:draft_sequence,
|
||||
:starred,
|
||||
:posted,
|
||||
:unpinned,
|
||||
:pinned_globally,
|
||||
|
@ -145,11 +144,6 @@ class TopicViewSerializer < ApplicationSerializer
|
|||
object.topic_user.present?
|
||||
end
|
||||
|
||||
def starred
|
||||
object.topic_user.starred?
|
||||
end
|
||||
alias_method :include_starred?, :has_topic_user?
|
||||
|
||||
def highest_post_number
|
||||
object.highest_post_number
|
||||
end
|
||||
|
|
|
@ -785,12 +785,6 @@ en:
|
|||
not_logged_in_user: 'user page with summary of current activity and preferences'
|
||||
current_user: 'go to your user page'
|
||||
|
||||
starred:
|
||||
title: 'Star'
|
||||
help:
|
||||
star: 'add this topic to your starred list'
|
||||
unstar: 'remove this topic from your starred list'
|
||||
|
||||
topics:
|
||||
bulk:
|
||||
reset_read: "Reset Read"
|
||||
|
@ -811,7 +805,6 @@ en:
|
|||
other: "You have selected <b>{{count}}</b> topics."
|
||||
|
||||
none:
|
||||
starred: "You have no starred topics."
|
||||
unread: "You have no unread topics."
|
||||
new: "You have no new topics."
|
||||
read: "You haven't read any topics yet."
|
||||
|
@ -823,7 +816,6 @@ en:
|
|||
educate:
|
||||
new: '<p>Your new topics appear here.</p><p>By default, topics are considered new and will show a <span class="badge new-topic badge-notification" style="vertical-align:middle;line-height:inherit;">new</span> indicator if they were created in the last 2 days.</p><p>You can change this in your <a href="%{userPrefsUrl}">preferences</a>.</p>'
|
||||
unread: '<p>Your unread topics appear here.</p><p>By default, topics are considered unread and will show unread counts <span class="badge new-posts badge-notification">1</span> if you:</p><ul><li>Created the topic</li><li>Replied to the topic</li><li>Read the topic for more than 4 minutes</li></ul><p>Or if you have explicitly set the topic to Tracked or Watched via the notification control at the bottom of each topic.</p><p>You can change this in your <a href="%{userPrefsUrl}">preferences</a>.</p>'
|
||||
starred: '<p>Your starred topics appear here.</p><p>To star or unstar a topic, use:</p><ul><li>the <i class="fa fa-star"></i> next to any topic title</li><li>the Star button at the bottom of each topic</li></ul>'
|
||||
bottom:
|
||||
latest: "There are no more latest topics."
|
||||
hot: "There are no more hot topics."
|
||||
|
@ -831,7 +823,6 @@ en:
|
|||
read: "There are no more read topics."
|
||||
new: "There are no more new topics."
|
||||
unread: "There are no more unread topics."
|
||||
starred: "There are no more starred topics."
|
||||
category: "There are no more {{category}} topics."
|
||||
top: "There are no more top topics."
|
||||
|
||||
|
@ -1433,9 +1424,6 @@ en:
|
|||
hot:
|
||||
title: "Hot"
|
||||
help: "a selection of the hottest topics"
|
||||
starred:
|
||||
title: "Starred"
|
||||
help: "topics you starred"
|
||||
read:
|
||||
title: "Read"
|
||||
help: "topics you've read, in the order that you last read them"
|
||||
|
@ -2217,7 +2205,6 @@ en:
|
|||
latest: '<b>g</b>, <b>l</b> Latest'
|
||||
new: '<b>g</b>, <b>n</b> New'
|
||||
unread: '<b>g</b>, <b>u</b> Unread'
|
||||
starred: '<b>g</b>, <b>f</b> Starred'
|
||||
categories: '<b>g</b>, <b>c</b> Categories'
|
||||
top: '<b>g</b>, <b>t</b> Top'
|
||||
navigation:
|
||||
|
|
29
db/migrate/20150106215342_remove_stars.rb
Normal file
29
db/migrate/20150106215342_remove_stars.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
class RemoveStars < ActiveRecord::Migration
|
||||
def up
|
||||
r = execute <<SQL
|
||||
INSERT INTO post_actions(user_id, post_id, post_action_type_id, created_at, updated_at)
|
||||
SELECT tu.user_id, p.id, 1, coalesce(tu.starred_at, now()), coalesce(tu.starred_at, now())
|
||||
FROM topic_users tu
|
||||
JOIN posts p ON p.topic_id = tu.topic_id AND p.post_number = 1
|
||||
LEFT JOIN post_actions pa ON
|
||||
pa.post_id = p.id AND
|
||||
pa.user_id = tu.user_id AND
|
||||
pa.post_action_type_id = 1
|
||||
WHERE pa.post_id IS NULL AND tu.starred
|
||||
SQL
|
||||
puts "#{r.cmd_tuples} stars were converted to bookmarks!"
|
||||
|
||||
execute <<SQL
|
||||
DELETE FROM user_actions WHERE action_type = 10
|
||||
SQL
|
||||
|
||||
remove_column :topic_users, :starred
|
||||
remove_column :topic_users, :starred_at
|
||||
remove_column :topic_users, :unstarred_at
|
||||
remove_column :topics, :star_count
|
||||
end
|
||||
|
||||
def down
|
||||
raise ActiveRecord::IrreversibleMigration
|
||||
end
|
||||
end
|
|
@ -56,7 +56,7 @@ module Discourse
|
|||
class CSRF < Exception; end
|
||||
|
||||
def self.filters
|
||||
@filters ||= [:latest, :unread, :new, :starred, :read, :posted]
|
||||
@filters ||= [:latest, :unread, :new, :read, :posted]
|
||||
end
|
||||
|
||||
def self.feed_filters
|
||||
|
|
|
@ -69,11 +69,6 @@ class TopicQuery
|
|||
create_list(:latest, {}, latest_results)
|
||||
end
|
||||
|
||||
# The starred topics
|
||||
def list_starred
|
||||
create_list(:starred) {|topics| topics.where('tu.starred') }
|
||||
end
|
||||
|
||||
def list_read
|
||||
create_list(:read, unordered: true) do |topics|
|
||||
topics.order('COALESCE(tu.last_visited_at, topics.bumped_at) DESC')
|
||||
|
|
|
@ -285,27 +285,6 @@ describe TopicQuery do
|
|||
|
||||
end
|
||||
|
||||
context 'list_starred' do
|
||||
|
||||
let(:topic) { Fabricate(:topic) }
|
||||
|
||||
it "returns no results when the user hasn't starred any topics" do
|
||||
topic_query.list_starred.topics.should be_blank
|
||||
end
|
||||
|
||||
context 'with a starred topic' do
|
||||
|
||||
before do
|
||||
topic.toggle_star(user, true)
|
||||
end
|
||||
|
||||
it "returns the topic after it has been starred" do
|
||||
topic_query.list_starred.topics.should == [topic]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'list_new' do
|
||||
|
||||
context 'without a new topic' do
|
||||
|
@ -386,11 +365,6 @@ describe TopicQuery do
|
|||
end
|
||||
|
||||
context "but interacted with" do
|
||||
it "is not included if starred" do
|
||||
other_users_topic.toggle_star(user, true)
|
||||
|
||||
topics.should be_blank
|
||||
end
|
||||
|
||||
it "is not included if read" do
|
||||
TopicUser.update_last_read(user, other_users_topic.id, 0, 0)
|
||||
|
|
|
@ -184,22 +184,6 @@ describe ListController do
|
|||
end
|
||||
end
|
||||
|
||||
context 'starred' do
|
||||
it 'raises an error when not logged in' do
|
||||
lambda { xhr :get, :starred }.should raise_error(Discourse::NotLoggedIn)
|
||||
end
|
||||
|
||||
context 'when logged in' do
|
||||
before do
|
||||
log_in_user(@user)
|
||||
xhr :get, :starred
|
||||
end
|
||||
|
||||
it { should respond_with(:success) }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
context 'read' do
|
||||
it 'raises an error when not logged in' do
|
||||
lambda { xhr :get, :read }.should raise_error(Discourse::NotLoggedIn)
|
||||
|
|
|
@ -436,49 +436,10 @@ describe TopicsController do
|
|||
@topic = Fabricate(:topic, user: log_in)
|
||||
end
|
||||
|
||||
it "changes the user's starred flag when the parameter is present" do
|
||||
Topic.any_instance.expects(:toggle_mute).with(@topic.user)
|
||||
xhr :put, :mute, topic_id: @topic.id, starred: 'true'
|
||||
end
|
||||
|
||||
it "removes the user's starred flag when the parameter is not true" do
|
||||
Topic.any_instance.expects(:toggle_mute).with(@topic.user)
|
||||
xhr :put, :unmute, topic_id: @topic.id, starred: 'false'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe 'star' do
|
||||
|
||||
it 'needs you to be logged in' do
|
||||
lambda { xhr :put, :star, topic_id: 1, starred: true }.should raise_error(Discourse::NotLoggedIn)
|
||||
end
|
||||
|
||||
describe 'when logged in' do
|
||||
before do
|
||||
@topic = Fabricate(:topic, user: log_in)
|
||||
end
|
||||
|
||||
it "ensures the user can see the topic" do
|
||||
Guardian.any_instance.expects(:can_see?).with(@topic).returns(false)
|
||||
xhr :put, :star, topic_id: @topic.id, starred: 'true'
|
||||
response.should be_forbidden
|
||||
end
|
||||
|
||||
it "changes the user's starred flag when the parameter is present" do
|
||||
Topic.any_instance.expects(:toggle_star).with(@topic.user, true)
|
||||
xhr :put, :star, topic_id: @topic.id, starred: 'true'
|
||||
end
|
||||
|
||||
it "removes the user's starred flag when the parameter is not true" do
|
||||
Topic.any_instance.expects(:toggle_star).with(@topic.user, false)
|
||||
xhr :put, :star, topic_id: @topic.id, starred: 'false'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'recover' do
|
||||
it "won't allow us to recover a topic when we're not logged in" do
|
||||
lambda { xhr :put, :recover, topic_id: 1 }.should raise_error(Discourse::NotLoggedIn)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Fabricator(:user_action) do
|
||||
user
|
||||
action_type UserAction::STAR
|
||||
action_type UserAction::BOOKMARK
|
||||
end
|
||||
|
|
|
@ -562,70 +562,6 @@ describe Topic do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'toggle_star' do
|
||||
|
||||
shared_examples_for "adding a star to a topic" do
|
||||
it 'triggers a forum topic user change with true' do
|
||||
# otherwise no chance the mock will work
|
||||
freeze_time
|
||||
TopicUser.expects(:change).with(@user, @topic.id, starred: true, starred_at: DateTime.now, unstarred_at: nil)
|
||||
@topic.toggle_star(@user, true)
|
||||
end
|
||||
|
||||
it 'increases the star_count of the forum topic' do
|
||||
expect {
|
||||
@topic.toggle_star(@user, true)
|
||||
@topic.reload
|
||||
}.to change(@topic, :star_count).by(1)
|
||||
end
|
||||
|
||||
it 'triggers the rate limiter' do
|
||||
Topic::StarLimiter.any_instance.expects(:performed!)
|
||||
@topic.toggle_star(@user, true)
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
@topic = Fabricate(:topic)
|
||||
@user = @topic.user
|
||||
end
|
||||
|
||||
it_should_behave_like "adding a star to a topic"
|
||||
|
||||
describe 'removing a star' do
|
||||
before do
|
||||
@topic.toggle_star(@user, true)
|
||||
@topic.reload
|
||||
end
|
||||
|
||||
it 'rolls back the rate limiter' do
|
||||
Topic::StarLimiter.any_instance.expects(:rollback!)
|
||||
@topic.toggle_star(@user, false)
|
||||
end
|
||||
|
||||
it 'triggers a forum topic user change with false' do
|
||||
freeze_time
|
||||
TopicUser.expects(:change).with(@user, @topic.id, starred: false, unstarred_at: DateTime.now)
|
||||
@topic.toggle_star(@user, false)
|
||||
end
|
||||
|
||||
it 'reduces the star_count' do
|
||||
expect {
|
||||
@topic.toggle_star(@user, false)
|
||||
@topic.reload
|
||||
}.to change(@topic, :star_count).by(-1)
|
||||
end
|
||||
|
||||
describe 'and adding a star again' do
|
||||
before do
|
||||
@topic.toggle_star(@user, false)
|
||||
@topic.reload
|
||||
end
|
||||
it_should_behave_like "adding a star to a topic"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "banner" do
|
||||
|
||||
let(:topic) { Fabricate(:topic) }
|
||||
|
|
|
@ -20,14 +20,14 @@ describe TopicUser do
|
|||
let(:topic_new_user) { TopicUser.get(topic, new_user)}
|
||||
let(:yesterday) { DateTime.now.yesterday }
|
||||
|
||||
def ensure_topic_user
|
||||
TopicUser.change(user, topic, last_emailed_post_number: 1)
|
||||
end
|
||||
|
||||
describe "unpinned" do
|
||||
|
||||
before do
|
||||
TopicUser.change(user, topic, {starred_at: yesterday})
|
||||
end
|
||||
|
||||
it "defaults to blank" do
|
||||
ensure_topic_user
|
||||
topic_user.cleared_pinned_at.should be_blank
|
||||
end
|
||||
|
||||
|
@ -37,19 +37,19 @@ describe TopicUser do
|
|||
|
||||
it 'should be set to tracking if auto_track_topics is enabled' do
|
||||
user.update_column(:auto_track_topics_after_msecs, 0)
|
||||
TopicUser.change(user, topic, {starred_at: yesterday})
|
||||
ensure_topic_user
|
||||
TopicUser.get(topic, user).notification_level.should == TopicUser.notification_levels[:tracking]
|
||||
end
|
||||
|
||||
it 'should reset regular topics to tracking topics if auto track is changed' do
|
||||
TopicUser.change(user, topic, {starred_at: yesterday})
|
||||
ensure_topic_user
|
||||
user.auto_track_topics_after_msecs = 0
|
||||
user.save
|
||||
topic_user.notification_level.should == TopicUser.notification_levels[:tracking]
|
||||
end
|
||||
|
||||
it 'should be set to "regular" notifications, by default on non creators' do
|
||||
TopicUser.change(user, topic, {starred_at: yesterday})
|
||||
ensure_topic_user
|
||||
TopicUser.get(topic,user).notification_level.should == TopicUser.notification_levels[:regular]
|
||||
end
|
||||
|
||||
|
@ -195,37 +195,20 @@ describe TopicUser do
|
|||
|
||||
describe 'change a flag' do
|
||||
|
||||
it 'creates a forum topic user record' do
|
||||
user; topic
|
||||
|
||||
lambda {
|
||||
TopicUser.change(user, topic.id, starred: true)
|
||||
}.should change(TopicUser, :count).by(1)
|
||||
end
|
||||
|
||||
it "only inserts a row once, even on repeated calls" do
|
||||
|
||||
topic; user
|
||||
|
||||
lambda {
|
||||
TopicUser.change(user, topic.id, starred: true)
|
||||
TopicUser.change(user, topic.id, starred: false)
|
||||
TopicUser.change(user, topic.id, starred: true)
|
||||
TopicUser.change(user, topic.id, total_msecs_viewed: 1)
|
||||
TopicUser.change(user, topic.id, total_msecs_viewed: 2)
|
||||
TopicUser.change(user, topic.id, total_msecs_viewed: 3)
|
||||
}.should change(TopicUser, :count).by(1)
|
||||
end
|
||||
|
||||
it 'triggers the observer callbacks when updating' do
|
||||
UserActionObserver.instance.expects(:after_save).twice
|
||||
3.times { TopicUser.change(user, topic.id, starred: true) }
|
||||
end
|
||||
|
||||
describe 'after creating a row' do
|
||||
before do
|
||||
TopicUser.change(user, topic.id, starred: true)
|
||||
end
|
||||
|
||||
it 'has the correct starred value' do
|
||||
TopicUser.get(topic, user).should be_starred
|
||||
ensure_topic_user
|
||||
end
|
||||
|
||||
it 'has a lookup' do
|
||||
|
|
|
@ -257,38 +257,6 @@ describe UserAction do
|
|||
|
||||
end
|
||||
|
||||
describe 'synchronize_starred' do
|
||||
it 'corrects out of sync starred' do
|
||||
post = Fabricate(:post)
|
||||
post.topic.toggle_star(post.user, true)
|
||||
UserAction.delete_all
|
||||
|
||||
UserAction.log_action!(
|
||||
action_type: UserAction::STAR,
|
||||
user_id: post.user.id,
|
||||
acting_user_id: post.user.id,
|
||||
target_topic_id: 99,
|
||||
target_post_id: -1,
|
||||
)
|
||||
|
||||
UserAction.log_action!(
|
||||
action_type: UserAction::STAR,
|
||||
user_id: Fabricate(:user).id,
|
||||
acting_user_id: post.user.id,
|
||||
target_topic_id: post.topic_id,
|
||||
target_post_id: -1,
|
||||
)
|
||||
|
||||
UserAction.synchronize_starred
|
||||
|
||||
actions = UserAction.all.to_a
|
||||
|
||||
expect(actions.length).to eq(1)
|
||||
expect(actions.first.action_type).to eq(UserAction::STAR)
|
||||
expect(actions.first.user_id).to eq(post.user.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'synchronize_target_topic_ids' do
|
||||
it 'correct target_topic_id' do
|
||||
post = Fabricate(:post)
|
||||
|
|
Loading…
Reference in New Issue
Block a user