Merge pull request #767 from indentlabs/collections-improvements

Collections improvements
This commit is contained in:
Andrew Brown 2020-10-12 03:23:27 -07:00 committed by GitHub
commit b84a70702c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 762 additions and 164 deletions

View File

@ -173,4 +173,8 @@ p.long-form {
color: orange !important;
cursor: pointer;
}
}
}
.spaced-paragraphs p {
margin-bottom: 1em;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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(
<div className="spaced-paragraphs">
<Typography>
Let's get started with some basic information.
</Typography>
<div className="input-field">
<label>Collection title</label>
<input type="text" name="page_collection[title]" />
</div>
<div className="input-field">
<label>Subtitle <span className="grey-text">(optional)</span></label>
<input type="text" name="page_collection[subtitle]" />
</div>
<div className="input-field">
<label>Description</label>
<input type="text" name="page_collection[description]" />
</div>
<div>
<p className="grey-text">Header image (optional)</p>
<div className="file-field input-field">
<div className="blue btn">
<span>Upload</span>
<input type="file" name="page_collection[header_image]" />
</div>
<div className="file-path-wrapper">
<input className="file-path validate" type="text" placeholder="Upload an image" />
</div>
</div>
<div className="help-text">
Supported file types: .png, .jpg, .jpeg, .gif
</div>
</div>
<br /><br />
</div>
);
case 1:
return (
<div>
<Typography>
Please check the types of pages you would like to allow in this collection. A small number of page types is recommended.
</Typography>
<div className="row">
{this.props.all_content_types.map(function(type) {
return(
<p className="col s12 m6 l4">
<label>
<input name="page_collection[page_types[Universe]]" type="hidden" value="0" />
<input type="checkbox" value="1" name="page_collection[page_types[Universe]]" />
<span className="purple-text">
<i className="material-icons left">language</i>
Universes
</span>
</label>
</p>
);
})}
</div>
</div>
);
case 2:
return (
<div>
<Typography>
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!
</Typography>
</div>
);
default:
return 'Unknown step';
}
}
render () {
return (
<div className='card-panel'>
<Stepper activeStep={this.state.active_step} orientation="vertical">
{this.steps().map((label, index) => (
<Step key={label}>
<StepLabel>{label}</StepLabel>
<StepContent>
{this.getStepContent(index)}
<div>
<div>
<Button
disabled={this.state.active_step === 0}
onClick={this.handleBack}
>
Back
</Button>
<Button
variant="contained"
color="primary"
onClick={this.handleNext}
>
{this.state.active_step === this.steps().length - 1 ? 'Finish' : 'Next'}
</Button>
</div>
</div>
</StepContent>
</Step>
))}
</Stepper>
{this.state.active_step === this.steps().length && (
<Paper square elevation={0}>
<Typography>All steps completed - you're finished!</Typography>
<Button onClick={this.handleReset}>
Reset
</Button>
</Paper>
)}
</div>
);
}
}
PageCollectionCreationForm.propTypes = {
document_id: PropTypes.number
};
export default PageCollectionCreationForm;

View File

@ -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

View File

