User interface for watching first post
This commit is contained in:
parent
323efcab71
commit
1eb64151f6
|
@ -1,5 +1,5 @@
|
||||||
import DropdownButton from 'discourse/components/dropdown-button';
|
import DropdownButton from 'discourse/components/dropdown-button';
|
||||||
import { all, buttonDetails } from 'discourse/lib/notification-levels';
|
import { allLevels, buttonDetails } from 'discourse/lib/notification-levels';
|
||||||
import { iconHTML } from 'discourse/helpers/fa-icon';
|
import { iconHTML } from 'discourse/helpers/fa-icon';
|
||||||
import computed from 'ember-addons/ember-computed-decorators';
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ export default DropdownButton.extend({
|
||||||
const prefix = this.get('i18nPrefix');
|
const prefix = this.get('i18nPrefix');
|
||||||
const postfix = this.get('i18nPostfix');
|
const postfix = this.get('i18nPostfix');
|
||||||
|
|
||||||
return all.map(l => {
|
return allLevels.map(l => {
|
||||||
const start = `${prefix}.${l.key}${postfix}`;
|
const start = `${prefix}.${l.key}${postfix}`;
|
||||||
return {
|
return {
|
||||||
id: l.id,
|
id: l.id,
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
import NotificationLevels from 'discourse/lib/notification-levels';
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
import { topicLevels } from 'discourse/lib/notification-levels';
|
||||||
|
|
||||||
// Support for changing the notification level of various topics
|
// Support for changing the notification level of various topics
|
||||||
export default Em.Controller.extend({
|
export default Ember.Controller.extend({
|
||||||
needs: ['topic-bulk-actions'],
|
needs: ['topic-bulk-actions'],
|
||||||
notificationLevelId: null,
|
notificationLevelId: null,
|
||||||
|
|
||||||
notificationLevels: function() {
|
@computed
|
||||||
var result = [];
|
notificationLevels() {
|
||||||
Object.keys(NotificationLevels).forEach(function(k) {
|
return topicLevels.map(level => {
|
||||||
result.push({
|
return {
|
||||||
id: NotificationLevels[k].toString(),
|
id: level.id.toString(),
|
||||||
name: I18n.t('topic.notifications.' + k.toLowerCase() + ".title"),
|
name: I18n.t(`topic.notifications.${level.key}.title`),
|
||||||
description: I18n.t('topic.notifications.' + k.toLowerCase() + ".description")
|
description: I18n.t(`topic.notifications.${level.key}.description`)
|
||||||
});
|
};
|
||||||
});
|
});
|
||||||
return result;
|
},
|
||||||
}.property(),
|
|
||||||
|
|
||||||
disabled: Em.computed.empty("notificationLevelId"),
|
disabled: Em.computed.empty("notificationLevelId"),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
changeNotificationLevel: function() {
|
changeNotificationLevel() {
|
||||||
this.get('controllers.topic-bulk-actions').performAndRefresh({
|
this.get('controllers.topic-bulk-actions').performAndRefresh({
|
||||||
type: 'change_notification_level',
|
type: 'change_notification_level',
|
||||||
notification_level_id: this.get('notificationLevelId')
|
notification_level_id: this.get('notificationLevelId')
|
||||||
|
|
|
@ -1,24 +1,25 @@
|
||||||
const NotificationLevels = {
|
const MUTED = 0;
|
||||||
WATCHING: 3,
|
const REGULAR = 1;
|
||||||
TRACKING: 2,
|
const TRACKING = 2;
|
||||||
REGULAR: 1,
|
const WATCHING = 3;
|
||||||
MUTED: 0
|
const WATCHING_FIRST_POST = 4;
|
||||||
};
|
|
||||||
export default NotificationLevels;
|
export const NotificationLevels = { WATCHING_FIRST_POST, WATCHING, TRACKING, REGULAR, MUTED };
|
||||||
|
|
||||||
export function buttonDetails(level) {
|
export function buttonDetails(level) {
|
||||||
switch(level) {
|
switch(level) {
|
||||||
case NotificationLevels.WATCHING:
|
case WATCHING_FIRST_POST:
|
||||||
return { id: NotificationLevels.WATCHING, key: 'watching', icon: 'exclamation-circle' };
|
return { id: WATCHING_FIRST_POST, key: 'watching_first_post', icon: 'dot-circle-o' };
|
||||||
case NotificationLevels.TRACKING:
|
case WATCHING:
|
||||||
return { id: NotificationLevels.TRACKING, key: 'tracking', icon: 'circle' };
|
return { id: WATCHING, key: 'watching', icon: 'exclamation-circle' };
|
||||||
case NotificationLevels.MUTED:
|
case TRACKING:
|
||||||
return { id: NotificationLevels.MUTED, key: 'muted', icon: 'times-circle' };
|
return { id: TRACKING, key: 'tracking', icon: 'circle' };
|
||||||
|
case MUTED:
|
||||||
|
return { id: MUTED, key: 'muted', icon: 'times-circle' };
|
||||||
default:
|
default:
|
||||||
return { id: NotificationLevels.REGULAR, key: 'regular', icon: 'circle-o' };
|
return { id: REGULAR, key: 'regular', icon: 'circle-o' };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export const all = [ NotificationLevels.WATCHING,
|
|
||||||
NotificationLevels.TRACKING,
|
export const allLevels = [ WATCHING, TRACKING, WATCHING_FIRST_POST, MUTED, REGULAR ].map(buttonDetails);
|
||||||
NotificationLevels.MUTED,
|
export const topicLevels = allLevels.filter(l => l.id !== WATCHING_FIRST_POST);
|
||||||
NotificationLevels.DEFAULT ].map(buttonDetails);
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ export default Ember.Mixin.create({
|
||||||
operation = { type: 'dismiss_posts' };
|
operation = { type: 'dismiss_posts' };
|
||||||
} else {
|
} else {
|
||||||
operation = { type: 'change_notification_level',
|
operation = { type: 'change_notification_level',
|
||||||
notification_level_id: NotificationLevels.REGULAR };
|
notification_level_id: NotificationLevels.REGULAR };
|
||||||
}
|
}
|
||||||
|
|
||||||
let promise;
|
let promise;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { createWidget } from 'discourse/widgets/widget';
|
import { createWidget } from 'discourse/widgets/widget';
|
||||||
import { all, buttonDetails } from 'discourse/lib/notification-levels';
|
import { topicLevels, buttonDetails } from 'discourse/lib/notification-levels';
|
||||||
import { h } from 'virtual-dom';
|
import { h } from 'virtual-dom';
|
||||||
import RawHTML from 'discourse/widgets/raw-html';
|
import RawHTML from 'discourse/widgets/raw-html';
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ export default createWidget('topic-notifications-button', {
|
||||||
const result = [ this.buttonFor(details.get('notification_level')) ];
|
const result = [ this.buttonFor(details.get('notification_level')) ];
|
||||||
|
|
||||||
if (state.expanded) {
|
if (state.expanded) {
|
||||||
result.push(h('ul.dropdown-menu', all.map(l => this.attach('notification-option', l))));
|
result.push(h('ul.dropdown-menu', topicLevels.map(l => this.attach('notification-option', l))));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrs.appendReason) {
|
if (attrs.appendReason) {
|
||||||
|
|
|
@ -29,8 +29,8 @@ class EmailController < ApplicationController
|
||||||
@watched_count = nil
|
@watched_count = nil
|
||||||
if @topic && @topic.category_id
|
if @topic && @topic.category_id
|
||||||
if CategoryUser.exists?(user_id: @user.id,
|
if CategoryUser.exists?(user_id: @user.id,
|
||||||
notification_level: CategoryUser.notification_levels[:watching],
|
notification_level: CategoryUser.watching_levels,
|
||||||
category_id: @topic.category_id)
|
category_id: @topic.category_id)
|
||||||
@watched_count = TopicUser.joins(:topic)
|
@watched_count = TopicUser.joins(:topic)
|
||||||
.where(:user => @user,
|
.where(:user => @user,
|
||||||
:notification_level => TopicUser.notification_levels[:watching],
|
:notification_level => TopicUser.notification_levels[:watching],
|
||||||
|
@ -74,7 +74,7 @@ class EmailController < ApplicationController
|
||||||
|
|
||||||
CategoryUser.where(user_id: user.id,
|
CategoryUser.where(user_id: user.id,
|
||||||
category_id: topic.category_id,
|
category_id: topic.category_id,
|
||||||
notification_level: CategoryUser.notification_levels[:watching]
|
notification_level: CategoryUser.watching_levels
|
||||||
)
|
)
|
||||||
.destroy_all
|
.destroy_all
|
||||||
updated = true
|
updated = true
|
||||||
|
|
|
@ -10,9 +10,16 @@ class CategoryUser < ActiveRecord::Base
|
||||||
self.where(user: user, category: category)
|
self.where(user: user, category: category)
|
||||||
end
|
end
|
||||||
|
|
||||||
# same for now
|
|
||||||
def self.notification_levels
|
def self.notification_levels
|
||||||
TopicUser.notification_levels
|
@notification_levels ||= Enum.new(muted: 0,
|
||||||
|
regular: 1,
|
||||||
|
tracking: 2,
|
||||||
|
watching: 3,
|
||||||
|
watching_first_post: 4)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.watching_levels
|
||||||
|
[notification_levels[:watching], notification_levels[:watching_first_post]]
|
||||||
end
|
end
|
||||||
|
|
||||||
%w{watch track}.each do |s|
|
%w{watch track}.each do |s|
|
||||||
|
|
|
@ -408,6 +408,9 @@ en:
|
||||||
watching:
|
watching:
|
||||||
title: "Watching"
|
title: "Watching"
|
||||||
description: "You will be notified of every new post in every message, and a count of new replies will be shown."
|
description: "You will be notified of every new post in every message, and a count of new replies will be shown."
|
||||||
|
watching_first_post:
|
||||||
|
title: "Watching First Post Only"
|
||||||
|
description: "You will only be notified of the first post in each new topic in this group."
|
||||||
tracking:
|
tracking:
|
||||||
title: "Tracking"
|
title: "Tracking"
|
||||||
description: "You will be notified if someone mentions your @name or replies to you, and a count of new replies will be shown."
|
description: "You will be notified if someone mentions your @name or replies to you, and a count of new replies will be shown."
|
||||||
|
@ -1811,6 +1814,9 @@ en:
|
||||||
watching:
|
watching:
|
||||||
title: "Watching"
|
title: "Watching"
|
||||||
description: "You will automatically watch all new topics in these categories. You will be notified of every new post in every topic, and a count of new replies will be shown."
|
description: "You will automatically watch all new topics in these categories. You will be notified of every new post in every topic, and a count of new replies will be shown."
|
||||||
|
watching_first_post:
|
||||||
|
title: "Watching First Post Only"
|
||||||
|
description: "You will only be notified of the first post in each new topic in these categories."
|
||||||
tracking:
|
tracking:
|
||||||
title: "Tracking"
|
title: "Tracking"
|
||||||
description: "You will automatically track all new topics in these categories. You will be notified if someone mentions your @name or replies to you, and a count of new replies will be shown."
|
description: "You will automatically track all new topics in these categories. You will be notified if someone mentions your @name or replies to you, and a count of new replies will be shown."
|
||||||
|
@ -2132,6 +2138,9 @@ en:
|
||||||
watching:
|
watching:
|
||||||
title: "Watching"
|
title: "Watching"
|
||||||
description: "You will automatically watch all new topics in this tag. You will be notified of all new posts and topics, plus the count of unread and new posts will also appear next to the topic."
|
description: "You will automatically watch all new topics in this tag. You will be notified of all new posts and topics, plus the count of unread and new posts will also appear next to the topic."
|
||||||
|
watching_first_post:
|
||||||
|
title: "Watching First Post Only"
|
||||||
|
description: "You will only be notified of the first post in each new topic in this tag."
|
||||||
tracking:
|
tracking:
|
||||||
title: "Tracking"
|
title: "Tracking"
|
||||||
description: "You will automatically track all new topics in this tag. A count of unread and new posts will appear next to the topic."
|
description: "You will automatically track all new topics in this tag. A count of unread and new posts will appear next to the topic."
|
||||||
|
|
|
@ -109,6 +109,20 @@ describe EmailController do
|
||||||
|
|
||||||
expect(CategoryUser.find_by(id: cu.id)).to eq(nil)
|
expect(CategoryUser.find_by(id: cu.id)).to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'can unwatch first post from category' do
|
||||||
|
p = Fabricate(:post)
|
||||||
|
key = UnsubscribeKey.create_key_for(p.user, p)
|
||||||
|
|
||||||
|
cu = CategoryUser.create!(user_id: p.user.id,
|
||||||
|
category_id: p.topic.category_id,
|
||||||
|
notification_level: CategoryUser.notification_levels[:watching_first_post])
|
||||||
|
|
||||||
|
post :perform_unsubscribe, key: key, unwatch_category: "1"
|
||||||
|
expect(response.status).to eq(302)
|
||||||
|
|
||||||
|
expect(CategoryUser.find_by(id: cu.id)).to eq(nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context '.unsubscribe' do
|
context '.unsubscribe' do
|
||||||
|
@ -197,6 +211,25 @@ describe EmailController do
|
||||||
expect(response.body).not_to include("unwatch_category")
|
expect(response.body).not_to include("unwatch_category")
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'correctly handles watched first post categories' do
|
||||||
|
post = Fabricate(:post)
|
||||||
|
user = post.user
|
||||||
|
cu = CategoryUser.create!(user_id: user.id,
|
||||||
|
category_id: post.topic.category_id,
|
||||||
|
notification_level: CategoryUser.notification_levels[:watching_first_post])
|
||||||
|
|
||||||
|
|
||||||
|
key = UnsubscribeKey.create_key_for(user, post)
|
||||||
|
get :unsubscribe, key: key
|
||||||
|
expect(response.body).to include("unwatch_category")
|
||||||
|
|
||||||
|
cu.destroy!
|
||||||
|
|
||||||
|
get :unsubscribe, key: key
|
||||||
|
expect(response.body).not_to include("unwatch_category")
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue