diff --git a/app/assets/stylesheets/content.css.scss b/app/assets/stylesheets/content.css.scss index 50930eab..f1e18ee1 100644 --- a/app/assets/stylesheets/content.css.scss +++ b/app/assets/stylesheets/content.css.scss @@ -173,4 +173,8 @@ p.long-form { color: orange !important; cursor: pointer; } -} \ No newline at end of file +} + +.spaced-paragraphs p { + margin-bottom: 1em; +} diff --git a/app/controllers/page_collection_submissions_controller.rb b/app/controllers/page_collection_submissions_controller.rb index ca3e069f..e3b0881e 100644 --- a/app/controllers/page_collection_submissions_controller.rb +++ b/app/controllers/page_collection_submissions_controller.rb @@ -25,7 +25,9 @@ class PageCollectionSubmissionsController < ApplicationController @page_collection_submission = PageCollectionSubmission.new(page_collection_submission_params) if @page_collection_submission.save - @page_collection_submission.content.update(privacy: 'public') + if @page_collection_submission.page_collection.try(:privacy) == 'public' + @page_collection_submission.content.update(privacy: 'public') + end redirect_to @page_collection_submission.page_collection, notice: 'Page submitted!' else diff --git a/app/controllers/page_collections_controller.rb b/app/controllers/page_collections_controller.rb index 2b18486d..55ad5398 100644 --- a/app/controllers/page_collections_controller.rb +++ b/app/controllers/page_collections_controller.rb @@ -2,16 +2,25 @@ class PageCollectionsController < ApplicationController before_action :authenticate_user!, except: [:show] before_action :set_sidenav_expansion - before_action :set_page_collection, only: [:show, :edit, :update, :destroy, :follow, :unfollow, :report] + before_action :set_navbar_color + + before_action :set_page_collection, only: [:show, :edit, :by_user, :update, :destroy, :follow, :unfollow, :report] + before_action :set_submittable_content, only: [:show, :by_user] # GET /page_collections def index @my_collections = current_user.page_collections + pending_submissions = PageCollectionSubmission.where(accepted_at: nil, page_collection_id: @my_collections.pluck(:id)) + @collections_with_pending = PageCollection.where(id: pending_submissions.pluck(:page_collection_id)) + followed_user_ids = UserFollowing.where(user_id: current_user.id).pluck(:followed_user_id) @network_collections = PageCollection.where(user_id: followed_user_ids, privacy: 'public') + @followed_collections = current_user.followed_page_collections - @random_collections = PageCollection.where(privacy: 'public').sample(9) + @random_collections = PageCollection.where(privacy: 'public').where.not( + id: @my_collections.pluck(:id) + @network_collections.pluck(:id) + @followed_collections.pluck(:id) + ).sample(9) end # GET /page_collections/1 @@ -20,14 +29,8 @@ class PageCollectionsController < ApplicationController return redirect_to page_collections_path, notice: "That Collection is not public." end - @pages = @page_collection.accepted_submissions + @pages = @page_collection.accepted_submissions.includes({content: [:universe, :user], user: []}) sort_pages - - @submittable_content = if user_signed_in? - @current_user_content.slice(*@page_collection.page_types) - else - [] - end end # GET /page_collections/new @@ -95,8 +98,11 @@ class PageCollectionsController < ApplicationController Rails.application.config.content_types[:all].each do |content_type| define_method(content_type.name.downcase.pluralize.to_sym) do set_page_collection + set_submittable_content - @pages = @page_collection.accepted_submissions.where(content_type: content_type.name) + @show_page_type_highlight = true + @page_type = content_type + @pages = @page_collection.accepted_submissions.where(content_type: content_type.name).includes({content: [:universe, :user], user: []}) sort_pages render :show @@ -125,15 +131,9 @@ class PageCollectionsController < ApplicationController return redirect_to page_collections_path, notice: "That Collection is not public." end - @pages = @page_collection.accepted_submissions.where(user_id: params[:user_id]) + @pages = @page_collection.accepted_submissions.where(user_id: params[:user_id]).includes({content: [:universe, :user], user: []}) sort_pages - @submittable_content = if user_signed_in? - @current_user_content.slice(*@page_collection.page_types) - else - [] - end - @show_contributor_highlight = true @highlighted_contributor = User.find_by(id: params[:user_id].to_i) render :show @@ -143,7 +143,16 @@ class PageCollectionsController < ApplicationController # Use callbacks to share common setup or constraints between actions. def set_page_collection - @page_collection = PageCollection.find(params[:id]) + @page_collection = PageCollection.find_by(id: params[:id]) + @page_collection ||= PageCollection.find_by(id: params[:page_collection_id]) + end + + def set_submittable_content + @submittable_content ||= if user_signed_in? + @current_user_content.slice(*@page_collection.page_types) + else + {} + end end # Only allow a trusted parameter "white list" through. @@ -161,6 +170,10 @@ class PageCollectionsController < ApplicationController def set_sidenav_expansion @sidenav_expansion = 'community' end + + def set_navbar_color + @navbar_color = PageCollection.hex_color + end def sort_pages case params.permit(:sort).fetch('sort', nil) @@ -168,6 +181,8 @@ class PageCollectionsController < ApplicationController @pages = @pages.reorder('cached_content_name ASC') when 'chronological' @pages = @pages.reorder('accepted_at ASC') + when 'shuffle' + @pages = @pages.shuffle when 'recent' @pages = @pages.reorder('accepted_at DESC') when nil diff --git a/app/controllers/stream_controller.rb b/app/controllers/stream_controller.rb index 29c1c570..7ac733b9 100644 --- a/app/controllers/stream_controller.rb +++ b/app/controllers/stream_controller.rb @@ -6,28 +6,30 @@ class StreamController < ApplicationController before_action :cache_linkable_content_for_each_content_type, only: [:index] def index - followed_users = current_user.followed_users.pluck(:id) - blocked_users = current_user.blocked_users.pluck(:id) + followed_users = current_user.followed_users.pluck(:id) + blocked_users = current_user.blocked_users.pluck(:id) blocked_by_users = current_user.blocked_by_users.pluck(:id) @feed = ContentPageShare.where(user_id: followed_users + [current_user.id] - blocked_users - blocked_by_users) .order('created_at DESC') - .includes([:content_page, :user, :share_comments]) - .limit(50) + .includes([:content_page, :secondary_content_page]) + .includes({ share_comments: [:user], user: [:avatar_attachment] }) + .limit(25) end def community end def global - blocked_users = current_user.blocked_users.pluck(:id) + blocked_users = current_user.blocked_users.pluck(:id) blocked_by_users = current_user.blocked_by_users.pluck(:id) @feed = ContentPageShare.all .where.not(user_id: blocked_users + blocked_by_users) .order('created_at DESC') - .includes([:content_page, :user, :share_comments]) - .limit(50) + .includes([:content_page, :secondary_content_page]) + .includes({ share_comments: [:user], user: [:avatar_attachment] }) + .limit(25) end def set_stream_navbar_color diff --git a/app/javascript/components/PageCollectionCreationForm.js b/app/javascript/components/PageCollectionCreationForm.js new file mode 100644 index 00000000..8cf5ca87 --- /dev/null +++ b/app/javascript/components/PageCollectionCreationForm.js @@ -0,0 +1,180 @@ +/* + Usage: + <%= react_component("PageCollectionCreationForm", {}) %> +*/ + +import React from "react" +import PropTypes from "prop-types" + +import Stepper from '@material-ui/core/Stepper'; +import Step from '@material-ui/core/Step'; +import StepLabel from '@material-ui/core/StepLabel'; +import StepContent from '@material-ui/core/StepContent'; +import Button from '@material-ui/core/Button'; +import Paper from '@material-ui/core/Paper'; +import Typography from '@material-ui/core/Typography'; + +class PageCollectionCreationForm extends React.Component { + + constructor(props) { + super(props); + + this.state = { + active_step: 0 + } + + this.handleNext = this.handleNext.bind(this); + this.handleBack = this.handleBack.bind(this); + this.handleReset = this.handleReset.bind(this); + } + + handleNext() { + this.setState({ active_step: this.state.active_step + 1 }); + }; + + handleBack() { + this.setState({ active_step: this.state.active_step - 1 }); + }; + + handleReset() { + this.setState({ active_step: 0 }); + }; + + classIcon(class_name) { + return window.ContentTypeData[class_name].icon; + } + + classColor(class_name) { + return window.ContentTypeData[class_name].color; + } + + steps() { + return ['Basic information', 'Acceptable pages', 'Privacy settings']; + } + + getStepContent(step) { + switch (step) { + case 0: + return( +
+ + Let's get started with some basic information. + +
+ + +
+
+ + +
+
+ + +
+
+

