thredded-workgroup 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +12 -4
- data/.rubocop_todo.yml +170 -0
- data/.travis.yml +3 -3
- data/CHANGELOG.md +9 -0
- data/Gemfile +1 -0
- data/Guardfile +16 -39
- data/README.md +27 -10
- data/Rakefile +1 -0
- data/app/assets/config/thredded_workgroup_manifest.js +3 -0
- data/app/assets/images/thredded/workgroup/envelope-o.svg +2 -0
- data/app/assets/images/thredded/workgroup/envelope-open-o.svg +2 -0
- data/app/assets/javascripts/thredded-workgroup.js +1 -13
- data/app/assets/javascripts/thredded/workgroup/components/followers.es6 +24 -0
- data/app/assets/javascripts/thredded/workgroup/components/overflow.es6 +60 -0
- data/app/assets/javascripts/thredded/workgroup/components/topics.es6 +151 -0
- data/app/assets/javascripts/thredded/workgroup/core/thredded_workgroup.js +1 -0
- data/app/assets/javascripts/thredded/workgroup/core/touch.es6 +16 -0
- data/app/assets/javascripts/thredded/workgroup/index.js +3 -0
- data/app/assets/stylesheets/thredded-workgroup.scss +2 -0
- data/app/assets/stylesheets/thredded/workgroup/_followers.scss +51 -0
- data/app/assets/stylesheets/thredded/workgroup/_navs.scss +29 -7
- data/app/assets/stylesheets/thredded/workgroup/_overflow.scss +71 -0
- data/app/assets/stylesheets/thredded/workgroup/_topics.scss +186 -16
- data/app/controllers/concerns/thredded/workgroup/all_unread_followed_topics.rb +31 -0
- data/app/controllers/thredded/application_controller.rb +23 -0
- data/app/controllers/thredded/posts_controller.rb +1 -0
- data/app/controllers/thredded/workgroup/application_controller.rb +1 -0
- data/app/controllers/thredded/workgroup/navs_controller.rb +1 -0
- data/app/controllers/thredded/workgroup/read_states_controller.rb +14 -0
- data/app/controllers/thredded/workgroup/topics_controller.rb +18 -0
- data/app/helpers/thredded/application_helper.rb +1 -0
- data/app/helpers/thredded/workgroup/application_helper.rb +1 -0
- data/app/jobs/thredded/workgroup/mark_all_topics_read_job.rb +13 -0
- data/app/view_hooks/thredded/all_view_hooks.rb +9 -0
- data/app/view_hooks/thredded/workgroup/view_hooks.rb +28 -0
- data/app/view_models/thredded/topic_view.rb +17 -0
- data/app/view_models/thredded/topics_page_view.rb +1 -0
- data/app/views/thredded/shared/nav/_unread_topics.html.erb +1 -0
- data/app/views/thredded/topics/_followers.html.erb +23 -0
- data/app/views/thredded/topics/_topic.html.erb +25 -28
- data/app/views/thredded/workgroup/navs/_personal_nav.html.erb +7 -1
- data/app/views/thredded/workgroup/navs/all_topics.html.erb +1 -1
- data/app/views/thredded/workgroup/navs/awaiting.html.erb +1 -1
- data/app/views/thredded/workgroup/navs/following.html.erb +1 -1
- data/app/views/thredded/workgroup/navs/unread.html.erb +1 -1
- data/app/views/thredded/workgroup/topics/_controls.html.erb +21 -0
- data/app/views/thredded/workgroup/topics/_last_post.html.erb +11 -0
- data/app/views/thredded/workgroup/topics/_last_post_with_controls.html.erb +12 -0
- data/app/views/thredded/workgroup/topics/_topics_with_last_post.html.erb +16 -0
- data/bin/rails.rb +1 -0
- data/bin/rspec +1 -0
- data/bin/update_from_thredded +1 -0
- data/config/locales/en.yml +11 -0
- data/config/routes.rb +9 -0
- data/docs/followers-above-post.png +0 -0
- data/docs/navbar.png +0 -0
- data/lib/thredded/workgroup.rb +1 -0
- data/lib/thredded/workgroup/engine.rb +11 -2
- data/lib/thredded/workgroup/thredded_route_delegator.rb +1 -0
- data/lib/thredded/workgroup/version.rb +2 -1
- data/shared.gemfile +4 -0
- data/thredded-workgroup.gemspec +6 -10
- metadata +62 -60
- data/app/assets/javascripts/thredded/workgroup/follow.js +0 -36
- data/app/assets/javascripts/thredded/workgroup/topics.js +0 -18
- data/app/views/thredded/topics/_topics_with_last_post.html.erb +0 -14
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Thredded
|
4
|
+
module Workgroup
|
5
|
+
module AllUnreadFollowedTopics
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
included do
|
8
|
+
include Pundit
|
9
|
+
helper_method :all_unread_followed_topics_count
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [ActiveRecord::Relation]
|
13
|
+
def all_topics_scope
|
14
|
+
@all_topics_scope ||=
|
15
|
+
policy_scope(Thredded::Topic.all).joins(:messageboard).merge(policy_scope(Thredded::Messageboard.all))
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return Integer
|
19
|
+
def all_unread_followed_topics_count
|
20
|
+
@all_unread_followed_topics_count ||=
|
21
|
+
if thredded_signed_in?
|
22
|
+
all_topics_scope.unread_followed_by(thredded_current_user).count
|
23
|
+
else
|
24
|
+
0
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# need to define `thredded_current_user` and possibly `pundit_user`
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency File.expand_path("../../app/controllers/thredded/application_controller",
|
4
|
+
Thredded::Engine.called_from)
|
5
|
+
|
6
|
+
module Thredded
|
7
|
+
module ApplicationControllerRetaining
|
8
|
+
def topics_scope
|
9
|
+
return super if messageboard_or_nil
|
10
|
+
all_topics_scope
|
11
|
+
end
|
12
|
+
|
13
|
+
def unread_followed_topics_count
|
14
|
+
return super if messageboard_or_nil
|
15
|
+
all_unread_followed_topics_count
|
16
|
+
end
|
17
|
+
end
|
18
|
+
class ApplicationController
|
19
|
+
include Thredded::Workgroup::AllUnreadFollowedTopics
|
20
|
+
|
21
|
+
prepend ::Thredded::ApplicationControllerRetaining
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Thredded
|
4
|
+
module Workgroup
|
5
|
+
class ReadStatesController < ::Thredded::Workgroup::ApplicationController
|
6
|
+
before_action :thredded_require_login!
|
7
|
+
|
8
|
+
def mark_all_topics_read
|
9
|
+
::Thredded::Workgroup::MarkAllTopicsReadJob.perform_later(thredded_current_user) if thredded_signed_in?
|
10
|
+
redirect_to request.referer, flash: { notice: "Marking all topics as read (will take a few seconds)" }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# frozen_string_literal: true # frozen_string_literal: true
|
4
|
+
|
5
|
+
module Thredded
|
6
|
+
module Workgroup
|
7
|
+
class TopicsController < Thredded::Workgroup::ApplicationController
|
8
|
+
before_action :thredded_require_login!
|
9
|
+
|
10
|
+
def kick
|
11
|
+
if (user_topic_follow = UserTopicFollow.where(topic_id: params[:id], user_id: params[:user_id]).first)
|
12
|
+
user_topic_follow.destroy
|
13
|
+
end
|
14
|
+
render plain: "Ok"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Thredded
|
4
|
+
module Workgroup
|
5
|
+
class MarkAllTopicsReadJob < ::ActiveJob::Base
|
6
|
+
def perform(user)
|
7
|
+
::Thredded::Topic.unread(user).each do |topic|
|
8
|
+
::Thredded::UserTopicReadState.touch!(user.id, topic.last_post)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Thredded
|
4
|
+
module Workgroup
|
5
|
+
module ViewHooks
|
6
|
+
attr_reader :topic_with_last_post
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
@topic_with_last_post = TopicWithLastPost.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# View hooks for a Topic when displaying last post.
|
14
|
+
class TopicWithLastPost
|
15
|
+
# @return [Thredded::AllViewHooks::ViewHook]
|
16
|
+
attr_reader :last_post_with_controls
|
17
|
+
|
18
|
+
# @return [Thredded::AllViewHooks::ViewHook]
|
19
|
+
attr_reader :last_post
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
@last_post_with_controls = Thredded::AllViewHooks::ViewHook.new
|
23
|
+
@last_post = Thredded::AllViewHooks::ViewHook.new
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_dependency File.expand_path("../../app/view_models/thredded/topic_view", Thredded::Engine.called_from)
|
3
4
|
module Thredded
|
4
5
|
class TopicView < Thredded::BaseTopicView
|
@@ -11,5 +12,21 @@ module Thredded
|
|
11
12
|
page = @read_state.first_unread_post_page || @read_state.last_read_post_page
|
12
13
|
Thredded::UrlsHelper.topic_path(@topic, page: page, anchor: anchor)
|
13
14
|
end
|
15
|
+
|
16
|
+
def reply_path
|
17
|
+
Thredded::UrlsHelper.topic_path(@topic, page: last_page, anchor: "new_post")
|
18
|
+
end
|
19
|
+
|
20
|
+
def mark_as_unread_path
|
21
|
+
Thredded::UrlsHelper.mark_as_unread_post_path(id: last_post.id, format: :json)
|
22
|
+
end
|
23
|
+
|
24
|
+
def mark_as_read_path
|
25
|
+
Thredded::UrlsHelper.mark_as_read_post_path(id: last_post.id, format: :json)
|
26
|
+
end
|
27
|
+
|
28
|
+
def last_page
|
29
|
+
(@topic.posts_count / Thredded.posts_per_page.to_f).ceil # TODO: doesn't account for visibility
|
30
|
+
end
|
14
31
|
end
|
15
32
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<% # overriding thredded's view %>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<% if Thredded.show_topic_followers %>
|
2
|
+
<%= define_svg_icons "thredded/follow.svg", "thredded/unfollow.svg" %>
|
3
|
+
<div class="thredded--topic-followers">
|
4
|
+
<% if topic.followers.length > 0 %>
|
5
|
+
<%= t('thredded.topics.followed_by')%>
|
6
|
+
<% topic.followers.each do |user| %>
|
7
|
+
<span class="thredded--follower user-<%= user.id %>">
|
8
|
+
<%= user_mention(user) %>
|
9
|
+
<%- if user == thredded_current_user %>
|
10
|
+
<%= t("thredded.workgroup.following.you")%>
|
11
|
+
<%- else %>
|
12
|
+
<button class="thredded--follower--remove" data-kick-path="<%= thredded_workgroup.kick_topic_path(topic.to_model.id, user_id: user.id) %>" title="Remove follower" aria-label="Remove follower">
|
13
|
+
<%= shared_inline_svg "thredded/follow.svg", class: "thredded--topics--follow-icon", role: "img" %>
|
14
|
+
<%= shared_inline_svg "thredded/unfollow.svg", class: "thredded--topics--unfollow-icon", role: "img" %>
|
15
|
+
</button>
|
16
|
+
<%- end %>
|
17
|
+
</span>
|
18
|
+
<% end %>
|
19
|
+
<% else %>
|
20
|
+
<%= t('thredded.topics.followed_by_noone')%>
|
21
|
+
<% end %>
|
22
|
+
</div>
|
23
|
+
<% end %>
|
@@ -2,22 +2,18 @@
|
|
2
2
|
id: dom_id(topic),
|
3
3
|
class: ['thredded--topics--topic', topic_css_classes(topic)],
|
4
4
|
data: {topic: topic.id, messageboard: topic.messageboard_id} do %>
|
5
|
-
|
5
|
+
|
6
|
+
<div class="thredded--topic--read-state-toggle">
|
7
|
+
<%= shared_inline_svg("thredded/workgroup/envelope-open-o.svg", class: "thredded--topics--read-icon thredded--icon", role: "img", viewBox: "0 0 1792 1792", title: "Mark as read") %>
|
8
|
+
<%= shared_inline_svg("thredded/workgroup/envelope-o.svg", class: "thredded--topics--unread-icon thredded--icon", role: "img", viewBox: "0 0 1792 1792", title: "Mark as unread") %>
|
9
|
+
</div>
|
6
10
|
|
7
11
|
<h1 class="thredded--topics--title">
|
8
12
|
<span class="thredded--topic-title"><%= link_to topic.title, topic.path %></span>
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
<% end %>
|
14
|
-
<svg viewBox="0 0 116 121" class="thredded--topics--follow-icon">
|
15
|
-
<% if topic.followed? %>
|
16
|
-
<use xlink:href="#thredded-follow-icon"/>
|
17
|
-
<% else %>
|
18
|
-
<use xlink:href="#thredded-unfollow-icon"/>
|
19
|
-
<% end %>
|
20
|
-
</svg>
|
13
|
+
<a href="#" class="thredded-follow-toggle js-thredded-follow-toggle">
|
14
|
+
<%= shared_inline_svg "thredded/follow.svg", class: "thredded--topics--follow-icon", role: "img" %>
|
15
|
+
<%= shared_inline_svg "thredded/unfollow.svg", class: "thredded--topics--unfollow-icon", role: "img" %>
|
16
|
+
</a>
|
21
17
|
</h1>
|
22
18
|
|
23
19
|
<% if topic.categories.any? %>
|
@@ -26,26 +22,27 @@
|
|
26
22
|
</ul>
|
27
23
|
<% end %>
|
28
24
|
|
25
|
+
<cite class="thredded--topics--updated-by">
|
26
|
+
<%= time_ago topic.last_post_at %>
|
27
|
+
<%= user_link topic.last_user %>
|
28
|
+
</cite>
|
29
|
+
|
30
|
+
<% if local_assigns[:show_messageboard] %>
|
31
|
+
<span class="thredded--topics--messageboard">
|
32
|
+
<%= t 'thredded.topics.in_messageboard_html',
|
33
|
+
messageboard_link: link_to(topic.messageboard_name, topic.messageboard_path) %>
|
34
|
+
</span>
|
35
|
+
<% end %>
|
29
36
|
|
30
37
|
<% if topic.blocked? && topic.can_moderate? %>
|
31
38
|
<span class="thredded--topics--moderation-state thredded--alert thredded--alert-danger">
|
32
39
|
<%= render 'thredded/shared/content_moderation_blocked_state', moderation_record: topic.last_moderation_record %>
|
33
40
|
</span>
|
34
41
|
<% end %>
|
42
|
+
<%= render 'thredded/workgroup/topics/last_post_with_controls', topic: topic if topic.last_post %>
|
43
|
+
<% end %>
|
35
44
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
<div class="thredded--topic-source">
|
40
|
-
<cite class="thredded--topics--updated-by">
|
41
|
-
<%= topic.last_user.thredded_display_name %>
|
42
|
-
<%= time_ago topic.last_post_at %>
|
43
|
-
</cite>
|
44
|
-
</div>
|
45
|
-
|
46
|
-
<div class="thredded--last-post">
|
47
|
-
<%= render 'thredded/posts_common/content', post: topic.last_post if topic.last_post %>
|
48
|
-
</div>
|
49
|
-
</div>
|
50
|
-
|
45
|
+
<% if local_assigns[:sticky_topics_divider] &&
|
46
|
+
!topic_iteration.last? && topic.sticky? && !topics[topic_counter + 1].sticky? %>
|
47
|
+
<%= render 'thredded/topics/sticky_topics_divider' %>
|
51
48
|
<% end %>
|
@@ -1,6 +1,12 @@
|
|
1
1
|
<ul class="thredded--workgroup">
|
2
2
|
<li class="<%= Thredded::Workgroup.navbar_class(params, :unread) %>">
|
3
|
-
<%= link_to
|
3
|
+
<%= link_to thredded_workgroup.unread_nav_path do%>
|
4
|
+
<%= t('thredded.workgroup.unread.link') %>
|
5
|
+
<% if all_unread_followed_topics_count > 0 -%>
|
6
|
+
<span class="thredded--user-navigation--unread-topics--followed-count"><%=shared_inline_svg "thredded/follow.svg", class: "thredded--unread-topics--followed-icon", role:"img" %>
|
7
|
+
<%= all_unread_followed_topics_count %></span>
|
8
|
+
<% end -%>
|
9
|
+
<% end -%>
|
4
10
|
</li>
|
5
11
|
<li class="<%= Thredded::Workgroup.navbar_class(params, :awaiting) %>">
|
6
12
|
<%= link_to thredded_workgroup.awaiting_nav_path do %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<div class="thredded--topic-controls">
|
2
|
+
<a class="thredded--topic--read-state-toggle thredded--topic--mark-as-read thredded--button" data-post-path="<%= topic.mark_as_read_path %>">
|
3
|
+
<%= shared_inline_svg("thredded/workgroup/envelope-open-o.svg", class: "thredded--topics--read-icon thredded--icon", role: "img", viewBox: "0 0 1792 1792") %>
|
4
|
+
<%= t("thredded.topics.mark_read")%>
|
5
|
+
</a>
|
6
|
+
<a class="thredded--topic--read-state-toggle thredded--topic--mark-as-unread thredded--button" data-post-path="<%= topic.mark_as_unread_path %>">
|
7
|
+
<%= shared_inline_svg("thredded/workgroup/envelope-o.svg", class: "thredded--topics--unread-icon thredded--icon", role: "img", viewBox: "0 0 1792 1792") %>
|
8
|
+
<%= t("thredded.topics.mark_unread")%>
|
9
|
+
</a>
|
10
|
+
<a class="thredded--topic--view-button thredded--button" href="<%= topic.reply_path %>">
|
11
|
+
<%= t("thredded.topics.view_or_reply")%>
|
12
|
+
</a>
|
13
|
+
<a href="#" class="js-thredded-follow-toggle thredded--topic--follow thredded--button">
|
14
|
+
<%= shared_inline_svg "thredded/follow.svg", class: "thredded--icon", role: "img" %>
|
15
|
+
<%= t("thredded.topics.follow")%>
|
16
|
+
</a>
|
17
|
+
<a href="#" class="js-thredded-follow-toggle thredded--topic--unfollow thredded--button">
|
18
|
+
<%= shared_inline_svg "thredded/unfollow.svg", class: "thredded--icon", role: "img" %>
|
19
|
+
<%= t("thredded.topics.unfollow")%>
|
20
|
+
</a>
|
21
|
+
</div>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%= view_hooks.topic_with_last_post.last_post.render self, topic: topic do %>
|
2
|
+
<div class="thredded--topic-source">
|
3
|
+
<cite class="thredded--topics--updated-by">
|
4
|
+
<%= topic.last_user.thredded_display_name %>
|
5
|
+
<%= time_ago topic.last_post_at %>
|
6
|
+
</cite>
|
7
|
+
</div>
|
8
|
+
<div class="thredded--last-post">
|
9
|
+
<%= render 'thredded/posts_common/content', post: topic.last_post %>
|
10
|
+
</div>
|
11
|
+
<% end %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= view_hooks.topic_with_last_post.last_post_with_controls.render self, topic: topic do %>
|
2
|
+
<div class="thredded--topic-last-post-with-controls">
|
3
|
+
<%= render "thredded/workgroup/topics/controls", topic: topic %>
|
4
|
+
<div class='thredded--topic-post-and-last-user thredded--condensable thredded--condensable--condensed'>
|
5
|
+
<%= render "thredded/workgroup/topics/last_post", topic: topic %>
|
6
|
+
<div class="thredded--condensable--overflow-only">
|
7
|
+
<span class="thredded--condensable--expand"><%= t("thredded.workgroup.condensable.read_all") %></span>
|
8
|
+
<span class="thredded--condensable--condense"><%= t("thredded.workgroup.condensable.read_less") %></span>
|
9
|
+
</div>
|
10
|
+
</div>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<%= define_svg_icons 'thredded/follow.svg', 'thredded/unfollow.svg' %>
|
2
|
+
|
3
|
+
<%= thredded_page do %>
|
4
|
+
<%= content_tag :section, class: 'thredded--main-section thredded--topics', 'data-thredded-topics' => true do %>
|
5
|
+
<%= render @topics, show_messageboard: !messageboard_or_nil %>
|
6
|
+
<% end %>
|
7
|
+
|
8
|
+
<%= link_to t("thredded.nav.mark_all_read"),
|
9
|
+
mark_all_topics_read_path,
|
10
|
+
class: 'thredded--button thredded--button-light thredded--button-wide',
|
11
|
+
method: :put -%>
|
12
|
+
|
13
|
+
<footer>
|
14
|
+
<%= paginate @topics %>
|
15
|
+
</footer>
|
16
|
+
<% end %>
|
data/bin/rails.rb
CHANGED
data/bin/rspec
CHANGED
data/bin/update_from_thredded
CHANGED
@@ -21,6 +21,7 @@ cp -pR $(bundle show thredded)/spec/dummy ./spec/dummy
|
|
21
21
|
|
22
22
|
# update some standard helpful files
|
23
23
|
cp $(bundle show thredded)/spec/support/features/fake_content.rb spec/support/features/fake_content.rb
|
24
|
+
cp $(bundle show thredded)/spec/lib/thredded/all_view_hooks_spec.rb spec/lib/thredded/all_view_hooks_spec.rb
|
24
25
|
|
25
26
|
# restore thredded-workgroup config, emoji
|
26
27
|
mv ./tmp/upgradecache/thredded_workgroup.rb ./spec/dummy/config/initializers/
|