@ -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(

View File

@ -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

View File

@ -2,13 +2,15 @@
<ul class="slides">
<li>
<%= image_tag "card-headers/#{content_type.downcase.pluralize}.jpg" %>
<div class="caption center-align bordered-text">
<h4>
<i class="material-icons <%= content_class.color %>-text"><%= content_class.icon %></i>
<%= content_type.titleize.pluralize %>
</h4>
<h5 class="light grey-text text-lighten-3"><%= t("content_oneliners.#{content_type.downcase}") %></h5>
</div>
<% unless defined?(image_only) && !!image_only %>
<div class="caption center-align bordered-text">
<h4>
<i class="material-icons <%= content_class.color %>-text"><%= content_class.icon %></i>
<%= content_type.titleize.pluralize %>
</h4>
<h5 class="light grey-text text-lighten-3"><%= t("content_oneliners.#{content_type.downcase}") %></h5>
</div>
<% end %>
</li>
</ul>
</div>

View File

@ -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!
<span class="right">
@ -22,13 +26,28 @@
<div class="main-container hoverable card row clearfix">
<div class="col s12 m6 l6">
<div class="card-image">
<%= 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 %>
<span class="card-title">
<%= link_to content do %>
<i class="material-icons tiny <%= content.class.color %>-text"><%= content.class.icon %></i>
<span class="white-text bordered-text"><%= content.title %></i>
<% 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 %>
<i class="material-icons tiny <%= secondary_content.class.color %>-text"><%= secondary_content.class.icon %></i>
<span class="white-text bordered-text"><%= secondary_content.name %></i>
<% end %>
<% else %>
<%= link_to content do %>
<i class="material-icons tiny <%= content.class.color %>-text"><%= content.class.icon %></i>
<span class="white-text bordered-text"><%= content.title %></i>
<% end %>
<% end %>
</span>
</div>
@ -42,11 +61,26 @@
<%= share.user.display_name %>
<% end %>
<span class="helper-text">
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 <span class="orange-text">accepted</span>!
<% 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!
<br /><br />
<%= link_to content, class: "btn #{PageCollection.color} hoverable left white-text clearfix", style: 'width: 100%' do %>
<i class="material-icons left"><%= PageCollection.icon %></i>
<span class="left"><%= content.name %></span>
<i class="material-icons right">arrow_right</i>
<% end %>
<div class="clearfix"></div>
<% 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 <span class="orange-text">accepted</span>!
<% end %>
</span>
</div>
<% if share.message.present? %>

View File

@ -67,7 +67,7 @@
</ul>
</div>
<div>
<ul class="">
<ul>
<li class="grey-text uppercase">
Reshare to...
</li>

View File

@ -2,7 +2,11 @@
<div class="col s12">
<div class="card">
<div class="card-content">
<div class="card-title">Pending submissions</div>
<div class="card-title">
You have <%= pluralize @page_collection_submissions.count, 'pending submission' %>
to
<%= link_to @page_collection.name, @page_collection, class: "#{PageCollection.color}-text" %>.
</div>
<p>
Submitters will be notified if you accept their content.
</p>
@ -30,18 +34,18 @@
</blockquote>
<div>
Submitted by
<%= link_to content.user, class: "#{User.color}-text" do %>
<%= link_to content.user, class: "#{User.color}-text text-lighten-3" do %>
<%= content.user.display_name %>
<% end %>
<%= time_ago_in_words page_collection_submission.submitted_at %> ago
</div>
</div>
<div class="card-action">
<%= link_to approve_page_collection_submission_path(page_collection_submission), class: 'green-text' do %>
<%= link_to approve_page_collection_submission_path(page_collection_submission), class: 'btn green white-text' do %>
<i class="material-icons left">check</i>
Approve
<% end %>
<%= link_to pass_page_collection_submission_path(page_collection_submission), class: 'red-text right' do %>
<%= link_to pass_page_collection_submission_path(page_collection_submission), class: 'btn red white-text right' do %>
<i class="material-icons left">close</i>
Pass
<% end %>

View File

@ -1,4 +0,0 @@
<p id="notice"><%= notice %></p>
<%= link_to 'Edit', edit_page_collection_submission_path(@page_collection_submission) %> |
<%= link_to 'Back', page_collection_submissions_path %>

View File

@ -0,0 +1,25 @@
<h1 class="center" style="font-size: 2em">
<i class="material-icons <%= PageCollection.color %>-text"><%= PageCollection.icon %></i>
<%= title %>
</h1>
<% collection_list.each do |collection| %>
<div class="col s12 m6 l4">
<%= link_to collection do %>
<div class="hoverable card <%= PageCollection.color %>" style="height: 250px">
<div class="card-image">
<%= image_tag collection.random_public_image, style: 'max-height: 250px;' %>
<span class="card-title bordered-text">
<%= collection.title %>
<br />
<small>
<% collection.page_types.each do |icon| %>
<% klass = icon.constantize %>
<i class="material-icons left tooltipped tiny <%= klass.color %>-text" data-tooltip="<%= icon.pluralize %>"><%= klass.icon %></i>
<% end %>
</small>
</span>
</div>
</div>
<% end %>
</div>
<% end %>

View File

@ -0,0 +1,4 @@
<div class="card-panel <%= PageCollection.color %> darken-3 white-text">
Showing all submitted pages from <%= link_to contributor.display_name, contributor, class: "#{User.color}-text" %>.
Click <%= link_to 'here', @page_collection, class: 'blue-text text-lighten-3' %> to see all pages regardless of author.
</div>

View File

@ -1,3 +1,8 @@
<%# react_component("PageCollectionCreationForm", {
all_content_types: Rails.application.config.content_types[:all].map(&:name),
active_content_types: page_collection.page_types
}) %>
<%= form_with(model: page_collection, local: true) do |f| %>
<% if page_collection.errors.any? %>
<div id="error_explanation">
@ -62,7 +67,8 @@
<div class="card-title">Acceptable pages</div>
<p class="grey-text">
Please check the types of pages you would like to allow in this collection. A small number of page types is recommended.
Please check the types of pages you'll allow to be submitted or added to this in this collection. A small number of page types is recommended.
You can change this at any time.
</p>
<br />