Header image (optional)

+
+
+ Upload + +
+
+ +
+
+
+ Supported file types: .png, .jpg, .jpeg, .gif +
+
+

+
+ ); + case 1: + return ( +
+ + Please check the types of pages you would like to allow in this collection. A small number of page types is recommended. + +
+ {this.props.all_content_types.map(function(type) { + return( +

+ +

+ ); + })} + +
+
+ ); + case 2: + return ( +
+ + By default, all Collections are private. However, you can choose to make your Collection public at any time, and you can also choose to + accept submissions from other users! + +
+ ); + + default: + return 'Unknown step'; + } + } + + render () { + return ( +
+ + {this.steps().map((label, index) => ( + + {label} + + {this.getStepContent(index)} +
+
+ + +
+
+
+
+ ))} +
+ {this.state.active_step === this.steps().length && ( + + All steps completed - you're finished! + + + )} +
+ ); + } +} + +PageCollectionCreationForm.propTypes = { + document_id: PropTypes.number +}; + +export default PageCollectionCreationForm; \ No newline at end of file diff --git a/app/models/page_collections/page_collection.rb b/app/models/page_collections/page_collection.rb index 062219b5..0347939d 100644 --- a/app/models/page_collections/page_collection.rb +++ b/app/models/page_collections/page_collection.rb @@ -1,3 +1,4 @@ + class PageCollection < ApplicationRecord acts_as_paranoid @@ -66,6 +67,10 @@ class PageCollection < ApplicationRecord 'brown' end + def self.hex_color + '#795548' + end + def self.icon 'layers' end diff --git a/app/models/page_collections/page_collection_submission.rb b/app/models/page_collections/page_collection_submission.rb index 471c7fa6..2b682263 100644 --- a/app/models/page_collections/page_collection_submission.rb +++ b/app/models/page_collections/page_collection_submission.rb @@ -5,6 +5,10 @@ class PageCollectionSubmission < ApplicationRecord belongs_to :page_collection belongs_to :user + after_create :mark_related_content_public + after_create :handle_auto_accept + after_create :create_submission_notification + after_create :cache_content_name scope :accepted, -> { where.not(accepted_at: nil).uniq(&:page_collection_id) } @@ -39,17 +43,35 @@ class PageCollectionSubmission < ApplicationRecord page_collection.user.content_page_share_followings.create({content_page_share: share}) end - after_create do + def mark_related_content_public + if page_collection.try(:privacy) == 'public' + content.update(privacy: 'public') + end + end + + def handle_auto_accept # If the submission was created by the collection owner, we want to automatically approve it. # If the collection has opted to automatically accept submissions, we also want to approve it. if user == page_collection.user || page_collection.auto_accept? update(accepted_at: DateTime.current) - # TODO Create a "user added a page to their collection" event + # Create a "user added a page to their collection" event if the page and the collection are public + if page_collection.try(:privacy) == 'public' + share = ContentPageShare.create( + user_id: self.user_id, + content_page_type: PageCollection.name, + content_page_id: page_collection_id, + secondary_content_page_type: content.class.name, + secondary_content_page_id: content.id, + shared_at: self.created_at, + privacy: 'public', + message: self.explanation + ) + end end end - after_create do + def create_submission_notification # If the submission needs reviewed, create a notification for the collection owner if user != page_collection.user && !page_collection.auto_accept? page_collection.user.notifications.create( diff --git a/app/models/users/user.rb b/app/models/users/user.rb index 06d87a05..f498643b 100644 --- a/app/models/users/user.rb +++ b/app/models/users/user.rb @@ -75,6 +75,7 @@ class User < ApplicationRecord @published_in_page_collections ||= PageCollection.where(id: ids) end has_many :page_collection_followings, dependent: :destroy + has_many :followed_page_collections, through: :page_collection_followings, source: :page_collection has_many :page_collection_reports, dependent: :destroy has_many :votes, dependent: :destroy diff --git a/app/views/content/components/_parallax_header.html.erb b/app/views/content/components/_parallax_header.html.erb index a042409b..ec26797f 100644 --- a/app/views/content/components/_parallax_header.html.erb +++ b/app/views/content/components/_parallax_header.html.erb @@ -2,13 +2,15 @@ diff --git a/app/views/content_page_shares/_stream_added_to_page_collection.html.erb b/app/views/content_page_shares/_stream_added_to_page_collection.html.erb index 221b9e93..ece8decb 100644 --- a/app/views/content_page_shares/_stream_added_to_page_collection.html.erb +++ b/app/views/content_page_shares/_stream_added_to_page_collection.html.erb @@ -8,7 +8,11 @@ <%= image_tag share.user.image_url(size=20), class: 'left circle avatar' %> <%= share.user.display_name %> <% end %> - got accepted into the + <% if share.user == content.user %> + added a <%= share.secondary_content_page.class.name.downcase %> to their + <% else %> + got accepted into the + <% end %> <%= link_to content.title, content, class: "#{content.class.color}-text text-darken-1" %> Collection! @@ -22,13 +26,28 @@
- <%= link_to [share.user, share] do %> - <%= image_tag content.random_public_image %> + <% if share.user == content.user %> + <%= link_to [share.user, share] do %> + <%= image_tag secondary_content.random_public_image %> + <% end %> + <% else %> + <%= link_to [share.user, share] do %> + <%= image_tag content.random_public_image %> + <% end %> <% end %> - <%= link_to content do %> - <%= content.class.icon %> - <%= content.title %> + <% if share.user_id == content.user_id %> + <%# if this is a share for adding content you own to your own collection, show the content instead of the collection %> + <%= link_to secondary_content do %> + <%= secondary_content.class.icon %> + <%= secondary_content.name %> + <% end %> + + <% else %> + <%= link_to content do %> + <%= content.class.icon %> + <%= content.title %> + <% end %> <% end %>
@@ -42,11 +61,26 @@ <%= share.user.display_name %> <% end %> - submitted - <%= link_to share.secondary_content_page.name, share.secondary_content_page, class: "#{share.secondary_content_page.class.color}-text" %> - to - <%= link_to content.title, content, class: "#{content.class.color}-text text-lighten-2" %> - and got accepted! + <% if secondary_content.user_id == share.user_id %> + added + <%= link_to secondary_content.name, secondary_content, class: "#{secondary_content.class.color}-text" %> + to their Collection! + +

+ <%= link_to content, class: "btn #{PageCollection.color} hoverable left white-text clearfix", style: 'width: 100%' do %> + <%= PageCollection.icon %> + <%= content.name %> + arrow_right + <% end %> +
+ + <% else %> + submitted + <%= link_to secondary_content.name, secondary_content, class: "#{secondary_content.class.color}-text" %> + to + <%= link_to content.title, content, class: "#{content.class.color}-text text-lighten-2" %> + and got accepted! + <% end %>
<% if share.message.present? %> diff --git a/app/views/content_page_shares/show.html.erb b/app/views/content_page_shares/show.html.erb index e8bac02a..465259ad 100644 --- a/app/views/content_page_shares/show.html.erb +++ b/app/views/content_page_shares/show.html.erb @@ -67,7 +67,7 @@
-