Merge branch 'master' of github.com:indentlabs/notebook

This commit is contained in:
Andrew Brown 2017-10-28 22:45:48 +03:00
commit 4dc933023c
995 changed files with 2670 additions and 94 deletions

View File

@ -58,9 +58,13 @@ gem 'mixpanel-ruby'
gem 'social-share-button'
# Apps
gem 'easy_translate'
#gem 'easy_translate'
gem 'levenshtein-ffi'
# Forum
gem 'thredded', '~> 0.13.2'
gem 'rails-ujs'
# Tech debt & hacks
gem 'binding_of_caller' # see has_changelog.rb

View File

@ -26,6 +26,8 @@ GEM
erubis (~> 2.7.0)
rails-dom-testing (~> 1.0, >= 1.0.5)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
active_record_union (1.2.0)
activerecord (>= 4.0)
activejob (4.2.7.1)
activesupport (= 4.2.7.1)
globalid (>= 0.3.0)
@ -47,11 +49,17 @@ GEM
ast (2.3.0)
authority (3.2.2)
activesupport (>= 3.0.0)
autoprefixer-rails (7.1.2.3)
execjs
aws-sdk (1.66.0)
aws-sdk-v1 (= 1.66.0)
aws-sdk-v1 (1.66.0)
json (~> 1.4)
nokogiri (>= 1.4.4)
babel-source (5.8.35)
babel-transpiler (0.7.0)
babel-source (>= 4.0, < 6)
execjs (~> 2.0)
bcrypt (3.1.11)
better_errors (2.1.1)
coderay (>= 1.0.0)
@ -94,6 +102,7 @@ GEM
tins (>= 1.6.0, < 2)
crack (0.4.3)
safe_yaml (~> 1.0.0)
crass (1.0.2)
cucumber (2.4.0)
builder (>= 2.1.2)
cucumber-core (~> 1.5.0)
@ -114,6 +123,8 @@ GEM
database_cleaner (1.5.3)
dateslices (0.0.4)
rails (> 4)
db_text_search (0.2.2)
activerecord (>= 4.1.15, < 6.0)
debug_inspector (0.0.2)
devise (4.2.0)
bcrypt (~> 3.0)
@ -125,10 +136,6 @@ GEM
docile (1.1.5)
domain_name (0.5.20161021)
unf (>= 0.0.5, < 1.0.0)
easy_translate (0.5.0)
json
thread
thread_safe
erubis (2.7.0)
execjs (2.7.0)
factory_girl (4.7.0)
@ -136,9 +143,13 @@ GEM
factory_girl_rails (4.7.0)
factory_girl (~> 4.7.0)
railties (>= 3.0.0)
fast_blank (1.0.0)
ffi (1.9.14)
filesize (0.1.1)
formatador (0.2.5)
friendly_id (5.2.1)
activerecord (>= 4.0.0)
gemoji (2.1.0)
gherkin (4.0.0)
globalid (0.3.7)
activesupport (>= 4.1.0)
@ -159,13 +170,33 @@ GEM
guard (~> 2.0)
rubocop (~> 0.20)
hashdiff (0.3.2)
html-pipeline (2.6.0)
activesupport (>= 2)
nokogiri (>= 1.4)
htmlentities (4.3.4)
http-cookie (1.0.3)
domain_name (~> 0.5)
httparty (0.13.7)
json (~> 1.8)
multi_xml (>= 0.5.2)
i18n (0.8.0)
inline_svg (1.2.2)
activesupport (>= 3.0)
nokogiri (>= 1.6)
json (1.8.6)
kaminari (1.0.1)
activesupport (>= 4.1.0)
kaminari-actionview (= 1.0.1)
kaminari-activerecord (= 1.0.1)
kaminari-core (= 1.0.1)
kaminari-actionview (1.0.1)
actionview
kaminari-core (= 1.0.1)
kaminari-activerecord (1.0.1)
activerecord
kaminari-core (= 1.0.1)
kaminari-core (1.0.1)
kramdown (1.14.0)
levenshtein-ffi (1.1.0)
ffi (~> 1.9)
libv8 (3.16.14.15)
@ -191,17 +222,29 @@ GEM
mini_portile2 (2.1.0)
minitest (5.10.1)
mixpanel-ruby (2.2.0)
moneta (1.0.0)
multi_json (1.12.1)
multi_test (0.1.2)
multi_xml (0.6.0)
mustache (1.0.5)
nenv (0.3.0)
netrc (0.11.0)
newrelic_rpm (4.5.0.337)
nokogiri (1.7.0.1)
mini_portile2 (~> 2.1.0)
nokogumbo (1.4.13)
nokogiri
notiffany (0.1.1)
nenv (~> 0.1)
shellany (~> 0.0)
onebox (1.8.16)
fast_blank (>= 1.0.0)
htmlentities (~> 4.3)
moneta (~> 1.0)
multi_json (~> 1.11)
mustache
nokogiri (~> 1.7)
sanitize
orm_adapter (0.5.0)
paperclip (4.2.4)
activemodel (>= 3.2.0)
@ -219,6 +262,8 @@ GEM
puma (3.6.0)
puma-heroku (1.0.0)
puma (~> 3.0)
pundit (1.1.0)
activesupport (>= 3.0.0)
rack (1.6.5)
rack-test (0.6.3)
rack (>= 1.0)
@ -245,6 +290,8 @@ GEM
rails-jquery-autocomplete (1.0.3)
rails (>= 3.2)
rails-perftest (0.0.6)
rails-ujs (0.1.0)
railties (>= 3.1)
rails_12factor (0.0.3)
rails_serve_static_assets
rails_stdout_logging
@ -262,6 +309,7 @@ GEM
json
rack
rb-fsevent (0.9.7)
rb-gravatar (1.0.5)
rb-inotify (0.9.7)
ffi (>= 0.5.0)
redcarpet (3.3.4)
@ -272,6 +320,7 @@ GEM
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
rinku (2.0.2)
rmagick (2.13.4)
rspec (3.5.0)
rspec-core (~> 3.5.0)
@ -308,6 +357,10 @@ GEM
ruby_dep (1.4.0)
rubyzip (1.2.0)
safe_yaml (1.0.4)
sanitize (4.5.0)
crass (~> 1.0.2)
nokogiri (>= 1.4.4)
nokogumbo (~> 1.4.1)
sass (3.4.22)
sass-rails (5.0.6)
railties (>= 4.0.0, < 6)
@ -334,6 +387,10 @@ GEM
sprockets (3.7.1)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-es6 (0.9.2)
babel-source (>= 5.8.11)
babel-transpiler
sprockets (>= 3.0.0)
sprockets-rails (3.2.0)
actionpack (>= 4.0)
activesupport (>= 4.0)
@ -347,9 +404,30 @@ GEM
libv8 (~> 3.16.14.0)
ref
thor (0.19.4)
thread (0.2.2)
thread_safe (0.3.5)
thredded (0.13.2)
active_record_union (>= 1.2.0)
autoprefixer-rails
db_text_search (~> 0.2.0)
friendly_id
gemoji (~> 2.1.0)
html-pipeline
htmlentities
inline_svg
kaminari
kramdown
nokogiri
onebox (~> 1.8, >= 1.8.13)
pundit (>= 1.1.0)
rails (>= 4.2.0)
rb-gravatar
rinku
sanitize
sass (>= 3.4.21)
sprockets-es6
timeago_js
tilt (2.0.5)
timeago_js (3.0.2)
tins (1.12.0)
tzinfo (1.2.2)
thread_safe (~> 0.1)
@ -390,7 +468,6 @@ DEPENDENCIES
database_cleaner
dateslices
devise
easy_translate
factory_girl_rails
filesize
guard
@ -411,6 +488,7 @@ DEPENDENCIES
rails (= 4.2.7.1)
rails-jquery-autocomplete
rails-perftest
rails-ujs
rails_12factor
raygun4ruby
redcarpet
@ -429,6 +507,7 @@ DEPENDENCIES
sqlite3
stripe
therubyracer
thredded (~> 0.13.2)
tzinfo-data
uglifier (>= 1.3.0)
webmock

View File

@ -1,3 +0,0 @@
// Place all the styles related to the Documents controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@ -1,3 +0,0 @@
// Place all the styles related to the Emails controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@ -1,3 +0,0 @@
// Place all the styles related to the Lab controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@ -1,3 +0,0 @@
// Place all the styles related to the Navigator controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@ -1,3 +0,0 @@
// Place all the styles related to the Voting controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@ -15,7 +15,7 @@ class RegistrationsController < Devise::RegistrationsController
end
def account_update_params
params.require(:user).permit(:name, :email, :password, :password_confirmation, :current_password, :email_updates, :fluid_preference)
params.require(:user).permit(:name, :email, :username, :password, :password_confirmation, :current_password, :email_updates, :fluid_preference)
end
protected