View File

@ -0,0 +1,5 @@
<div class="card-panel <%= page_type.color %> darken-3 white-text">
Showing all submitted <%= page_type.name %> pages.
Click <%= link_to 'here', @page_collection, class: 'blue-text text-lighten-3' %> to see all pages regardless of type.
</div>

View File

@ -1,5 +1,5 @@
<% if user_signed_in? && (@page_collection.allow_submissions? || @page_collection.user == current_user) %>
<ul class="collapsible">
<ul class="hoverable collapsible">
<li>
<div class="collapsible-header blue white-text">
<i class="material-icons <%= PageCollection.color %>-text text-darken-2"><%= PageCollection.icon %></i>
@ -21,7 +21,10 @@
<% end %>
<label>Select a page to <%= @page_collection.user == current_user ? 'add' : 'submit' %></label>
<div class="helper-text">
Submitting a page will automatically change its privacy to "public".
Submitting a page will automatically change its privacy to "public" if this collection is public.
<% if @page_collection.privacy == 'public' %>
(It is!)
<% end %>
</div>
</div>

View File

@ -88,4 +88,31 @@
<li><%= link_to pluralize(@page_collection.pending_submissions.count, 'pending submission'), page_collection_pending_submissions_path(page_collection_id: @page_collection.id) %></li>
<li><%= link_to 'Edit this collection', edit_page_collection_path(@page_collection) %></li>
</ul>
<% end %>
<% end %>
<ul>
<li class="grey-text uppercase">
Share collection to...
</li>
<li>
<%= link_to [
'http://twitter.com/share?',
'url=' + URI::escape(page_collection_url(@page_collection)),
'&text=' + URI::escape("I'm building a collection of fictional " + @page_collection.page_types.map(&:pluralize).map(&:downcase).to_sentence + " on Notebook.ai. Check it out!")
].join, class: 'blue-text', target: '_blank' do %>
<i class="material-icons tiny left" style="margin-top: 4px;">share</i>
Twitter
<% end %>
</li>
<li>
<%=
link_to "https://www.facebook.com/sharer/sharer.php?app_id=1523926344336934&u=#{URI::escape(page_collection_url(@page_collection))}&display=popup&ref=plugin&src=share_button",
class: 'blue-text',
onclick: "return !window.open(this.href, 'Facebook', 'width=640,height=580')" do
%>
<i class="material-icons tiny left" style="margin-top: 4px">share</i>
Facebook
<% end %>
</li>
</ul>

View File

