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' likes }}
|
||||||
{{ render 'admin_report_counts' flags }}
|
{{ render 'admin_report_counts' flags }}
|
||||||
{{ render 'admin_report_counts' bookmarks }}
|
{{ render 'admin_report_counts' bookmarks }}
|
||||||
{{ render 'admin_report_counts' starred }}
|
|
||||||
{{ render 'admin_report_counts' emails }}
|
{{ render 'admin_report_counts' emails }}
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -165,7 +165,7 @@ var controllerOpts = {
|
||||||
|
|
||||||
var split = this.get('filter').split('/');
|
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], {
|
return I18n.t("topics.none.educate." + split[0], {
|
||||||
userPrefsUrl: Discourse.getURL("/users/") + (Discourse.User.currentProp("username_lower")) + "/preferences"
|
userPrefsUrl: Discourse.getURL("/users/") + (Discourse.User.currentProp("username_lower")) + "/preferences"
|
||||||
|
|
|
@ -3,7 +3,6 @@ var PATH_BINDINGS = {
|
||||||
'g l': '/latest',
|
'g l': '/latest',
|
||||||
'g n': '/new',
|
'g n': '/new',
|
||||||
'g u': '/unread',
|
'g u': '/unread',
|
||||||
'g f': '/starred',
|
|
||||||
'g c': '/categories',
|
'g c': '/categories',
|
||||||
'g t': '/top'
|
'g t': '/top'
|
||||||
},
|
},
|
||||||
|
|
|
@ -74,7 +74,7 @@ Discourse.NavItem.reopenClass({
|
||||||
if (!Discourse.Category.list() && testName === "categories") return null;
|
if (!Discourse.Category.list() && testName === "categories") return null;
|
||||||
if (!Discourse.Site.currentProp('top_menu_items').contains(testName)) 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.category) { args.category = opts.category; }
|
||||||
if (opts.noSubcategories) { args.noSubcategories = true; }
|
if (opts.noSubcategories) { args.noSubcategories = true; }
|
||||||
return Discourse.NavItem.create(args);
|
return Discourse.NavItem.create(args);
|
||||||
|
|
|
@ -172,14 +172,6 @@ Discourse.Topic = Discourse.Model.extend({
|
||||||
.then(function () { self.set('archetype', 'regular'); });
|
.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() {
|
estimatedReadingTime: function() {
|
||||||
var wordCount = this.get('word_count');
|
var wordCount = this.get('word_count');
|
||||||
if (!wordCount) return;
|
if (!wordCount) return;
|
||||||
|
@ -188,15 +180,15 @@ Discourse.Topic = Discourse.Model.extend({
|
||||||
return Math.floor(wordCount / 500.0);
|
return Math.floor(wordCount / 500.0);
|
||||||
}.property('word_count'),
|
}.property('word_count'),
|
||||||
|
|
||||||
toggleStar: function() {
|
toggleBookmark: function() {
|
||||||
var topic = this;
|
var topic = this;
|
||||||
topic.toggleProperty('starred');
|
topic.toggleProperty('bookmarked');
|
||||||
return Discourse.ajax({
|
return Discourse.ajax({
|
||||||
url: "" + (this.get('url')) + "/star",
|
url: "" + (this.get('url')) + "/bookmark",
|
||||||
type: 'PUT',
|
type: 'PUT',
|
||||||
data: { starred: topic.get('starred') ? true : false }
|
data: { bookmarked: topic.get('bookmarked') ? true : false }
|
||||||
}).then(null, function (error) {
|
}).then(null, function (error) {
|
||||||
topic.toggleProperty('starred');
|
topic.toggleProperty('bookmarked');
|
||||||
|
|
||||||
if (error && error.responseText) {
|
if (error && error.responseText) {
|
||||||
bootbox.alert($.parseJSON(error.responseText).errors);
|
bootbox.alert($.parseJSON(error.responseText).errors);
|
||||||
|
|
|
@ -16,7 +16,6 @@ var UserActionTypes = {
|
||||||
replies: 6,
|
replies: 6,
|
||||||
mentions: 7,
|
mentions: 7,
|
||||||
quotes: 9,
|
quotes: 9,
|
||||||
starred: 10,
|
|
||||||
edits: 11,
|
edits: 11,
|
||||||
messages_sent: 12,
|
messages_sent: 12,
|
||||||
messages_received: 13
|
messages_received: 13
|
||||||
|
@ -127,8 +126,6 @@ Discourse.UserAction = Discourse.Model.extend({
|
||||||
case UserActionTypes.likes_given:
|
case UserActionTypes.likes_given:
|
||||||
case UserActionTypes.likes_received:
|
case UserActionTypes.likes_received:
|
||||||
return "likes";
|
return "likes";
|
||||||
case UserActionTypes.starred:
|
|
||||||
return "stars";
|
|
||||||
case UserActionTypes.edits:
|
case UserActionTypes.edits:
|
||||||
return "edits";
|
return "edits";
|
||||||
case UserActionTypes.bookmarks:
|
case UserActionTypes.bookmarks:
|
||||||
|
@ -205,7 +202,6 @@ Discourse.UserAction.reopenClass({
|
||||||
TO_COLLAPSE: [
|
TO_COLLAPSE: [
|
||||||
UserActionTypes.likes_given,
|
UserActionTypes.likes_given,
|
||||||
UserActionTypes.likes_received,
|
UserActionTypes.likes_received,
|
||||||
UserActionTypes.starred,
|
|
||||||
UserActionTypes.edits,
|
UserActionTypes.edits,
|
||||||
UserActionTypes.bookmarks
|
UserActionTypes.bookmarks
|
||||||
],
|
],
|
||||||
|
@ -213,7 +209,6 @@ Discourse.UserAction.reopenClass({
|
||||||
TO_SHOW: [
|
TO_SHOW: [
|
||||||
UserActionTypes.likes_given,
|
UserActionTypes.likes_given,
|
||||||
UserActionTypes.likes_received,
|
UserActionTypes.likes_received,
|
||||||
UserActionTypes.starred,
|
|
||||||
UserActionTypes.edits,
|
UserActionTypes.edits,
|
||||||
UserActionTypes.bookmarks,
|
UserActionTypes.bookmarks,
|
||||||
UserActionTypes.messages_sent,
|
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.latest'}}}</li>
|
||||||
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.new'}}}</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.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.categories'}}}</li>
|
||||||
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.top'}}}</li>
|
<li>{{{i18n 'keyboard_shortcuts_help.jump_to.top'}}}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -54,7 +54,6 @@ export default Ember.Component.extend(StringBuffer, {
|
||||||
case Discourse.UserAction.TYPES.bookmarks: return "bookmark";
|
case Discourse.UserAction.TYPES.bookmarks: return "bookmark";
|
||||||
case Discourse.UserAction.TYPES.edits: return "pencil";
|
case Discourse.UserAction.TYPES.edits: return "pencil";
|
||||||
case Discourse.UserAction.TYPES.replies: return "reply";
|
case Discourse.UserAction.TYPES.replies: return "reply";
|
||||||
case Discourse.UserAction.TYPES.starred: return "star";
|
|
||||||
}
|
}
|
||||||
}.property("content.action_type")
|
}.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 TopicAdminMenuButton from 'discourse/views/topic-admin-menu-button';
|
||||||
import LoginReplyButton from 'discourse/views/login-reply-button';
|
import LoginReplyButton from 'discourse/views/login-reply-button';
|
||||||
import FlagTopicButton from 'discourse/views/flag-topic-button';
|
import FlagTopicButton from 'discourse/views/flag-topic-button';
|
||||||
import StarButton from 'discourse/views/star-button';
|
|
||||||
import ShareButton from 'discourse/views/share-button';
|
import ShareButton from 'discourse/views/share-button';
|
||||||
import InviteReplyButton from 'discourse/views/invite-reply-button';
|
import InviteReplyButton from 'discourse/views/invite-reply-button';
|
||||||
import ReplyButton from 'discourse/views/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')) {
|
if (this.get('topic.details.can_invite_to')) {
|
||||||
this.attachViewClass(InviteReplyButton);
|
this.attachViewClass(InviteReplyButton);
|
||||||
}
|
}
|
||||||
this.attachViewClass(StarButton);
|
|
||||||
this.attachViewClass(ShareButton);
|
this.attachViewClass(ShareButton);
|
||||||
if (this.get('topic.details.can_flag_topic')) {
|
if (this.get('topic.details.can_flag_topic')) {
|
||||||
this.attachViewClass(FlagTopicButton);
|
this.attachViewClass(FlagTopicButton);
|
||||||
|
|
|
@ -10,9 +10,6 @@
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
font: 1.071em/0.9 "FontAwesome";
|
font: 1.071em/0.9 "FontAwesome";
|
||||||
}
|
}
|
||||||
.has-icon .starred:before {
|
|
||||||
content: "\f005";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,24 +36,12 @@ body {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#main {
|
#main {
|
||||||
.fa-star.starred {
|
|
||||||
color: $danger;
|
|
||||||
}
|
|
||||||
a.star {
|
a.star {
|
||||||
color: dark-light-diff($secondary, $primary, 80%, -20%);
|
color: dark-light-diff($secondary, $primary, 80%, -20%);
|
||||||
&:before {
|
&:before {
|
||||||
font-family: "FontAwesome";
|
font-family: "FontAwesome";
|
||||||
content: "\f005";
|
content: "\f005";
|
||||||
}
|
}
|
||||||
&.starred {
|
|
||||||
color: $danger;
|
|
||||||
@include hover {
|
|
||||||
opacity: 1;
|
|
||||||
&:before {
|
|
||||||
content: "\f005";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include hover {
|
@include hover {
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
|
@ -551,12 +551,6 @@ video {
|
||||||
line-height: 1.3em;
|
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 {
|
.topic-statuses {
|
||||||
margin-top: -2px;
|
margin-top: -2px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,36 +18,6 @@ body {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#main {
|
#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 {
|
img.avatar {
|
||||||
&.header {
|
&.header {
|
||||||
width: 45px;
|
width: 45px;
|
||||||
|
|
|
@ -166,14 +166,6 @@ class TopicsController < ApplicationController
|
||||||
render nothing: true
|
render nothing: true
|
||||||
end
|
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
|
def mute
|
||||||
toggle_mute
|
toggle_mute
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,7 +11,6 @@ class AdminDashboardData
|
||||||
'users_by_trust_level',
|
'users_by_trust_level',
|
||||||
'likes',
|
'likes',
|
||||||
'bookmarks',
|
'bookmarks',
|
||||||
'starred',
|
|
||||||
'emails',
|
'emails',
|
||||||
'user_to_user_private_messages',
|
'user_to_user_private_messages',
|
||||||
'system_private_messages',
|
'system_private_messages',
|
||||||
|
|
|
@ -91,13 +91,7 @@ class Report
|
||||||
end
|
end
|
||||||
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:
|
# Post action counts:
|
||||||
|
|
||||||
def self.report_flags(report)
|
def self.report_flags(report)
|
||||||
basic_report_about report, PostAction, :flag_count_by_date, report.start_date, report.end_date
|
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'
|
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])
|
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 :ignore_category_auto_close
|
||||||
attr_accessor :skip_callbacks
|
attr_accessor :skip_callbacks
|
||||||
|
|
||||||
|
@ -612,27 +605,6 @@ class Topic < ActiveRecord::Base
|
||||||
@participants_summary ||= TopicParticipantsSummary.new(self, options).summary
|
@participants_summary ||= TopicParticipantsSummary.new(self, options).summary
|
||||||
end
|
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)
|
def make_banner!(user)
|
||||||
# only one banner at the same time
|
# only one banner at the same time
|
||||||
previous_banner = Topic.where(archetype: Archetype.banner).first
|
previous_banner = Topic.where(archetype: Archetype.banner).first
|
||||||
|
@ -662,10 +634,6 @@ class Topic < ActiveRecord::Base
|
||||||
}
|
}
|
||||||
end
|
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:
|
# Even if the slug column in the database is null, topic.slug will return something:
|
||||||
def slug
|
def slug
|
||||||
unless slug = read_attribute(:slug)
|
unless slug = read_attribute(:slug)
|
||||||
|
|
|
@ -2,9 +2,6 @@ class TopicUser < ActiveRecord::Base
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :topic
|
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|
|
scope :tracking, lambda { |topic_id|
|
||||||
where(topic_id: topic_id)
|
where(topic_id: topic_id)
|
||||||
.where("COALESCE(topic_users.notification_level, :regular) >= :tracking",
|
.where("COALESCE(topic_users.notification_level, :regular) >= :tracking",
|
||||||
|
@ -86,8 +83,6 @@ class TopicUser < ActiveRecord::Base
|
||||||
|
|
||||||
TopicUser.transaction do
|
TopicUser.transaction do
|
||||||
attrs = attrs.dup
|
attrs = attrs.dup
|
||||||
attrs[:starred_at] = DateTime.now if attrs[:starred_at].nil? && attrs[:starred]
|
|
||||||
|
|
||||||
if attrs[:notification_level]
|
if attrs[:notification_level]
|
||||||
attrs[:notifications_changed_at] ||= DateTime.now
|
attrs[:notifications_changed_at] ||= DateTime.now
|
||||||
attrs[:notifications_reason_id] ||= TopicUser.notification_reasons[:user_changed]
|
attrs[:notifications_reason_id] ||= TopicUser.notification_reasons[:user_changed]
|
||||||
|
|
|
@ -14,7 +14,6 @@ class UserAction < ActiveRecord::Base
|
||||||
RESPONSE= 6
|
RESPONSE= 6
|
||||||
MENTION = 7
|
MENTION = 7
|
||||||
QUOTE = 9
|
QUOTE = 9
|
||||||
STAR = 10
|
|
||||||
EDIT = 11
|
EDIT = 11
|
||||||
NEW_PRIVATE_MESSAGE = 12
|
NEW_PRIVATE_MESSAGE = 12
|
||||||
GOT_PRIVATE_MESSAGE = 13
|
GOT_PRIVATE_MESSAGE = 13
|
||||||
|
@ -30,7 +29,6 @@ class UserAction < ActiveRecord::Base
|
||||||
MENTION,
|
MENTION,
|
||||||
QUOTE,
|
QUOTE,
|
||||||
BOOKMARK,
|
BOOKMARK,
|
||||||
STAR,
|
|
||||||
EDIT
|
EDIT
|
||||||
].each_with_index.to_a.flatten]
|
].each_with_index.to_a.flatten]
|
||||||
|
|
||||||
|
@ -240,35 +238,8 @@ SQL
|
||||||
builder.exec
|
builder.exec
|
||||||
end
|
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!
|
def self.ensure_consistency!
|
||||||
self.synchronize_target_topic_ids
|
self.synchronize_target_topic_ids
|
||||||
self.synchronize_starred
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.update_like_count(user_id, action_type, delta)
|
def self.update_like_count(user_id, action_type, delta)
|
||||||
|
@ -294,7 +265,7 @@ SQL
|
||||||
end
|
end
|
||||||
|
|
||||||
unless (guardian.user && guardian.user.id == user_id) || guardian.is_staff?
|
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")
|
builder.where("t.visible")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -9,27 +9,6 @@ class UserActionObserver < ActiveRecord::Observer
|
||||||
log_topic(model)
|
log_topic(model)
|
||||||
when (model.is_a?(Post))
|
when (model.is_a?(Post))
|
||||||
log_post(model)
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ class TopicListItemSerializer < ListableTopicSerializer
|
||||||
|
|
||||||
attributes :views,
|
attributes :views,
|
||||||
:like_count,
|
:like_count,
|
||||||
:starred,
|
|
||||||
:has_summary,
|
:has_summary,
|
||||||
:archetype,
|
:archetype,
|
||||||
:last_poster_username,
|
:last_poster_username,
|
||||||
|
@ -13,12 +12,6 @@ class TopicListItemSerializer < ListableTopicSerializer
|
||||||
has_many :posters, serializer: TopicPosterSerializer, embed: :objects
|
has_many :posters, serializer: TopicPosterSerializer, embed: :objects
|
||||||
has_many :participants, 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
|
def posters
|
||||||
object.posters || []
|
object.posters || []
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,7 +29,6 @@ class TopicViewSerializer < ApplicationSerializer
|
||||||
attributes :draft,
|
attributes :draft,
|
||||||
:draft_key,
|
:draft_key,
|
||||||
:draft_sequence,
|
:draft_sequence,
|
||||||
:starred,
|
|
||||||
:posted,
|
:posted,
|
||||||
:unpinned,
|
:unpinned,
|
||||||
:pinned_globally,
|
:pinned_globally,
|
||||||
|
@ -145,11 +144,6 @@ class TopicViewSerializer < ApplicationSerializer
|
||||||
object.topic_user.present?
|
object.topic_user.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def starred
|
|
||||||
object.topic_user.starred?
|
|
||||||
end
|
|
||||||
alias_method :include_starred?, :has_topic_user?
|
|
||||||
|
|
||||||
def highest_post_number
|
def highest_post_number
|
||||||
object.highest_post_number
|
object.highest_post_number
|
||||||
end
|
end
|
||||||
|
|
|
@ -785,12 +785,6 @@ en:
|
||||||
not_logged_in_user: 'user page with summary of current activity and preferences'
|
not_logged_in_user: 'user page with summary of current activity and preferences'
|
||||||
current_user: 'go to your user page'
|
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:
|
topics:
|
||||||
bulk:
|
bulk:
|
||||||
reset_read: "Reset Read"
|
reset_read: "Reset Read"
|
||||||
|
@ -811,7 +805,6 @@ en:
|
||||||
other: "You have selected <b>{{count}}</b> topics."
|
other: "You have selected <b>{{count}}</b> topics."
|
||||||
|
|
||||||
none:
|
none:
|
||||||
starred: "You have no starred topics."
|
|
||||||
unread: "You have no unread topics."
|
unread: "You have no unread topics."
|
||||||
new: "You have no new topics."
|
new: "You have no new topics."
|
||||||
read: "You haven't read any topics yet."
|
read: "You haven't read any topics yet."
|
||||||
|
@ -823,7 +816,6 @@ en:
|
||||||
educate:
|
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>'
|
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>'
|
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:
|
bottom:
|
||||||
latest: "There are no more latest topics."
|
latest: "There are no more latest topics."
|
||||||
hot: "There are no more hot topics."
|
hot: "There are no more hot topics."
|
||||||
|
@ -831,7 +823,6 @@ en:
|
||||||
read: "There are no more read topics."
|
read: "There are no more read topics."
|
||||||
new: "There are no more new topics."
|
new: "There are no more new topics."
|
||||||
unread: "There are no more unread topics."
|
unread: "There are no more unread topics."
|
||||||
starred: "There are no more starred topics."
|
|
||||||
category: "There are no more {{category}} topics."
|
category: "There are no more {{category}} topics."
|
||||||
top: "There are no more top topics."
|
top: "There are no more top topics."
|
||||||
|
|
||||||
|
@ -1433,9 +1424,6 @@ en:
|
||||||
hot:
|
hot:
|
||||||
title: "Hot"
|
title: "Hot"
|
||||||
help: "a selection of the hottest topics"
|
help: "a selection of the hottest topics"
|
||||||
starred:
|
|
||||||
title: "Starred"
|
|
||||||
help: "topics you starred"
|
|
||||||
read:
|
read:
|
||||||
title: "Read"
|
title: "Read"
|
||||||
help: "topics you've read, in the order that you last read them"
|
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'
|
latest: '<b>g</b>, <b>l</b> Latest'
|
||||||
new: '<b>g</b>, <b>n</b> New'
|
new: '<b>g</b>, <b>n</b> New'
|
||||||
unread: '<b>g</b>, <b>u</b> Unread'
|
unread: '<b>g</b>, <b>u</b> Unread'
|
||||||
starred: '<b>g</b>, <b>f</b> Starred'
|
|
||||||
categories: '<b>g</b>, <b>c</b> Categories'
|
categories: '<b>g</b>, <b>c</b> Categories'
|
||||||
top: '<b>g</b>, <b>t</b> Top'
|
top: '<b>g</b>, <b>t</b> Top'
|
||||||
navigation:
|
navigation:
|
||||||
|
|
|
@ -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
|
class CSRF < Exception; end
|
||||||
|
|
||||||
def self.filters
|
def self.filters
|
||||||
@filters ||= [:latest, :unread, :new, :starred, :read, :posted]
|
@filters ||= [:latest, :unread, :new, :read, :posted]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.feed_filters
|
def self.feed_filters
|
||||||
|
|
|
@ -69,11 +69,6 @@ class TopicQuery
|
||||||
create_list(:latest, {}, latest_results)
|
create_list(:latest, {}, latest_results)
|
||||||
end
|
end
|
||||||
|
|
||||||
# The starred topics
|
|
||||||
def list_starred
|
|
||||||
create_list(:starred) {|topics| topics.where('tu.starred') }
|
|
||||||
end
|
|
||||||
|
|
||||||
def list_read
|
def list_read
|
||||||
create_list(:read, unordered: true) do |topics|
|
create_list(:read, unordered: true) do |topics|
|
||||||
topics.order('COALESCE(tu.last_visited_at, topics.bumped_at) DESC')
|
topics.order('COALESCE(tu.last_visited_at, topics.bumped_at) DESC')
|
||||||
|
|
|
@ -285,27 +285,6 @@ describe TopicQuery do
|
||||||
|
|
||||||
end
|
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 'list_new' do
|
||||||
|
|
||||||
context 'without a new topic' do
|
context 'without a new topic' do
|
||||||
|
@ -386,11 +365,6 @@ describe TopicQuery do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "but interacted with" do
|
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
|
it "is not included if read" do
|
||||||
TopicUser.update_last_read(user, other_users_topic.id, 0, 0)
|
TopicUser.update_last_read(user, other_users_topic.id, 0, 0)
|
||||||
|
|
|
@ -184,22 +184,6 @@ describe ListController do
|
||||||
end
|
end
|
||||||
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
|
context 'read' do
|
||||||
it 'raises an error when not logged in' do
|
it 'raises an error when not logged in' do
|
||||||
lambda { xhr :get, :read }.should raise_error(Discourse::NotLoggedIn)
|
lambda { xhr :get, :read }.should raise_error(Discourse::NotLoggedIn)
|
||||||
|
|
|
@ -436,49 +436,10 @@ describe TopicsController do
|
||||||
@topic = Fabricate(:topic, user: log_in)
|
@topic = Fabricate(:topic, user: log_in)
|
||||||
end
|
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
|
||||||
|
|
||||||
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
|
describe 'recover' do
|
||||||
it "won't allow us to recover a topic when we're not logged in" 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)
|
lambda { xhr :put, :recover, topic_id: 1 }.should raise_error(Discourse::NotLoggedIn)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Fabricator(:user_action) do
|
Fabricator(:user_action) do
|
||||||
user
|
user
|
||||||
action_type UserAction::STAR
|
action_type UserAction::BOOKMARK
|
||||||
end
|
end
|
||||||
|
|
|
@ -562,70 +562,6 @@ describe Topic do
|
||||||
end
|
end
|
||||||
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
|
describe "banner" do
|
||||||
|
|
||||||
let(:topic) { Fabricate(:topic) }
|
let(:topic) { Fabricate(:topic) }
|
||||||
|
|
|
@ -20,14 +20,14 @@ describe TopicUser do
|
||||||
let(:topic_new_user) { TopicUser.get(topic, new_user)}
|
let(:topic_new_user) { TopicUser.get(topic, new_user)}
|
||||||
let(:yesterday) { DateTime.now.yesterday }
|
let(:yesterday) { DateTime.now.yesterday }
|
||||||
|
|
||||||
|
def ensure_topic_user
|
||||||
|
TopicUser.change(user, topic, last_emailed_post_number: 1)
|
||||||
|
end
|
||||||
|
|
||||||
describe "unpinned" do
|
describe "unpinned" do
|
||||||
|
|
||||||
before do
|
|
||||||
TopicUser.change(user, topic, {starred_at: yesterday})
|
|
||||||
end
|
|
||||||
|
|
||||||
it "defaults to blank" do
|
it "defaults to blank" do
|
||||||
|
ensure_topic_user
|
||||||
topic_user.cleared_pinned_at.should be_blank
|
topic_user.cleared_pinned_at.should be_blank
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -37,19 +37,19 @@ describe TopicUser do
|
||||||
|
|
||||||
it 'should be set to tracking if auto_track_topics is enabled' do
|
it 'should be set to tracking if auto_track_topics is enabled' do
|
||||||
user.update_column(:auto_track_topics_after_msecs, 0)
|
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]
|
TopicUser.get(topic, user).notification_level.should == TopicUser.notification_levels[:tracking]
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should reset regular topics to tracking topics if auto track is changed' do
|
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.auto_track_topics_after_msecs = 0
|
||||||
user.save
|
user.save
|
||||||
topic_user.notification_level.should == TopicUser.notification_levels[:tracking]
|
topic_user.notification_level.should == TopicUser.notification_levels[:tracking]
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should be set to "regular" notifications, by default on non creators' do
|
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]
|
TopicUser.get(topic,user).notification_level.should == TopicUser.notification_levels[:regular]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -195,37 +195,20 @@ describe TopicUser do
|
||||||
|
|
||||||
describe 'change a flag' 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
|
it "only inserts a row once, even on repeated calls" do
|
||||||
|
|
||||||
topic; user
|
topic; user
|
||||||
|
|
||||||
lambda {
|
lambda {
|
||||||
TopicUser.change(user, topic.id, starred: true)
|
TopicUser.change(user, topic.id, total_msecs_viewed: 1)
|
||||||
TopicUser.change(user, topic.id, starred: false)
|
TopicUser.change(user, topic.id, total_msecs_viewed: 2)
|
||||||
TopicUser.change(user, topic.id, starred: true)
|
TopicUser.change(user, topic.id, total_msecs_viewed: 3)
|
||||||
}.should change(TopicUser, :count).by(1)
|
}.should change(TopicUser, :count).by(1)
|
||||||
end
|
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
|
describe 'after creating a row' do
|
||||||
before do
|
before do
|
||||||
TopicUser.change(user, topic.id, starred: true)
|
ensure_topic_user
|
||||||
end
|
|
||||||
|
|
||||||
it 'has the correct starred value' do
|
|
||||||
TopicUser.get(topic, user).should be_starred
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'has a lookup' do
|
it 'has a lookup' do
|
||||||
|
|
|
@ -257,38 +257,6 @@ describe UserAction do
|
||||||
|
|
||||||
end
|
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
|
describe 'synchronize_target_topic_ids' do
|
||||||
it 'correct target_topic_id' do
|
it 'correct target_topic_id' do
|
||||||
post = Fabricate(:post)
|
post = Fabricate(:post)
|
||||||
|
|
Loading…
Reference in New Issue