View File

@ -11,6 +11,8 @@ class User < ActiveRecord::Base
include HasContent
include Authority::UserAbilities
validates_uniqueness_of :username, allow_nil: true, allow_blank: true
has_many :subscriptions
has_many :billing_plans, through: :subscriptions
def on_premium_plan?
@ -139,4 +141,12 @@ class User < ActiveRecord::Base
:email
]
end
def forum_username
username = self.username.present? ? self.username : nil
username ||= self.name.present? ? self.name : nil
username ||= 'Anonymous Author'
username
end
end

View File

@ -6,13 +6,18 @@
<div class="card-content">
<h4>Personal information</h4>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
<%= f.label 'Name (visible on your profile and forum posts)' %><br />
<%= f.text_field :name, autofocus: true %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
<%= f.label 'Email (always completely private)' %><br />
<%= f.email_field :email %>
</div>
<div class="field">
<%= f.label 'Username (users can @mention you with your username on the forums)' %><br />
<%= f.text_field :username %>
</div>
</div>
</div>
@ -54,7 +59,7 @@
<div class="field">
<%= f.check_box :email_updates %>
<%= f.label :email_updates do %>
If this box is checked, you will receive occasional updates by email about new Notebook.ai features.
I want to receive occasional updates by email about new Notebook.ai features.
<% end %>
</div>
</div>

View File

@ -19,7 +19,7 @@
</li>
<li class="divider"></li>
<li>
<%= link_to privacy_policy_path do %>
<%= link_to main_app.privacy_policy_path do %>
<i class="material-icons left">verified_user</i>
Privacy policy
<% end %>
@ -57,14 +57,14 @@
</li>
<li>
<%= link_to subscription_path do %>
<%= link_to main_app.subscription_path do %>
<i class="material-icons left">credit_card</i>
Account billing
<span class="badge right">&nbsp;</span>
<% end %>
</li>
<li>
<%= link_to edit_user_registration_path do %>
<%= link_to main_app.edit_user_registration_path do %>
<i class="material-icons left">settings</i>
Account settings
<span class="badge right">&nbsp;</span>
@ -75,13 +75,13 @@
<!--
<li>
<%= link_to friends_landing_path do %>
<%= link_to main_app.friends_landing_path do %>
<i class="material-icons left">people</i>
Community Drive
<% end %>
</li>
<li>
<%= link_to community_voting_path do %>
<%= link_to main_app.community_voting_path do %>
<i class="material-icons left">star_outline</i>
Vote on features
<% end %>
@ -90,20 +90,20 @@
<li class="divider"></li>
-->
<li>
<%= link_to prompts_path do %>
<%= link_to main_app.prompts_path do %>
<i class="material-icons left">lightbulb_outline</i>
Worldbuilding prompts
<% end %>
</li>
<li>
<%= link_to notebook_export_path do %>
<%= link_to main_app.notebook_export_path do %>
<i class="material-icons left">file_download</i>
Notebook downloads
<% end %>
</li>
<li class="divider"></li>
<li>
<%= link_to destroy_user_session_path do %>
<%= link_to main_app.destroy_user_session_path do %>
<i class="material-icons left">power_settings_new</i>
Sign out
<% end %>
@ -111,20 +111,20 @@
</ul>
<ul id="login-slide" class="side-nav">
<li><%= link_to 'Sign in', new_user_session_path %></li>
<li><%= link_to 'Sign up', new_user_registration_path %></li>
<li><%= link_to 'Sign in', main_app.new_user_session_path %></li>
<li><%= link_to 'Sign up', main_app.new_user_registration_path %></li>
<li class="divider"></li>
<li><%= link_to 'Report a problem', 'https://docs.google.com/forms/d/e/1FAIpQLSe0jnqJlcPJDqwogGere5j8-8F1nSGGYkzbsI-XkOeMnGwLrA/viewform', target: '_new' %></li>
<li><%= link_to 'Request a feature', 'https://docs.google.com/forms/d/e/1FAIpQLScOhSMdDqWqJu9HGPQdmd0R9s90_AcSo0g6_Nc1qNjQIbSaXA/viewform', target: '_new' %></li>
<li><%= link_to 'Leave feedback', 'https://docs.google.com/forms/d/e/1FAIpQLScZWEVMgm8hBWIIVj1LPzo0GqflmWUrLQlc4TAYqsaS087oAA/viewform', target: '_new' %></li>
<li class="divider"></li>
<li><%= link_to 'Privacy policy', privacy_policy_path %></li>
<li><%= link_to 'Privacy policy', main_app.privacy_policy_path %></li>
</ul>
<div class="navbar-fixed">
<nav class="light-blue">
<div class="nav-wrapper">
<%= link_to 'Notebook.ai', root_url, class: 'brand-logo center' %>
<%= link_to 'Notebook.ai', main_app.root_url, class: 'brand-logo center' %>
<ul class="right">
<% if user_signed_in? %>
@ -140,8 +140,8 @@
</a>
</li>
<% else %>
<li class="hide-on-med-and-down"><%= link_to 'Sign in', new_user_session_path %></li>
<li class="hide-on-med-and-down"><%= link_to 'Sign up', new_user_registration_path %></li>
<li class="hide-on-med-and-down"><%= link_to 'Sign in', main_app.new_user_session_path %></li>
<li class="hide-on-med-and-down"><%= link_to 'Sign up', main_app.new_user_registration_path %></li>
<% end %>
</ul>
<ul class="left">
@ -175,7 +175,7 @@
<div id="search">
<button type="button" class="close red">×</button>
<%= form_tag search_path, method: :get do %>
<%= form_tag main_app.search_path, method: :get do %>
<input type="search" name="q" value="" placeholder="search your notebook" />
<button type="submit" class="btn btn-primary blue">Search everything</button>
<% end %>

View File

@ -31,6 +31,34 @@
<% end %>
</li>
<!--
<li>
<%= link_to thredded_path do %>
<i class="material-icons grey-text">
forum
</i>
Discussions
<###
unread_threads = Thredded::Topic
.followed_by(current_user)
.unread(current_user)
.count
private_messages = Thredded::PrivateTopic
.for_user(current_user)
.unread(current_user)
.count
###>
<% unread_threads = 0; private_messages = 0 %>
<% if unread_threads > 0 || private_messages > 0 %>
<span class="badge <%= 'blue white-text' if private_messages > 0 %>">
<%= unread_threads %><%= "/#{private_messages}" if private_messages > 0 %>
</span>
<% end %>
<% end %>
</li>
-->
<li>
<%= link_to notes_path do %>
<i class="material-icons grey-text">
@ -147,4 +175,4 @@
$(document).ready(function () {
$(".button-collapse").sideNav();
})
</script>
</script>

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<title><%= yield :thredded_page_title %> | Notebook.ai</title>
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport' />
<%= stylesheet_link_tag 'thredded', 'data-turbolinks-track': 'reload' %>
<%= csrf_meta_tag %>
<%= javascript_include_tag 'thredded',
async: !Rails.application.config.assets.debug,
defer: true,
'data-turbolinks-track': 'reload'%>
<%== Gravatar.prefetch_dns %>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
</head>
<body>
<%= render 'thredded/shared/nav/bar' %>
<%= yield %>
</body>
</html>

View File

@ -0,0 +1 @@
<li class="<%= category.name.underscore %>"><%= category.name %></li>

View File

@ -0,0 +1,6 @@
<% content_for :thredded_page_title, @message %>
<% content_for :thredded_page_id, 'thredded--error-forbidden' %>
<% content_for :thredded_breadcrumbs, render('thredded/shared/breadcrumbs') %>
<%= thredded_page do %>
<p class="thredded--alert thredded--alert-warning"><%= @message %></p>
<% end %>

View File

@ -0,0 +1,6 @@
<% content_for :thredded_page_title, @message %>
<% content_for :thredded_page_id, 'thredded--error-not-found' %>
<% content_for :thredded_breadcrumbs, render('thredded/shared/breadcrumbs') %>
<%= thredded_page do %>
<p class="thredded--alert thredded--alert-danger"><%= @message %></p>
<% end %>

View File

@ -0,0 +1,11 @@
<%# Link to the "First" page
- available local variables
url: url to the first page
current_page: a page object for the currently displayed page
total_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<span class="first">
<%= link_to_unless current_page.first?, t('views.pagination.first').html_safe, url, :remote => remote %>
</span>

View File

@ -0,0 +1,8 @@
<%# Non-link tag that stands for skipped pages...
- available local variables
current_page: a page object for the currently displayed page
total_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<span class="page gap"><%= t('views.pagination.truncate').html_safe %></span>

View File