@ -5,12 +5,20 @@
Trending
<% end %>
-->
<%= link_to params.permit(:sort).merge({sort: 'alphabetical'}), class: 'btn btn-flat' do %>
<%= link_to params.permit(:sort).merge({sort: 'alphabetical'}), class: 'btn btn-flat tooltipped', data: { tooltip: "Show pages in this collection alphabetically, by name" } do %>
<i class="material-icons left">sort</i>
Alphabetical
<% end %>
<%= link_to params.permit(:sort).merge({sort: 'recent'}), class: 'btn btn-flat' do %>
<%= link_to params.permit(:sort).merge({sort: 'chronological'}), class: 'btn btn-flat tooltipped', data: { tooltip: "Show pages in this collection in the order they were added" } do %>
<i class="material-icons left">sort</i>
Chronological
<% end %>
<%= link_to params.permit(:sort).merge({sort: 'recent'}), class: 'btn btn-flat tooltipped', data: { tooltip: "Sort pages in this collection most-recently-added-first" } do %>
<i class="material-icons left">sort</i>
Recently added
<% end %>
<%= link_to params.permit(:sort).merge({sort: 'shuffle'}), class: 'btn btn-flat tooltipped', data: { tooltip: "Show pages in this collection in a random order" } do %>
<i class="material-icons left">sort</i>
Shuffle
<% end %>
</div>

View File

@ -0,0 +1,62 @@
<div class="row">
<% pages.each do |page| %>
<div class="col s12 m4 l3">
<% content = page.content %>
<% next unless (current_user || User.new).can_read?(content) %>
<div class="hoverable card" style="min-height: 330px;">
<div class="card-image waves-effect waves-block waves-light">
<%= image_tag content.random_public_image, class: 'activator', style: "height: 300px;" %>
</div>
<div class="card-content fixed-card-content" style="border-top: 6px solid <%= content.class.hex_color %>">
<span class="card-title activator grey-text text-darken-4">
<%= link_to content.name, content %>
<i class="material-icons right">more_vert</i>
</span>
<p>
Submitted by
<%= link_to content.user, class: "#{User.color}-text" do %>
<%= content.user.display_name %>
<% end %>
</p>
</div>
<div class="card-reveal">
<span class="card-title grey-text text-darken-4" style="border-bottom: 4px solid <%= content.class.hex_color %>">
<%= link_to content.name, content %>
<i class="material-icons right">close</i>
</span>
<% if page.explanation? %>
<blockquote>
<%= simple_format page.explanation %>
</blockquote>
<% end %>
<ul>
<li>
<%= link_to content, class: "#{content.class.color}-text" do %>
<i class="material-icons right">arrow_right</i>
View <%= content.name %>'s notebook page
<% end %>
</li>
<li class="clearfix">
<%= link_to page_collection_submissions_by_user_path(page_collection_id: @page_collection.id, user_id: page.user_id), class: "#{PageCollection.color}-text" do %>
<i class="material-icons right">arrow_right</i>
View more submissions from this user
<% end %>
</li>
<li class="clearfix">
<%= link_to page_collection_submissions_by_user_path(page_collection_id: @page_collection.id, user_id: page.user_id), class: "#{User.color}-text" do %>
<i class="material-icons right">arrow_right</i>
View <%= page.user.display_name %>'s profile
<% end %>
</li>
<% if user_signed_in? && current_user == @page_collection.user %>
<li>&nbsp;</li>
<li class="divider"></li>
<li>&nbsp;</li>
<li><%= link_to 'Remove from collection', page_collection_submission_path(page), method: :delete, class: 'red-text', data: { confirm: "Are you sure you want to remove this page from this collection?" } %></li>
<% end %>
</ul>
</div>
</div>
</div>
<% end %>
</div>

View File

@ -1,33 +1,20 @@
<%= content_for :full_width_page_header do %>
<%= render partial: 'content/components/parallax_header', locals: { content_type: 'PageCollection', content_class: PageCollection, image_only: true } %>
<% end %>
<%= render partial: 'notice_dismissal/messages/15' %>
<% if @my_collections.any? || current_user.on_premium_plan? %>
<% if @collections_with_pending.any? %>
<div class="row">
<h1 class="center" style="font-size: 2em">
<i class="material-icons <%= PageCollection.color %>-text"><%= PageCollection.icon %></i>
Your collections
</h1>
<% @my_collections.each do |collection| %>
<div class="col s12 m6 l4">
<%= link_to collection do %>
<div class="hoverable card <%= PageCollection.color %>" style="height: 250px">
<div class="card-image">
<%= image_tag collection.random_public_image, style: 'max-height: 250px;' %>
<span class="card-title bordered-text">
<%= collection.title %>
<br />
<small>
<% collection.page_types.each do |icon| %>
<% klass = icon.constantize %>
<i class="material-icons left tooltipped tiny <%= klass.color %>-text" data-tooltip="<%= icon.pluralize %>"><%= klass.icon %></i>
<% end %>
</small>
</span>
</div>
</div>
<% end %>
</div>
<% end %>
<% if current_user.on_premium_plan? %>
<%= render partial: 'page_collections/collection_grid', locals: { collection_list: @collections_with_pending, title: "Your collections with pending submissions" } %>
</div>
<% end %>
<% if @my_collections.any? || current_user.on_premium_plan? || Date.current < 'October 21, 2020'.to_date %>
<div class="row">
<%= render partial: 'page_collections/collection_grid', locals: { collection_list: @my_collections, title: "Your collections" } %>
<% if current_user.on_premium_plan? || Date.current < 'October 21, 2020'.to_date %>
<div class="col s12 m6 l4">
<%= link_to new_page_collection_path do %>
<div class="card-panel <%= PageCollection.color %> white-text hoverable center" style="height: 246px;">
@ -42,62 +29,20 @@
</div>
<% end %>
<% if @followed_collections.any? %>
<div class="row">
<%= render partial: 'page_collections/collection_grid', locals: { collection_list: @followed_collections, title: "Collections you follow" } %>
</div>
<% end %>
<% if @network_collections.any? %>
<div class="row">
<h1 class="center" style="font-size: 2em">
<i class="material-icons <%= PageCollection.color %>-text"><%= PageCollection.icon %></i>
Collections from your network
</h1>
<% @network_collections.each do |collection| %>
<div class="col s12 m6 l4">
<%= link_to collection do %>
<div class="hoverable card <%= PageCollection.color %>" style="height: 250px">
<div class="card-image">
<%= image_tag collection.random_public_image, style: 'max-height: 250px;' %>
<span class="card-title bordered-text">
<%= collection.title %>
<br />
<small>
<% collection.page_types.each do |icon| %>
<% klass = icon.constantize %>
<i class="material-icons left tooltipped tiny <%= klass.color %>-text" data-tooltip="<%= icon.pluralize %>"><%= klass.icon %></i>
<% end %>
</small>
</span>
</div>
</div>
<% end %>
</div>
<% end %>
<%= render partial: 'page_collections/collection_grid', locals: { collection_list: @network_collections, title: "Collections from your network" } %>
</div>
<% end %>
<% if @random_collections.any? %>
<div class="row">
<h1 class="center" style="font-size: 2em">
<i class="material-icons <%= PageCollection.color %>-text"><%= PageCollection.icon %></i>
Discover more collections
</h1>
<% @random_collections.each do |collection| %>
<div class="col s12 m6 l4">
<%= link_to collection do %>
<div class="hoverable card <%= PageCollection.color %>" style="height: 250px">
<div class="card-image">
<%= image_tag collection.random_public_image, style: 'max-height: 250px;' %>
<span class="card-title bordered-text">
<%= collection.title %>
<br />
<small>
<% collection.page_types.each do |icon| %>
<% klass = icon.constantize %>
<i class="material-icons left tooltipped tiny <%= klass.color %>-text" data-tooltip="<%= icon.pluralize %>"><%= klass.icon %></i>
<% end %>
</small>
</span>
</div>
</div>
<% end %>
</div>
<% end %>
<%= render partial: 'page_collections/collection_grid', locals: { collection_list: @random_collections, title: "Discover more collections" } %>
</div>
<% end %>

View File

@ -1,3 +1,3 @@
<h1 style="font-size: 2em">New Page Collection</h1>
<h1 style="font-size: 2em">Create a Collection</h1>
<%= render 'form', page_collection: @page_collection %>

View File

@ -1,25 +1,266 @@
<%= content_for :full_width_page_header do %>
<%= render partial: 'content/components/collection_header', locals: { collection: @page_collection } %>
<div class="row">
<div class="col s12 m12 l7">
<div class="card">
<div class="card-content">
<div class="card-title">
<% if user_signed_in? %>
<% if current_user != @page_collection.user %>
<% if @page_collection.followed_by?(current_user) %>
<%= link_to unfollow_page_collection_path(@page_collection), class: "btn #{PageCollection.color} lighten-2 right" do %>
<i class="material-icons left"><%= PageCollection.icon %></i>
Unfollow
<% end %>
<% else %>
<%= link_to follow_page_collection_path(@page_collection), class: "btn #{PageCollection.color} right" do %>
<i class="material-icons left"><%= PageCollection.icon %></i>
Follow for updates
<% end %>
<% end %>
<% else %>
<%= link_to 'Edit collection', edit_page_collection_path(@page_collection), class: 'btn btn-flat right' %>
<% end %>
<% else %>
<%= link_to '#', class: "btn #{PageCollection.color} lighten-2 right disabled" do %>
<i class="material-icons left"><%= PageCollection.icon %></i>
Follow
<% end %>
<% end %>
About this collection
</div>
<br />
<% if user_signed_in? && @page_collection.user == current_user %>
<%= form_for @page_collection do |f| %>
<div class="input-field">
<%= f.text_area :description, class: 'materialize-textarea' %>
<%= f.label :description, 'Collection Description' %>
<div class="help-text">You can add details for this collection to explain what kinds of pages you'd like it to contain.</div>
</div>
<%= f.submit 'Save changes', class: 'btn right blue white-text' %>
<div class="clearfix"></div>
<% end %>
<% else %>
<% if @page_collection.description? %>
<div class="spaced-paragraphs">
<%= simple_format @page_collection.description %>
</div>
<% end %>
<% end %>
</div>
</div>
</div>
<div class="col s12 m12 l5">
<% if user_signed_in? && @page_collection.user_id == current_user.id %>
<% if @page_collection.pending_submissions.count > 0 %>
<%=
link_to page_collection_pending_submissions_path(page_collection_id: @page_collection.id),
class: "#{PageCollection.color} white-text btn btn-large",
style: "width: 100%" do
%>
<i class="material-icons left">notifications_active</i>
<div class="left">
<%= pluralize(@page_collection.pending_submissions.count, 'pending submission') %>
</div>
<% end %>
<% end %>
<% end %>
<%# render partial: 'page_collections/quick_add' %>
<a class="waves-effect hoverable waves-light btn btn-large modal-trigger <%= 'disabled' unless user_signed_in? %> blue" href="#share-page-modal" style="width: 100%; margin-top: 0.5em;">
<i class="material-icons <%= PageCollection.color %>-text text-darken-2 left"><%= PageCollection.icon %></i>
<div class="left">
<%= @page_collection.user == current_user ? 'Add' : 'Submit' %> a page
<span class="hide-on-small-only">
to this Collection
</span>
</div>
</a>
<br /><br />
<div class="grey-text uppercase">In this collection</div>
<div class="collection">
<% @page_collection.page_types.each do |pt| %>
<% klass = pt.constantize %>
<%= link_to(send(pt.downcase.pluralize + '_page_collection_path', @page_collection), class: "collection-item #{klass.color} white-text") do %>
<i class="material-icons left"><%= klass.icon %></i>
<%= pt.pluralize %>
<span class="badge white-text"><%= @page_collection.accepted_submissions.where(content_type: pt).count %></span>
<% end %>
<% end %>
<%= link_to @page_collection, class: "collection-item #{PageCollection.color}-text" do %>
<i class="material-icons left"><%= PageCollection.icon %></i>
All Pages
<span class="badge brown-text"><%= @page_collection.accepted_submissions.count %></span>
<% end %>
</div>
<div class="grey-text uppercase">Curator</div>
<div>
<%= link_to @page_collection.user, class: "#{User.color}-text" do %>
<%= image_tag @page_collection.user.image_url(size=20), class: 'left circle', style: 'margin-right: 8px;' %>
<%= @page_collection.user.display_name %>
<% end %>
</div>
<% if @page_collection.contributors.any? %>
<br />
<div class="grey-text uppercase">Contributors</div>
<% @page_collection.contributors.each do |user| %>
<div class="col s12 m6 l3">
<%= link_to user, class: "#{User.color}-text" do %>
<%= image_tag user.image_url(size=20), class: 'left circle', style: 'margin-right: 8px;' %>
<%= user.display_name %>
<% end %>
</div>
<% end %>
<br />
<% end %>
<!--
<div class="col s12 m6 l6">
<br />
<div class="grey-text uppercase">
Share collection to...
</div>
<ul>
<li>
<%= link_to [
'http://twitter.com/share?',
'url=' + URI::escape(page_collection_url(@page_collection)),
'&text=' + URI::escape("I'm building a collection of fictional " + @page_collection.page_types.map(&:pluralize).map(&:downcase).to_sentence + " on Notebook.ai. Check it out!")
].join, class: 'blue-text', target: '_blank' do %>
<i class="material-icons tiny left" style="margin-top: 4px;">share</i>
Twitter
<% end %>
</li>
<li>
<%=
link_to "https://www.facebook.com/sharer/sharer.php?app_id=1523926344336934&u=#{URI::escape(page_collection_url(@page_collection))}&display=popup&ref=plugin&src=share_button",
class: 'blue-text',
onclick: "return !window.open(this.href, 'Facebook', 'width=640,height=580')" do
%>
<i class="material-icons tiny left" style="margin-top: 4px">share</i>
Facebook
<% end %>
</li>
</ul>
</div>
-->
</div>
</div>
<% if @pages.empty? %>
<div class="row">
<div class="col s12 m10 offset-m1 l8 offset-l2">
<div class="card-panel">
This collection doesn't have any approved public pages yet.
<% if user_signed_in? %>
<% if current_user == @page_collection.user %>
<a class="modal-trigger" href="#share-page-modal">
Add your first page.
</a>
<% else %>
<a class="modal-trigger" href="#share-page-modal">
Yours could be first!
</a>
<% end %>
<% else %>
Sign in to submit your pages!
<% end %>
</div>
</div>
</div>
<% else %>
<%= render partial: 'page_collections/sort_bar' %>
<% if !!@show_contributor_highlight %>
<%= render partial: 'page_collections/contributor_highlight_bar', locals: { contributor: @highlighted_contributor } %>
<% end %>
<% if !!@show_page_type_highlight %>
<%= render partial: 'page_collections/page_type_highlight_bar', locals: { page_type: @page_type } %>
<% end %>
<%= render partial: 'page_collections/tiles', locals: { pages: @pages } %>
<% end %>
<% end %>
<div class="row">
<div class="col s12 m9 l8">
<% if @pages.empty? %>
<div class="card-panel">
This collection doesn't have any approved public pages yet. Please check back later!
</div>
<% else %>
<%= render partial: 'page_collections/sort_bar' %>
<% if !!@show_contributor_highlight %>
<div class="card-panel <%= PageCollection.color %> darken-3 white-text">
Showing all submitted pages from <%= link_to @highlighted_contributor.display_name, @highlighted_contributor, class: "#{User.color}-text" %>.
Click <%= link_to 'here', @page_collection, class: 'blue-text text-lighten-3' %> to see all pages regardless of author.
</div>
<%= form_for PageCollectionSubmission.new do |f| %>
<div id="share-page-modal" class="modal modal-fixed-footer">
<div class="modal-content">
<h4 class="center">
<%= @page_collection.user == current_user ? 'Add' : 'Submit' %> a page
<span class="hide-on-small-only">
to this Collection
</span>
</h4>
<br />
<% if @submittable_content.values.flatten.any? %>
<div class="row">
<div class="col s12 m12 l12">
<%= f.hidden_field :page_collection_id, value: @page_collection.id %>
<div class="center">
<% @submittable_content.keys.each do |submittable_class_name| %>
<% submittable_class = submittable_class_name.constantize %>
<i class="material-icons bordered-text <%= submittable_class.color %>-text <%= @submittable_content.keys.length > 6 ? 'small' : 'medium' %> tooltipped"
data-tooltip="This Collection allows <%= submittable_class_name.downcase.pluralize %>."><%= submittable_class.icon %></i> &nbsp;
<% end %>
</div>
<br />
<div class="input-field clearfix">
<%= f.select :content do %>
<% @submittable_content.each do |content_type, content_list| %>
<optgroup label="<%= content_type.pluralize %>">
<% content_list.each do |content| %>
<option value="<%= content_type %>-<%= content.id %>"><%= content.name %></option>
<% end %>
</optgroup>
<% end %>
<% end %>
<label>Select a page to <%= @page_collection.user == current_user ? 'add' : 'submit' %></label>
<div class="helper-text">
Submitting a page will automatically change its privacy to "public" if this collection is public.
<% if @page_collection.privacy == 'public' %>
(It is!)
<% end %>
</div>
</div>
</div>
<div class="col s12 m12 l12">
<div class="input-field">
<%= f.text_area :explanation, class: 'materialize-textarea' %>
<%= f.label :explanation, 'Add a message' %>
<div class="helper-text">
<% if @page_collection.user == current_user %>
This message will be visible to everyone.
<% else %>
If this submission is accepted, this message will be visible to everyone.
<% end %>
It can be as long or as short as you'd like!
</div>
</div>
</div>
</div>
<% else %>
<p>
You don't have any pages to submit to this collection.
</p>
<% end %>
<%= render partial: 'page_collections/stream', locals: { pages: @pages } %>
<% end %>
</div>
<div class="modal-footer">
<%= f.submit (@page_collection.user == current_user ? 'Add' : 'Submit') + ' page', class: "btn #{PageCollection.color} white-text" %>
<a href="#!" class="modal-close waves-effect waves-green btn-flat left">Nevermind</a>
</div>
</div>
<div class="col s12 m3 l4">
<%= render partial: 'page_collections/sidebar' %>
</div>
</div>
<% end %>