@ -0,0 +1,11 @@
<%# Link to the "Last" page
- available local variables
url: url to the last page
current_page: a page object for the currently displayed page
total_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<span class="last">
<%= link_to_unless current_page.last?, t('views.pagination.last').html_safe, url, :remote => remote %>
</span>

View File

@ -0,0 +1,11 @@
<%# Link to the "Next" page
- available local variables
url: url to the next page
current_page: a page object for the currently displayed page
total_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<span class="next">
<%= link_to_unless current_page.last?, t('views.pagination.next').html_safe, url, :rel => 'next', :remote => remote %>
</span>

View File

@ -0,0 +1,12 @@
<%# Link showing page number
- available local variables
page: a page object for "this" page
url: url to this page
current_page: a page object for the currently displayed page
total_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<span class="page<%= ' current' if page.current? %>">
<%= link_to_unless page.current?, page, url, {:remote => remote, :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil} %>
</span>

View File

@ -0,0 +1,23 @@
<%# The container tag
- available local variables
current_page: a page object for the currently displayed page
total_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
paginator: the paginator that renders the pagination tags inside
-%>
<%= paginator.render do -%>
<nav class="pagination thredded--pagination">
<%= first_page_tag unless current_page.first? %>
<%= prev_page_tag unless current_page.first? %>
<% each_page do |page| -%>
<% if page.left_outer? || page.right_outer? || page.inside_window? -%>
<%= page_tag page %>
<% elsif !page.was_truncated? -%>
<%= gap_tag %>
<% end -%>
<% end -%>
<%= next_page_tag unless current_page.last? %>
<%= last_page_tag unless current_page.last? %>
</nav>
<% end -%>

View File

@ -0,0 +1,11 @@
<%# Link to the "Previous" page
- available local variables
url: url to the previous page
current_page: a page object for the currently displayed page
total_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<span class="prev">
<%= link_to_unless current_page.first?, t('views.pagination.previous').html_safe, url, :rel => 'prev', :remote => remote %>
</span>

View File

@ -0,0 +1,28 @@
<% content_for :thredded_page_title, t('thredded.messageboard_group.create') %>
<% content_for :thredded_page_id, 'thredded--messageboard-groups-new' %>
<% content_for :thredded_breadcrumbs do %>
<ul class="thredded--navigation-breadcrumbs">
<li class="thredded--navigation-breadcrumbs--item-no-link">
<%= t('thredded.messageboard_group.create') %>
</li>
</ul>
<% end %>
<%= thredded_page do %>
<section class="thredded--main-section">
<%= form_for @messageboard_group, html: { class: 'thredded--form' } do |f| %>
<ul class="thredded--form-list">
<li>
<%= f.label :name %>
<%= f.text_field :name, required: true %>
</li>
<li>
<%= f.submit t('thredded.messageboard_group.create'),
class: 'thredded--form--submit',
'data-disable-with' => t('thredded.messageboard_group.form.create_btn_submitting') %>
</li>
</ul>
<% end %>
</section>
<% end %>

View File

@ -0,0 +1,24 @@
<%= form_for messageboard, html: { class: 'thredded--form' } do |f| %>
<ul class="thredded--form-list">
<li>
<%= f.label t('thredded.messageboard.form.title_label') %>
<%= f.text_field :name, required: true %>
</li>
<li>
<%= f.label t('thredded.messageboard.form.description_label') %>
<%= f.text_field :description %>
</li>
<li>
<%= f.label t('thredded.messageboard.form.messageboard_group_id_label') %>
<%= f.collection_select :messageboard_group_id, Thredded::MessageboardGroup.all, :id, :name,
include_blank: t('thredded.messageboard.form.no_group') %>
</li>
<li>
<%= f.submit @messageboard.persisted? ? t('thredded.messageboard.update') : t('thredded.messageboard.create'),
class: 'thredded--form--submit',
'data-disable-with' => @messageboard.persisted? ?
t('thredded.messageboard.form.update_btn_submitting') :
t('thredded.messageboard.form.create_btn_submitting') %>
</li>
</ul>
<% end %>

View File

@ -0,0 +1,24 @@
<% if policy(messageboard).read? %>
<%= view_hooks.messageboards_index.messageboard.render self, messageboard: messageboard do %>
<%= link_to messageboard_topics_path(messageboard), class: 'thredded--messageboard' do %>
<header class="thredded--messageboard--header">
<h2 class="thredded--messageboard--title"><%= messageboard.name %></h2>
<h3 class="thredded--messageboard--meta">
<%= t 'thredded.messageboard.topics_and_posts_counts',
topics_count: number_with_delimiter(messageboard.topics_count),
posts_count: number_with_delimiter(messageboard.posts_count) %>
</h3>
</header>
<p class="thredded--messageboard--description"><%= messageboard.description %></p>
<% if messageboard.last_topic %>
<p class="thredded--messageboard--byline">
<%= t 'thredded.messageboard.last_updated_by_html',
time_ago: time_ago(messageboard.last_topic.last_post_at),
user: messageboard.last_user.thredded_display_name %>
</p>
<% end %>
<% end %>
<% end %>
<% end %>

View File

@ -0,0 +1,15 @@
<% content_for :thredded_page_title, t('thredded.nav.edit_messageboard') %>
<% content_for :thredded_page_id, 'thredded--messageboard-edit' %>
<% content_for :thredded_breadcrumbs do %>
<ul class="thredded--navigation-breadcrumbs">
<li class="thredded--navigation-breadcrumbs--item-no-link">
<%= t('thredded.nav.edit_messageboard') %>
</li>
</ul>
<% end %>
<%= thredded_page do %>
<section class="thredded--main-section">
<%= render 'form', messageboard: @messageboard %>
</section>
<% end %>

View File

@ -0,0 +1,34 @@
<% content_for :thredded_page_title, t('thredded.messageboard.index.page_title') %>
<% content_for :thredded_page_id, 'thredded--messageboards-index' %>
<% content_for :thredded_breadcrumbs, render('thredded/shared/breadcrumbs') %>
<%= thredded_page do %>
<%= view_hooks.messageboards_index.container.render self, groups: @groups do %>
<section class="thredded--main-section thredded--messageboards">
<%= view_hooks.messageboards_index.list.render self, groups: @groups do %>
<% @groups.each do |group| %>
<% if group.name.present? %>
<h3 class="thredded--messageboards-group--title"><%= group.name %></h3>
<% end %>
<div class="thredded--messageboards-group">
<%= view_hooks.messageboards_index.group.render self, group: group do %>
<%= render group.messageboards %>
<% end %>
</div>
<% end %>
<% end %>
<div class="thredded--messageboards--actions">
<% if policy(Thredded::Messageboard.new).create? %>
<a class="thredded--button" href="<%= new_messageboard_path %>" rel="nofollow">
<%= t('thredded.messageboard.create') %>
</a>
<% end %>
<% if policy(Thredded::MessageboardGroup.new).create? %>
<a class="thredded--button" href="<%= new_messageboard_group_path %>" rel="nofollow">
<%= t('thredded.messageboard_group.create') %>
</a>
<% end %>
</div>
</section>
<% end %>
<% end %>

View File

@ -0,0 +1,15 @@
<% content_for :thredded_page_title, t('thredded.messageboard.create') %>
<% content_for :thredded_page_id, 'thredded--messageboards-new' %>
<% content_for :thredded_breadcrumbs do %>
<ul class="thredded--navigation-breadcrumbs">
<li class="thredded--navigation-breadcrumbs--item-no-link">
<%= t('thredded.messageboard.create') %>
</li>
</ul>
<% end %>
<%= thredded_page do %>
<section class="thredded--main-section">
<%= render 'form', messageboard: @messageboard %>
</section>
<% end %>

View File

@ -0,0 +1,19 @@
<% content_for :thredded_main_navigation do %>
<nav class="thredded--moderation-navigation">
<ul class="thredded--moderation-navigation--items">
<li class="thredded--moderation-navigation--item thredded--moderation-navigation--pending">
<%= link_to t('thredded.nav.moderation_pending'), pending_moderation_path %>
</li>
<li class="thredded--moderation-navigation--item thredded--moderation-navigation--history">
<%= link_to t('thredded.nav.moderation_history'), moderation_history_path %>
</li>
<li class="thredded--moderation-navigation--item thredded--moderation-navigation--activity">
<%= link_to t('thredded.nav.moderation_activity'), moderation_activity_path %>
</li>
<li class="thredded--moderation-navigation--item thredded--moderation-navigation--users">
<%= link_to t('thredded.nav.moderation_users'), users_moderation_path %>
</li>
</ul>
<%= render 'users_search_form' %>
</nav>
<% end %>

View File

@ -0,0 +1,19 @@
<% post, content = post_and_content if local_assigns.key?(:post_and_content) %>
<%= content_tag :article, id: dom_id(post), class: 'thredded--post thredded--post-moderation' do %>
<%= render 'thredded/posts_common/actions', post: post %>
<%= render 'thredded/posts_common/header_with_user_and_topic',
post: post,
post_user_link: if post.user
link_to(post.user.thredded_display_name, user_moderation_path(post.user.id))
else
content_tag :em, t('thredded.null_user_name')
end
%>
<%= content || render('thredded/posts/content', post: post) %>
<% if post.blocked? %>
<p class="thredded--alert thredded--alert-danger">
<%= render 'thredded/shared/content_moderation_blocked_state', moderation_record: post.last_moderation_record %>
</p>
<% end %>
<%= render 'post_moderation_actions', post: post %>
<% end %>

View File

@ -0,0 +1,12 @@
<div class="thredded--post-moderation-actions">
<% unless post.approved? %>
<%= button_to t('thredded.moderation.approve_btn'), moderate_post_path,
class: 'thredded--button',
params: { id: post.to_model.id, moderation_state: 'approved' } %>
<% end %>
<% unless post.blocked? %>
<%= button_to t('thredded.moderation.block_btn'), moderate_post_path,
class: 'thredded--button',
params: { id: post.to_model.id, moderation_state: 'blocked' } %>
<% end %>
</div>

View File

@ -0,0 +1,46 @@
<%
record = post_moderation_record
post = record.post
if post
post_view = Thredded::PostView.new(post, policy(post))
end
moderation_state_notice_args = {
moderator: user_link(record.moderator),
time_ago: time_ago(record.created_at)
}
%>
<article class="thredded--post-moderation-record thredded--post-moderation-record-<%= record.moderation_state %>">
<header class="thredded--post-moderation-record--header">
<p class="thredded--post-moderation-record--moderation-state-notice">
<% if record.approved? %>
<%= t('thredded.moderation.post_approved_html', moderation_state_notice_args) %>
<% elsif record.blocked? %>
<%= t('thredded.moderation.post_blocked_html', moderation_state_notice_args) %>
<% end %>
</p>
<% if post && post.content != record.post_content %>
<p class="thredded--post-moderation-record--content-changed-notice">
<%= t('thredded.moderation.posts_content_changed_since_moderation_html', post_url: post_permalink_path(post)) %>
</p>
<% end %>
<%= content_tag :em, t('thredded.moderation.post_deleted_notice') unless post %>
</header>
<article class="thredded--post">
<% post_user_link = capture do %>
<% if record.post_user %>
<%= link_to record.post_user.thredded_display_name, user_moderation_path(record.post_user.id) %>
<% else %>
<%= safe_join [record.post_user_name, content_tag(:em, t('thredded.null_user_name'))].compact, ', ' %>
<% end %>
<% end %>
<% if post %>
<%= render 'thredded/posts_common/header_with_user_and_topic', post: post_view, post_user_link: post_user_link %>
<% else %>
<header><h2 class="thredded--post--user"><%= post_user_link %></h2></header>
<% end %>
<div class="thredded--post--content">
<%= Thredded::ContentFormatter.new(self).format_content(record.post_content) %>
</div>
</article>
<%= render 'post_moderation_actions', post: post if post %>
</article>

View File

@ -0,0 +1,3 @@
<% user_detail = user.thredded_user_detail %>
<%= user_detail.moderation_state.to_s.humanize %>
<%= time_ago user_detail.moderation_state_changed_at, default: '' %>

View File

@ -0,0 +1,12 @@
<% post, content = post_and_content if local_assigns.key?(:post_and_content) %>
<%= content_tag :article, id: dom_id(post), class: 'thredded--post thredded--post-moderation' do %>
<%= render 'thredded/posts_common/actions', post: post %>
<%= render 'thredded/posts_common/header_with_topic', post: post %>
<%= content || render('thredded/posts/content', post: post) %>
<% if post.blocked? %>
<p class="thredded--alert thredded--alert-danger">
<%= render 'thredded/shared/content_moderation_blocked_state', moderation_record: post.last_moderation_record %>
</p>
<% end %>
<%= render 'post_moderation_actions', post: post %>
<% end %>

View File

@ -0,0 +1,13 @@
<%= form_tag users_moderation_path,
method: 'get',
class: 'thredded--form thredded--navigation--search thredded--navigation--search--right',
'data-thredded-turboform' => true do %>
<%= label_tag :q, t('thredded.moderation.search_users.form_label') %>
<%= text_field_tag :q, @query,
type: 'search',
required: true,
# If there are no results the user will likely want to change the query, so auto-focus.
autofocus: @query.presence && !@users.presence,
placeholder: t('thredded.moderation.search_users.form_placeholder') %>
<button type="submit"><%= t 'thredded.search.form.btn_submit' %></button>
<% end %>

View File

@ -0,0 +1,20 @@
<% content_for :thredded_page_title, t('thredded.nav.moderation') %>
<% content_for :thredded_page_id, 'thredded--moderation-activity' %>
<%= render 'nav' %>
<%= thredded_page do %>
<section class="thredded--main-section">
<h1><%= t 'thredded.recent_activity' %></h1>
<% if @last_moderated_record %>
<div class="thredded--moderated-notice">
<%= render 'post_moderation_record', post_moderation_record: @last_moderated_record %>
</div>
<% end %>
<% if @posts.present? %>
<%= render_posts @posts,
partial: 'thredded/moderation/post',
content_partial: 'thredded/posts/content' %>
<%= paginate @posts %>
<% end %>
</section>
<% end %>

View File

@ -0,0 +1,13 @@
<% content_for :thredded_page_title,
safe_join([t('thredded.nav.moderation'), t('thredded.nav.moderation_history')], ': ') %>
<% content_for :thredded_page_id, 'thredded--moderation-history' %>
<%= render 'nav' %>
<%= thredded_page do %>
<section class="thredded--main-section">
<% if @post_moderation_records.present? %>
<%= render partial: 'post_moderation_record', collection: @post_moderation_records %>
<%= paginate @post_moderation_records %>
<% end %>
</section>
<% end %>

View File

@ -0,0 +1,24 @@
<% content_for :thredded_page_title, t('thredded.nav.moderation') %>
<% content_for :thredded_page_id, 'thredded--pending-moderation' %>
<%= render 'nav' %>
<%= thredded_page do %>
<section class="thredded--main-section">
<% if @last_moderated_record %>
<div class="thredded--moderated-notice">
<%= render 'post_moderation_record', post_moderation_record: @last_moderated_record %>
</div>
<% end %>
<% if @posts.present? %>
<%= render_posts @posts,
partial: 'thredded/moderation/post',
content_partial: 'thredded/posts/content' %>
<%= paginate @posts %>
<% else %>
<div class="thredded--empty">
<h3 class="thredded--empty--title"><%= t 'thredded.moderation.pending.empty.title' %></h3>
<p><%= t 'thredded.moderation.pending.empty.content' %></p>
</div>
<% end %>
</section>
<% end %>

View File

@ -0,0 +1,54 @@
<%
user = @user
user_detail = user.thredded_user_detail
%>
<% content_for :thredded_page_title, t('thredded.nav.moderation') %>
<% content_for :thredded_page_id, 'thredded--moderation-user' %>
<%= render 'nav' %>
<%= thredded_page do %>
<section class="thredded--main-section">
<%= view_hooks.moderation_user_page.user_title.render self, user: user do %>
<h1 class="thredded--moderation--user--title">
<%= image_tag Thredded.avatar_url.call(user), class: 'thredded--user--avatar' %><%= user.thredded_display_name %>
</h1>
<% end %>
<%= view_hooks.moderation_user_page.user_info.render self, user: user do %>
<ul class="thredded--moderation--user--info">
<%= view_hooks.moderation_user_page.user_info_list_items.render self, user: user do %>
<li><%= t 'thredded.users.user_since_html', time_ago: time_ago(user.created_at) %></li>
<% if user_detail.last_seen_at %>
<li><%= t 'thredded.users.last_active_html', time_ago: time_ago(user_detail.last_seen_at) %></li>
<% end %>
<% if user_detail.topics_count > 0 %>
<li><%= t 'thredded.users.started_topics_count', count: user_detail.topics_count %></li>
<% end %>
<% if user_detail.posts_count > 0 %>
<li><%= t 'thredded.users.posts_count', count: user_detail.posts_count %></li>
<% end %>
<li><%= render 'user_moderation_state', user: @user %></li>
<% end %>
</ul>
<% end %>
<%= view_hooks.moderation_user_page.user_moderation_actions.render self, user: user do %>
<div class="thredded--user--moderation-actions">
<% unless user_detail.approved? %>
<%= button_to t('thredded.moderation.approve_btn'), moderate_user_path,
class: 'thredded--button',
params: { id: user.to_model.id, moderation_state: 'approved' } %>
<% end %>
<% unless user_detail.blocked? %>
<%= button_to t('thredded.moderation.block_btn'), moderate_user_path,
class: 'thredded--button',
params: { id: user.to_model.id, moderation_state: 'blocked' } %>
<% end %>
</div>
<% end %>
<% if @posts.present? %>
<h2><%= t 'thredded.users.recent_activity' %></h2>
<%= render_posts @posts,
partial: 'thredded/moderation/user_post',
content_partial: 'thredded/posts/content' %>
<%= paginate @posts %>
<% end %>
</section>
<% end %>