View File

@ -6,7 +6,7 @@
<div class="blue lighten-3 comment black-text">
<% end %>
<%# Nesting from above %>
<%# Nested indents from above %>
<%= simple_format ContentFormatterService.show(
text: comment.message,
viewing_user: current_user

View File

@ -8,7 +8,7 @@
<% elsif share.content_page_type == PageCollection.name %>
<% if share.secondary_content_page.present? %>
<%= render partial: 'content_page_shares/stream_added_to_page_collection', locals: { share: share, content: share.content_page } %>
<%= render partial: 'content_page_shares/stream_added_to_page_collection', locals: { share: share, content: share.content_page, secondary_content: share.secondary_content_page } %>
<% else %>
<%= render partial: 'content_page_shares/stream_new_page_collection', locals: { share: share, content: share.content_page } %>
<% end %>

View File

@ -38,8 +38,8 @@
</div>
<div class="card-tabs">
<ul class="tabs tabs-fixed-width">
<li class="tab col s3"><a class="blue-text" href="#tab-about-me">About Me</a></li>
<li class="tab col s3"><a class="active blue-text" href="#tab-recent-activity">Recent Activity</a></li>
<li class="tab col s3"><a class="active blue-text" href="#tab-about-me">About Me</a></li>
<li class="tab col s3"><a class="blue-text" href="#tab-recent-activity">Recent Activity</a></li>
<li class="tab col s3"><a class="blue-text" href="#tab-universes">Universes</a></li>
<!--<li class="tab col s3"><a class="blue-text" href="#tab-documents">Documents</a></li>-->
<% if show_collections_tab %>

View File

@ -0,0 +1,5 @@
class AddReferenceCodeToNotifications < ActiveRecord::Migration[6.0]
def change
add_column :notifications, :reference_code, :string
end
end