View File

@ -0,0 +1,41 @@
<% content_for :thredded_page_title, t('thredded.nav.moderation') %>
<% content_for :thredded_page_id, 'thredded--moderation-users' %>
<%= render 'nav' %>
<%= thredded_page do %>
<section class="thredded--main-section">
<% if @users.present? %>
<% if @query.present? %>
<p class="thredded--alert thredded--alert-success">
<%= t 'thredded.moderation.search_users.results_message', query: "'#{@query}'" %>
</p>
<% end %>
<table class="thredded--moderation--users-table thredded--table">
<caption><%= page_entries_info @users %></caption>
<thead>
<tr>
<th>User</th>
<th>Moderation state</th>
</tr>
</thead>
<tbody>
<% @users.each do |user| %>
<tr>
<td>
<%= link_to user.thredded_display_name, user_moderation_path(user.id), class: 'thredded--link' %>
</td>
<td>
<%= render 'user_moderation_state', user: user %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= paginate @users %>
<% else %>
<p class="thredded--alert thredded--alert-danger">
<%= t 'thredded.moderation.search_users.no_results_message', query: "'#{@query}'" %>
</p>
<% end %>
</section>
<% end %>

View File

@ -0,0 +1,23 @@
<div class="thredded--email">
<figure class="thredded--email-post">
<figcaption class="thredded--email-post--author">
<%= @post.user.thredded_display_name %> <%= link_to 'said', post_permalink_url(@post) %>:
</figcaption>
<% cache [@post, 'content-onebox-placeholders'] do %>
<%= render partial: 'thredded/posts/content',
locals: { post: @post, options: {onebox_placeholders: true} } %>
<% end %>
</figure>
<hr/>
<p>
This email was sent to you because you are following this topic
"<%= link_to @post.postable.title, post_permalink_url(@post.id) %>".
<%= link_to 'View the conversation here', topic_url(@post.postable) %>.
</p>
<p>
To unsubscribe from these emails, update your
<%= link_to 'preferences', edit_messageboard_preferences_url(@post.messageboard) %>.
</p>
</div>

View File

@ -0,0 +1,10 @@
<%= @post.content %>
---
This email was sent to you because you are following this topic
"<%= @post.postable.title %>". Go here to view the conversation:
<%= post_permalink_url @post %>
To unsubscribe from these emails, update your preferences here:
<%= edit_messageboard_preferences_url @post.messageboard %>

View File

@ -0,0 +1 @@
<%= @post.filtered_content(self) %>

View File

@ -0,0 +1 @@
<%= @post.filtered_content(self) %>

View File

@ -0,0 +1 @@
<%= render 'thredded/posts_common/content', post: post, options: local_assigns[:options] || {} %>

View File

@ -0,0 +1,5 @@
<%= render 'thredded/posts_common/form',
post: post,
content_label: t('thredded.posts.form.content_label'),
button_text: button_text,
button_submitting_text: local_assigns.key?(:button_submitting_text) ? button_submitting_text : nil %>

View File

@ -0,0 +1,13 @@
<% post, content = post_and_content if local_assigns.key?(:post_and_content) %>
<%= content_tag :article, id: dom_id(post), class: "thredded--post thredded--#{post.read_state}--post" do %>
<%= render 'thredded/posts_common/actions', post: post, actions: local_assigns[:actions] %>
<%= render 'thredded/posts_common/header', post: post %>
<%= content || render('thredded/posts/content', post: post) %>
<% if post.pending_moderation? && !Thredded.content_visible_while_pending_moderation %>
<p class="thredded--alert thredded--alert-warning"><%= t 'thredded.posts.pending_moderation_notice' %></p>
<% elsif post.blocked? && post.can_moderate? %>
<p class="thredded--alert thredded--alert-danger">
<%= render 'thredded/shared/content_moderation_blocked_state', moderation_record: post.last_moderation_record %>
</p>
<% end %>
<% end %>

View File

@ -0,0 +1,3 @@
<span class="posts_count">
<%= post.user_posts_count %> posts
</span>

View File

@ -0,0 +1,16 @@
<% content_for :thredded_page_title, t('thredded.nav.edit_post') %>
<% content_for :thredded_page_id, 'thredded--edit-post' %>
<% content_for :thredded_breadcrumbs do %>
<ul class="thredded--navigation-breadcrumbs">
<li><%= link_to t('thredded.nav.edit_post'), edit_post_path(@post_form.post) %></li>
</ul>
<% end %>
<%= thredded_page do %>
<section class="thredded--main-section">
<%= render 'thredded/posts/form',
post: @post_form,
button_text: t('thredded.posts.form.update_btn'),
button_submitting_text: t('thredded.posts.form.update_btn_submitting')%>
</section>
<% end %>

View File

@ -0,0 +1,15 @@
<% content_for :thredded_page_title, @post_form.topic.title %>
<% content_for :thredded_page_id, 'thredded--topic--new-post' %>
<% content_for :thredded_breadcrumbs, render('thredded/shared/breadcrumbs') %>
<%= thredded_page do %>
<section class="thredded--main-section">
<div class="thredded--post-form--wrapper">
<h3 class="thredded--post-form--title"><%= t('thredded.posts.form.title_label') %></h3>
<%= render 'thredded/posts/form',
post: @post_form,
button_text: t('thredded.posts.form.create_btn'),
button_submitting_text: t('thredded.posts.form.create_btn_submitting') %>
</div>
</section>
<% end %>

View File

@ -0,0 +1,28 @@
<% actions ||= {} %>
<% actions_html = capture do %>
<%= view_hooks.post_common.actions.render self, post: post do %>
<% if actions[:quote] && post.can_reply? %>
<%= render 'thredded/posts_common/actions/quote', post: post %>
<% end %>
<% if post.can_update? %>
<%= render 'thredded/posts_common/actions/edit', post: post %>
<% end %>
<% if post.can_destroy? %>
<%= render 'thredded/posts_common/actions/delete', post: post %>
<% end %>
<% if post.read_state %>
<%= view_hooks.post_common.mark_as_unread.render self, post: post do %>
<%= render 'thredded/posts_common/actions/mark_as_unread', post: post %>
<% end %>
<% end %>
<% end %>
<% end %>
<%- if actions_html.present? %>
<div class='thredded--post--dropdown'>
<%= inline_svg 'thredded/three-dot-menu.svg', class: 'thredded--post--dropdown--toggle' %>
<div class='thredded--post--dropdown--actions'>
<%= actions_html %>
</div>
</div>
<% end %>

View File

@ -0,0 +1,3 @@
<div class="thredded--post--content">
<%= post.filtered_content(self, local_assigns[:options] || {}) %>
</div>

View File

@ -0,0 +1,22 @@
<%# locals: post, content_label, button_text, button_submitting_text. %>
<%= form_for post,
url: post.submit_path,
as: :post,
html: {
class: 'thredded--form thredded--post-form',
'data-thredded-post-form' => true,
'data-autocomplete-url' => autocomplete_users_path,
'data-autocomplete-min-length' => Thredded.autocomplete_min_length,
} do |form| %>
<ul class="thredded--form-list">
<%= render 'thredded/posts_common/form/content',
form: form, content_label: content_label, preview_url: post.preview_path %>
<li>
<% button_submitting_text ||=
post.persisted? ? t('thredded.form.update_btn_submitting') : t('thredded.form.create_btn_submitting') %>
<button type="submit" class="thredded--form--submit" data-disable-with="<%= button_submitting_text %>">
<%= button_text %>
</button>
</li>
</ul>
<% end %>

View File

@ -0,0 +1,8 @@
<%# @param post [Thredded::PostView] %>
<header>
<%= image_tag post.avatar_url, class: 'thredded--post--avatar' if post.user %>
<h2 class="thredded--post--user"><%= user_link post.user %></h2>
<a href="<%= post.permalink_path %>" rel="nofollow" class="thredded--link thredded--post--created-at">
<%= time_ago post.created_at %>
</a>
</header>

View File

@ -0,0 +1,15 @@
<%# @param post [Thredded::PostView] %>
<% topic = post.to_model.postable %>
<header>
<h2 class="thredded--post--topic">
<%=
topic_link = link_to(topic.title, post.permalink_path)
if topic.first_post == post.to_model
t 'thredded.users.started_topic_html', topic_link: topic_link
else
t 'thredded.users.posted_in_topic_html', topic_link: topic_link
end
%>
</h2>
<p class="thredded--post--created-at"><%= time_ago post.created_at %></p>
</header>

View File

@ -0,0 +1,18 @@
<%# @param post [Thredded::PostView] %>
<%# @param post_user_link [String] optional %>
<% topic = post.to_model.postable %>
<% post_user_link ||= user_link(post.user) %>
<header>
<%= image_tag post.avatar_url, class: 'thredded--post--avatar' if post.user %>
<h2 class="thredded--post--user-and-topic">
<%=
topic_link = link_to(topic.title, post.permalink_path)
if topic.first_post == post.to_model
t 'thredded.users.user_started_topic_html', user_link: post_user_link, topic_link: topic_link
else
t 'thredded.users.user_posted_in_topic_html', user_link: post_user_link, topic_link: topic_link
end
%>
</h2>
<p class="thredded--post--created-at"><%= time_ago post.created_at %></p>
</header>

View File

@ -0,0 +1,4 @@
<%= button_to t('thredded.posts.delete'), post.destroy_path,
method: :delete,
class: 'thredded--post--delete thredded--post--dropdown--actions--item',
data: {confirm: I18n.t('thredded.posts.delete_confirm')} %>

View File

@ -0,0 +1,3 @@
<%= link_to t('thredded.posts.edit'), post.edit_path,
class: 'thredded--post--edit thredded--post--dropdown--actions--item',
rel: 'nofollow' %>

View File

@ -0,0 +1,2 @@
<%= button_to(t('thredded.topics.mark_as_unread'), post.mark_unread_path, method: :post, class:
'thredded--post--mark-as-unread thredded--post--dropdown--actions--item') %>

View File

@ -0,0 +1,4 @@
<%= link_to t('thredded.posts.quote_btn'), url_for(post.quote_url_params),
'data-thredded-quote-post' => post.quote_path,
class: 'thredded--post--quote thredded--post--dropdown--actions--item',
rel: 'nofollow' %>

View File

@ -0,0 +1,7 @@
<%= render 'thredded/posts_common/form/content_field',
form: form,
content_label: content_label %>
<%= render 'thredded/posts_common/form/preview_area',
form: form,
preview_url: preview_url %>

View File

@ -0,0 +1,8 @@
<li>
<%= form.label :content, content_label %>
<%= view_hooks.post_form.content_text_area.render self, form: form, content_label: content_label do %>
<%= render 'thredded/posts_common/form/before_content', form: form %>
<%= form.text_area :content, {rows: 5, required: true} %>
<%= render 'thredded/posts_common/form/after_content', form: form %>
<% end %>
</li>

View File

@ -0,0 +1,16 @@
<%= view_hooks.post_form.preview_area.render self, form: form, preview_url: preview_url do %>
<li>
<noscript>
<button type="submit" class="thredded--button thredded--post--preview-btn"
formtarget="_blank" formaction="<%= preview_url %>">
<%= t 'thredded.form.preview' %>
</button>
</noscript>
<div class="thredded--preview-area"
data-thredded-preview-area data-thredded-preview-url="<%= preview_url %>">
<h4 class="thredded--preview-area--title"><%= t 'thredded.form.preview' %></h4>
<div class="thredded--preview-area--post thredded--post--content" data-thredded-preview-area-post></div>
</div>
</li>
<% end %>

View File

@ -0,0 +1,95 @@
<%# @type preferences [Thredded::UserPreferencesForm] %>
<%= form_for(preferences, method: :patch, url: preferences.update_path, html: {
class: 'thredded--form thredded--notification-preferences-form',
'data-thredded-user-preferences-form' => true
}) do |f| %>
<ul class="thredded--form-list">
<li>
<%= f.label :auto_follow_topics do %>
<%= f.check_box :auto_follow_topics,
'data-thredded-update-checkbox-on-change' =>
'user_preferences_form[messageboard_auto_follow_topics]' %>
<%= t 'thredded.preferences.form.auto_follow_topics.label' %>
<p class="thredded--form-list--hint">
<%= t 'thredded.preferences.form.auto_follow_topics.hint' %>
</p>
<% end %>
</li>
<li>
<%= f.label :follow_topics_on_mention do %>
<%= f.check_box :follow_topics_on_mention, 'data-thredded-bound-messageboard-pref' => 'user_preferences_form[messageboard_follow_topics_on_mention]' %>
<%= t 'thredded.preferences.form.follow_topics_on_mention.label' %>
<p class="thredded--form-list--hint">
<%= t 'thredded.preferences.form.follow_topics_on_mention.hint' %>
</p>
<% end %>
</li>
<% if Thredded.notifiers.present? %>
<li>
<label><%= t 'thredded.preferences.form.notifications_for_followed_topics.label' %></label>
<%= f.fields_for :notifications_for_followed_topics, preferences.notifications_for_followed_topics do |fn| %>
<%= fn.label :enabled do %>
<%= fn.hidden_field :notifier_key %>
<%= fn.check_box :enabled,
'data-thredded-bound-messageboard-pref' =>
"user_preferences_form[messageboard_notifications_for_followed_topics_attributes][#{fn.index}][enabled]" %>
<%= fn.object.notifier_human_name %>
<%- end %>
<%- end %>
</li>
<li>
<label><%= t 'thredded.preferences.form.notifications_for_private_topics.label' %></label>
<%= f.fields_for :notifications_for_private_topics, preferences.notifications_for_private_topics do |fn| %>
<%= fn.label :enabled do %>
<%= fn.hidden_field :notifier_key %>
<%= fn.check_box :enabled %>
<%= fn.object.notifier_human_name %>
<% end %>
<% end %>
</li>
<% end %>
</ul>
<% if preferences.messageboard %>
<h2 class="thredded--preferences--title">
<%= t 'thredded.preferences.messageboard_preferences_title_html', messageboard: messageboard.name %>
</h2>
<ul class="thredded--form-list" data-thredded-user-preferences-form-messageboard-fields>
<li>
<%= f.label :messageboard_auto_follow_topics do %>
<%= f.check_box :messageboard_auto_follow_topics %>
<%= t 'thredded.preferences.form.messageboard_auto_follow_topics.label' %>
<p class="thredded--form-list--hint">
<%= t 'thredded.preferences.form.messageboard_auto_follow_topics.hint' %>
</p>
<% end %>
</li>
<li>
<%= f.label :messageboard_follow_topics_on_mention do %>
<%= f.check_box :messageboard_follow_topics_on_mention %>
<%= t 'thredded.preferences.form.messageboard_follow_topics_on_mention.label' %>
<p class="thredded--form-list--hint">
<%= t 'thredded.preferences.form.messageboard_follow_topics_on_mention.hint' %>
</p>
<% end %>
</li>
<% if Thredded.notifiers.present? %>
<li>
<label><%= t 'thredded.preferences.form.messageboard_notifications_for_followed_topics.label' %></label>
<%= f.fields_for :messageboard_notifications_for_followed_topics,
preferences.messageboard_notifications_for_followed_topics do |fn| %>
<%= fn.label :enabled do %>
<%= fn.hidden_field :notifier_key %>
<%= fn.hidden_field :messageboard_id %>
<%= fn.check_box :enabled %>
<%= fn.object.notifier_human_name %>
<% end %>
<%- end %>
</li>
<% end %>
</ul>
<% end %>
<button type="submit" class="thredded--form--submit"
data-disable-with="<%= t 'thredded.preferences.form.update_btn_submitting' %>">
<%= t 'thredded.preferences.form.submit_btn' %>
</button>
<% end %>

View File

@ -0,0 +1,8 @@
<% preferences.messageboard_groups.each do |group| %>
<h3 class="thredded--messageboards-group--title"><%= group.name %></h3>
<div class="thredded--messageboards-group">
<%= render partial: 'thredded/preferences/messageboards_nav_item',
collection: group.messageboards,
as: :messageboard %>
</div>
<% end %>

View File

@ -0,0 +1,2 @@
<%= link_to messageboard.name, edit_messageboard_preferences_path(messageboard),
class: 'thredded--preferences--messageboards-nav--item thredded--messageboard' %>

View File

@ -0,0 +1,20 @@
<% content_for :thredded_page_title, t('thredded.preferences.edit.page_title') %>
<% content_for :thredded_page_id, 'thredded--preferences' %>
<% content_for :thredded_breadcrumbs, render('thredded/shared/breadcrumbs') %>
<%= thredded_page do %>
<section class="thredded--main-section thredded--preferences">
<section class="thredded--preferences--form">
<h2 class="thredded--preferences--title"><%= t 'thredded.preferences.global_preferences_title' %></h2>
<%= render 'thredded/preferences/form', preferences: @preferences %>
</section>
<% unless preferences.messageboard %>
<section class="thredded--preferences--messageboards-nav">
<h2 class="thredded--preferences--title">
<%= t 'thredded.preferences.messageboard_preferences_nav_title' %>
</h2>
<%= render 'thredded/preferences/messageboards_nav', preferences: @preferences %>
</section>
<% end %>
</section>
<% end %>

View File

@ -0,0 +1 @@
<%= @private_post.filtered_content(self) %>

View File

@ -0,0 +1 @@
<%= @private_post.filtered_content(self) %>

View File

@ -0,0 +1 @@
<%= render 'thredded/posts_common/content', post: post, options: local_assigns[:options] || {} %>

View File

@ -0,0 +1,6 @@
<%# TODO: For private topics, only autocomplete users in this private topic %>
<%= render 'thredded/posts_common/form',
post: post,
button_text: t('thredded.private_posts.form.create_btn'),
button_submitting_text: t('thredded.private_posts.form.create_btn_submitting'),
content_label: t('thredded.private_posts.form.content_label') %>

View File

@ -0,0 +1,6 @@
<% private_post, content = post_and_content if local_assigns.key?(:post_and_content) %>
<%= content_tag :article, id: dom_id(private_post), class: 'thredded--post' do %>
<%= render 'thredded/posts_common/actions', post: private_post, actions: local_assigns[:actions] %>
<%= render 'thredded/posts_common/header', post: private_post %>
<%= content || render('thredded/private_posts/content', post: post) %>
<% end %>

View File

@ -0,0 +1,16 @@
<% content_for :thredded_page_title, t('thredded.nav.edit_post') %>
<% content_for :thredded_page_id, 'thredded--edit-post' %>
<% content_for :thredded_breadcrumbs do %>
<ul class="thredded--navigation-breadcrumbs">
<li><%= link_to t('thredded.nav.edit_post'), edit_post_path(@post_form.post) %></li>
</ul>
<% end %>
<%= thredded_page do %>
<section class="thredded--main-section">
<%= render 'thredded/posts/form',
post: @post_form,
button_text: t('thredded.posts.form.update_btn'),
button_submitting_text: t('thredded.posts.form.update_btn_submitting')%>
</section>
<% end %>

View File

@ -0,0 +1,11 @@
<% private_topic = @post_form.topic %>
<% content_for :thredded_page_title, private_topic.title %>
<% content_for :thredded_page_id, 'thredded--private-topic--new_post' %>
<% content_for :thredded_breadcrumbs, render('thredded/private_topics/breadcrumbs') %>
<%= thredded_page do %>
<section class="thredded--main-section">
<%= render 'thredded/private_posts/form',
post: @post_form %>
</section>
<% end %>

View File

@ -0,0 +1,20 @@
<div class="thredded--email">
<figure class="thredded--email-post">
<figcaption class="thredded--email-post--author">
<%= @post.user.thredded_display_name %> <%= link_to 'said', private_post_permalink_url(@post) %>:
</figcaption>
<% cache [@post, 'content-onebox-placeholders'] do %>
<%= render partial: 'thredded/private_posts/content',
locals: { post: @post, options: {onebox_placeholders: true} } %>
<% end %>
</figure>
<hr/>
<p>
This email was sent to you because <%= @topic.user.thredded_display_name %> included you in a
private topic, "<%= link_to @topic.title, private_topic_url(@topic) %>".
</p>
<p>
To unsubscribe from these emails, update your <%= link_to 'preferences', edit_preferences_url %>.
</p>
</div>

View File

@ -0,0 +1,12 @@
<%= @post.user.thredded_display_name %> said:
<%= @post.content %>
---
This email was sent to you because <%= @topic.user.thredded_display_name %>
included you in the private topic "<%= @topic.title %>".
Go here to view the conversation:
<%= private_post_permalink_url(@post) %>
To unsubscribe from these emails, update your preferences here:
<%= edit_preferences_url %>

View File

@ -0,0 +1 @@
<%= @private_post.filtered_content(self) %>

View File

@ -0,0 +1,4 @@
<ul class="thredded--navigation-breadcrumbs">
<li><%= link_to t('thredded.nav.all_messageboards'), messageboards_path -%></li>
<li><%= link_to t('thredded.nav.private_topics'), private_topics_path -%></li>
</ul>

View File

@ -0,0 +1,39 @@
<%= form_for private_topic,
url: private_topic.submit_path,
html: {
class: "thredded--form thredded--new-private-topic-form #{local_assigns[:css_class]}",
'data-thredded-topic-form' => true,
# TODO: only autocomplete users in this private topic
'data-autocomplete-url' => autocomplete_users_path,
'data-autocomplete-min-length' => Thredded.autocomplete_min_length,
} do |form| %>
<ul class="thredded--form-list on-top">
<li class="title">
<%= form.label :title, t('thredded.private_topics.form.title_label') %>
<%= form.text_field :title, placeholder: placeholder, required: true %>
</li>
<li>
<%= form.label :user_names, t('thredded.private_topics.form.users_label') %>
<%= form.text_area :user_names,
placeholder: t('thredded.private_topics.form.users_placeholder'),
'data-thredded-users-select' => true,
'data-autocomplete-url' => autocomplete_users_path,
'data-autocomplete-min-length' => Thredded.autocomplete_min_length,
rows: 1 %>
</li>
<%= render 'thredded/posts_common/form/content',
form: form,
content_label: t('thredded.private_topics.form.content_label'),
preview_url: private_topic.preview_path %>
<li>
<button type="submit" class="thredded--form--submit"
data-disable-with="<%= t 'thredded.private_topics.form.create_btn_submitting' %>">
<%= t('thredded.private_topics.form.create_btn') %>
</button>
</li>
</ul>
<% end %>

View File

@ -0,0 +1,17 @@
<header class="thredded--topic-header">
<h1 class="thredded--topic-header--title"><%= topic.title %></h1>
<cite class="thredded--topic-header--started-by">
<%= t 'thredded.topics.started_by_html',
time_ago: time_ago(topic.created_at),
user: user_link(topic.user) %>
</cite>
<span class="thredded--topic-header--participants">
<%= render partial: 'thredded/private_topics/header/participant',
collection: (topic.users - [topic.user]) %>
</span>
<% if topic.can_update? %>
<%= link_to t('thredded.private_topics.edit'), topic.edit_path,
class: 'thredded--topic-header--edit-topic',
rel: 'nofollow' %>
<% end %>
</header>

View File

@ -0,0 +1,6 @@
<div class="thredded--empty">
<h3 class="thredded--empty--title"><%= t 'thredded.private_topics.no_private_topics.title' %></h3>
<a class="thredded--button" href="<%= new_private_topic_path %>">
<%= t 'thredded.private_topics.no_private_topics.create_btn' %>
</a>
</div>

View File

@ -0,0 +1,23 @@
<%= content_tag :article,
id: dom_id(private_topic),
class: ['thredded--topics--topic', *topic_css_classes(private_topic)] do %>
<div class="thredded--topics--posts-count"><%= private_topic.posts_count %></div>
<h1 class="thredded--topics--title">
<%= link_to private_topic.title, private_topic.path %>
</h1>
<cite class="thredded--topics--updated-by">
<%= time_ago private_topic.last_post_at %>
<span class="thredded--topics--participants">
<%= render partial: 'thredded/private_topics/private_topic/participant',
collection: [private_topic.last_user, *(private_topic.users - [private_topic.last_user])] %>
</span>
</cite>
<cite class="thredded--topics--started-by">
<%= time_ago private_topic.created_at %>
<%= user_link private_topic.user %>
</cite>
<% end %>

View File

@ -0,0 +1,35 @@
<% content_for :thredded_page_title, t('thredded.nav.edit_private_topic') %>
<% content_for :thredded_page_id, 'thredded--edit-private-topic' %>
<% content_for :thredded_breadcrumbs do %>
<ul class="thredded--navigation-breadcrumbs">
<li><%= link_to t('thredded.nav.all_messageboards'), messageboards_path %></li>
<li><%= link_to t('thredded.nav.private_topics'), private_topics_path %></li>
<li><%= link_to @private_topic.title, topic_path(@private_topic) %></li>
<li><%= link_to t('thredded.nav.edit_private_topic'), edit_private_topic_path(@private_topic) %></li>
</ul>
<% end %>
<%= thredded_page do %>
<section class="thredded--main-section">
<%= form_for @private_topic,
url: private_topic_path(@private_topic),
html: { class: 'thredded--form', 'data-thredded-topic-form' => true } do |form| %>
<ul class="thredded--form-list on-top">
<li class="title">
<%= form.label :title, t('thredded.private_topics.form.title_label') %>
<%= form.text_field :title,
placeholder: t('thredded.private_topics.form.title_placeholder_new'),
autofocus: true,
required: true %>
</li>
<li>
<button type="submit" class="thredded--form--submit"
data-disable-with="<%= t 'thredded.private_topics.form.update_btn_submitting' %>">
<%= t('thredded.private_topics.form.update_btn') %>
</button>
</li>
</ul>
<% end %>
</section>
<% end %>

View File

@ -0,0 +1 @@
<span class="thredded--topic-header--participants--participant"><%= user_link participant %></span>

View File

@ -0,0 +1,32 @@
<% content_for :thredded_page_title, t('thredded.nav.private_topics') %>
<% content_for :thredded_page_id, 'thredded--private-topics-index' %>
<% content_for :thredded_breadcrumbs, render('thredded/private_topics/breadcrumbs') %>
<%= thredded_page do %>
<%= content_tag :section,
class: 'thredded--main-section thredded--private-topics',
'data-thredded-topics' => true do %>
<% if @private_topics.empty? -%>
<%= render 'thredded/private_topics/no_private_topics' %>
<% else -%>
<%= render 'thredded/private_topics/form',
private_topic: @new_private_topic,
css_class: 'thredded--is-compact',
placeholder: t('thredded.private_topics.form.title_placeholder_start') if @new_private_topic %>
<%= render @private_topics %>
<% unless unread_private_topics_count.zero? %>
<%= link_to t('thredded.nav.mark_all_read'),
mark_all_private_topics_read_path,
class: 'thredded--button thredded--button-light thredded--button-wide',
method: :put -%>
<% end %>
<% end -%>
<% end %>
<footer class="thredded--pagination-bottom">
<%= paginate @private_topics %>
</footer>
<% end %>

View File

@ -0,0 +1,11 @@
<% content_for :thredded_page_title, 'Create a New Private Topic' %>
<% content_for :thredded_page_id, 'thredded--new-private-topic' %>
<% content_for :thredded_breadcrumbs, render('thredded/private_topics/breadcrumbs') %>
<%= thredded_page do %>
<section class="thredded--main-section">
<%= render 'thredded/private_topics/form',
private_topic: @private_topic,
placeholder: t('thredded.private_topics.form.title_placeholder_new') if @private_topic %>
</section>
<% end %>

View File

@ -0,0 +1 @@
<span class="thredded--topics--participants--participant"><%= user_link participant %></span>

View File

@ -0,0 +1,28 @@
<% private_topic = @posts.topic %>
<% content_for :thredded_page_title, private_topic.title %>
<% content_for :thredded_page_id, 'thredded--private-topic-show' %>
<% content_for :thredded_breadcrumbs, render('thredded/private_topics/breadcrumbs') %>
<%= thredded_page do %>
<%= content_tag :section,
id: dom_id(private_topic),
class: ['thredded--main-section', 'thredded--topic', *topic_css_classes(private_topic)] do %>
<%= render 'thredded/private_topics/header', topic: private_topic %>
<%= view_hooks.posts_common.pagination_top.render(self, posts: @posts) do %>
<footer class="thredded--pagination-top"><%= paginate @posts %></footer>
<% end %>
<%= render_posts @posts,
partial: 'thredded/private_posts/private_post',
content_partial: 'thredded/private_posts/content',
locals: { actions: { quote: true } } %>
<%= view_hooks.posts_common.pagination_bottom.render(self, posts: @posts) do %>
<footer class="thredded--pagination-bottom"><%= paginate @posts %></footer>
<% end %>
<% if policy(@new_post.post).create? %>
<%= render 'thredded/private_posts/form',
topic: private_topic,
post: @new_post %>
<% end %>
<% end %>
<% end %>

View File

@ -0,0 +1,13 @@
<%= form_tag search_path(messageboard),
method: 'get',
class: 'thredded--form thredded--navigation--search thredded--navigation--search-topics',
'data-thredded-turboform' => true do %>
<%= label_tag :q, t('thredded.search.form.label') %>
<%= text_field_tag :q, @query,
type: 'search',
required: true,
# If there are no results the user will likely want to change the query, so auto-focus.
autofocus: @query.presence && !@topics.presence,
placeholder: t('thredded.search.form.placeholder') %>
<button type="submit"><%= t 'thredded.search.form.btn_submit' %></button>
<% end %>

View File

@ -0,0 +1,6 @@
<ul class="thredded--navigation-breadcrumbs">
<li><%= link_to t('thredded.nav.all_messageboards'), messageboards_path %></li>
<% if messageboard_or_nil.try(:persisted?) %>
<li><%= link_to messageboard.name, messageboard_topics_path(messageboard) %></li>
<% end %>
</ul>

View File

@ -0,0 +1,8 @@
<% # @param moderation_record [Thredded::PostModerationRecord, nil] %>
<% if moderation_record %>
<%= t 'thredded.content_moderation_states.content_blocked_notice_with_record_html',
moderator: user_link(moderation_record.moderator),
time_ago: time_ago(moderation_record.created_at) %>
<% else %>
<%= t 'thredded.content_moderation_states.content_blocked_notice' %>
<% end %>

View File

@ -0,0 +1,18 @@
<% if (users = active_users).present? %>
<aside data-thredded-currently-online class="thredded--currently-online">
<header>
<h3 class="thredded--currently-online--title open">
<%= t "thredded.users.currently_online" %>
</h3>
</header>
<ul class="thredded--currently-online--users">
<% users.each do |user| %>
<li class="thredded--currently-online--user">
<img class="thredded--currently-online--avatar" src="<%= Thredded.avatar_url.call(user) %>" alt=""/>
<%= user.thredded_display_name %>
</li>
<% end %>
</ul>
</aside>
<% end %>

View File

@ -0,0 +1,7 @@
<% [:success, :error, :notice, :alert].each do |key| %>
<% if flash[key] %>
<div class="thredded--flash-message thredded--flash-message--<%= key %>" data-thredded-flash-message>
<%= flash[key] %>
</div>
<% end %>
<% end %>

View File

@ -0,0 +1,3 @@
<header>
<%= render 'thredded/shared/nav' %>
</header>

View File

@ -0,0 +1,17 @@
<nav class="thredded--navigation">
<ul class="thredded--user-navigation<%= ' thredded--user-navigation-standalone' if Thredded.standalone_layout? %>">
<%= render 'thredded/shared/nav/moderation' %>
<%= render 'thredded/shared/nav/notification_preferences', messageboard: messageboard_or_nil %>
<%= render 'thredded/shared/nav/private_topics' %>
<%= render 'thredded/shared/nav/standalone_profile' if thredded_signed_in? %>
<%= render 'thredded/shared/nav/standalone' %>
</ul>
<% if content_for? :thredded_main_navigation %>
<%= yield :thredded_main_navigation %>
<% else %>
<div class="thredded--main-navigation">
<%= yield :thredded_breadcrumbs %>
<%= render 'thredded/search/form', messageboard: messageboard_or_nil %>
</div>
<% end %>
</nav>

View File

@ -0,0 +1,15 @@
<%= content_tag(:div, id: 'thredded--container', class: thredded_container_classes, data: thredded_container_data) do %>
<%= render 'thredded/shared/header' %>
<%= render 'thredded/shared/flash_messages' %>
<%= yield :thredded_page_content %>
<%= render 'thredded/shared/currently_online' %>
<%- end %>
<%# If thredded JS is loaded via an [async] script, the JS may
run before or after DOMContentLoaded. Expose a flag to Thredded
so it can initialize correctly. %>
<script data-turbolinks-eval="false">
document.addEventListener('DOMContentLoaded', function() {
(window.Thredded = window.Thredded || {}).DOMContentLoadedFired = true;
});
</script>

View File

@ -0,0 +1,38 @@
<div class="nav">
<div style="float: left">
<%= link_to main_app.root_path do %>
&lsaquo; Back to <strong>Notebook.ai</strong>
<span style="background: white; width: 5px; padding: 10px 0; margin: 0 10px;">&nbsp;</span>
<%= link_to 'Discussions Home', main_app.thredded_path %>
<% end %>
</div>
<div style="float: right">
<% if user_signed_in? %>
<!--
Hello,
<%= link_to thredded_current_user.thredded_display_name, current_user %>!
-->
<% if thredded_current_user.username.blank? %>
<%= link_to 'Claim your username!', main_app.edit_user_registration_path(thredded_current_user) %>
<% end %>
<% end %>
</div>
<div style="clear: both"></div>
</div>
<style>
.nav {
background: #03A9F4;
color: white;
margin: 0;
padding: 16px 8px;
box-shadow: 1px 1px 1px grey;
}
.nav a {
color: white;
text-decoration: none;
}
</style>

Some files were not shown because too many files have changed in this diff Show More