Merge branch 'master' into groups
Conflicts: db/schema.rb
7
Gemfile
|
@ -28,7 +28,6 @@ gem 'devise'
|
|||
gem 'devise-async'
|
||||
gem 'bootstrap_form'
|
||||
gem 'font-kit-rails'
|
||||
gem 'nprogress-rails'
|
||||
gem 'font-awesome-rails', '~> 4.2.0.0'
|
||||
gem 'rails-assets-growl'
|
||||
gem "paperclip", "~> 4.2"
|
||||
|
@ -38,7 +37,6 @@ gem 'ruby-progressbar'
|
|||
|
||||
gem 'rails_admin'
|
||||
|
||||
gem 'twitter'
|
||||
gem 'sidekiq'
|
||||
gem 'sinatra', require: false
|
||||
|
||||
|
@ -50,6 +48,11 @@ gem 'redcarpet'
|
|||
# OmniAuth and providers
|
||||
gem 'omniauth'
|
||||
gem 'omniauth-twitter'
|
||||
gem 'omniauth-tumblr'
|
||||
|
||||
# OAuth clients
|
||||
gem 'twitter'
|
||||
gem 'tumblr_client'
|
||||
|
||||
gem 'foreman'
|
||||
gem 'redis'
|
||||
|
|
15
Gemfile.lock
|
@ -111,6 +111,8 @@ GEM
|
|||
i18n (~> 0.5)
|
||||
faraday (0.9.0)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
faraday_middleware (0.9.1)
|
||||
faraday (>= 0.7.4, < 0.10)
|
||||
font-awesome-rails (4.2.0.0)
|
||||
railties (>= 3.2, < 5.0)
|
||||
font-kit-rails (1.1.0)
|
||||
|
@ -163,7 +165,6 @@ GEM
|
|||
mini_portile (~> 0.6.0)
|
||||
nokogumbo (1.2.0)
|
||||
nokogiri
|
||||
nprogress-rails (0.1.6.3)
|
||||
oauth (0.4.7)
|
||||
omniauth (1.2.2)
|
||||
hashie (>= 1.2, < 4)
|
||||
|
@ -171,6 +172,8 @@ GEM
|
|||
omniauth-oauth (1.0.1)
|
||||
oauth
|
||||
omniauth (~> 1.0)
|
||||
omniauth-tumblr (1.1)
|
||||
omniauth-oauth (~> 1.0)
|
||||
omniauth-twitter (1.1.0)
|
||||
multi_json (~> 1.3)
|
||||
omniauth-oauth (~> 1.0)
|
||||
|
@ -309,6 +312,13 @@ GEM
|
|||
tilt (1.4.1)
|
||||
timers (4.0.1)
|
||||
hitimes
|
||||
tumblr_client (0.8.5)
|
||||
faraday (~> 0.9.0)
|
||||
faraday_middleware (~> 0.9.0)
|
||||
json
|
||||
mime-types
|
||||
oauth
|
||||
simple_oauth
|
||||
turbolinks (2.5.3)
|
||||
coffee-rails
|
||||
twitter (5.13.0)
|
||||
|
@ -368,8 +378,8 @@ DEPENDENCIES
|
|||
jquery-rails
|
||||
jquery-turbolinks
|
||||
mysql2
|
||||
nprogress-rails
|
||||
omniauth
|
||||
omniauth-tumblr
|
||||
omniauth-twitter
|
||||
paperclip (~> 4.2)
|
||||
pg
|
||||
|
@ -391,6 +401,7 @@ DEPENDENCIES
|
|||
spring
|
||||
sweetalert-rails
|
||||
thin
|
||||
tumblr_client
|
||||
turbolinks
|
||||
twitter
|
||||
uglifier (>= 1.3.0)
|
||||
|
|
24
Rakefile
|
@ -72,7 +72,7 @@ namespace :justask do
|
|||
user.save!
|
||||
puts "#{user.screen_name} no longer an admin."
|
||||
end
|
||||
|
||||
|
||||
desc "Gives moderator status to an user."
|
||||
task :mod, [:screen_name] => :environment do |t, args|
|
||||
fail "screen name required" if args[:screen_name].nil?
|
||||
|
@ -90,7 +90,27 @@ namespace :justask do
|
|||
fail "user #{args[:screen_name]} not found" if user.nil?
|
||||
user.moderator = false
|
||||
user.save!
|
||||
puts "#{user.screen_name} no longer an moderator."
|
||||
puts "#{user.screen_name} is no longer an moderator."
|
||||
end
|
||||
|
||||
desc "Hits an user with the banhammer."
|
||||
task :ban, [:screen_name] => :environment do |t, args|
|
||||
fail "screen name required" if args[:screen_name].nil?
|
||||
user = User.find_by_screen_name(args[:screen_name])
|
||||
fail "user #{args[:screen_name]} not found" if user.nil?
|
||||
user.banned = true
|
||||
user.save!
|
||||
puts "#{user.screen_name} got hit by\033[5m YE OLDE BANHAMMER\033[0m!!1!"
|
||||
end
|
||||
|
||||
desc "Removes banned status from an user."
|
||||
task :unban, [:screen_name] => :environment do |t, args|
|
||||
fail "screen name required" if args[:screen_name].nil?
|
||||
user = User.find_by_screen_name(args[:screen_name])
|
||||
fail "user #{args[:screen_name]} not found" if user.nil?
|
||||
user.banned = false
|
||||
user.save!
|
||||
puts "#{user.screen_name} is no longer banned."
|
||||
end
|
||||
|
||||
desc "Gives supporter status to an user."
|
||||
|
|
|
@ -3,16 +3,13 @@
|
|||
#= require jquery.turbolinks
|
||||
#= require turbolinks
|
||||
#= require bootstrap
|
||||
#= require nprogress
|
||||
#= require nprogress-turbolinks
|
||||
#= require growl
|
||||
#= require cheet
|
||||
#= require jquery.guillotine
|
||||
#= require sweet-alert
|
||||
#= require_tree .
|
||||
|
||||
NProgress.configure
|
||||
showSpinner: false
|
||||
Turbolinks.enableProgressBar()
|
||||
|
||||
window.showNotification = (text, success=true) ->
|
||||
args =
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
<% if Rails.env.production? %>
|
||||
var _paq = _paq || [];
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
_paq.push(['setCustomUrl', document.location]);
|
||||
_paq.push(['setDocumentTitle', document.title]);
|
||||
(function() {
|
||||
var u="//stat.rrerr.net/";
|
||||
_paq.push(['setTrackerUrl', u+'piwik.php']);
|
||||
_paq.push(['setSiteId', 9]);
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
<% else %>
|
||||
console.log("i track'd ur bich");
|
||||
<% end %>
|
|
@ -34,6 +34,8 @@ body { padding-top: $navbar-height; }
|
|||
|
||||
@import "font-awesome";
|
||||
|
||||
$nprogress-color: darken($navbar-inverse-bg, 15%);
|
||||
@import 'nprogress';
|
||||
@import 'nprogress-bootstrap';
|
||||
html.turbolinks-progress-bar::before {
|
||||
background-color: darken($navbar-inverse-bg, 15%) !important;
|
||||
box-shadow: 0px 0px 10px darken($navbar-inverse-bg, 15%), 0px 0px 5px darken($navbar-inverse-bg, 15%);
|
||||
height: 2px !important;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.text-muted a, .answerbox .text-muted a:hover {
|
||||
color: $gray-dark;
|
||||
.answerbox .text-muted a, .answerbox .text-muted a:hover {
|
||||
color: $gray;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,11 @@
|
|||
}
|
||||
|
||||
.answerbox--question-text {
|
||||
font-weight: bold;
|
||||
color: $gray-darker;
|
||||
color: $gray;
|
||||
}
|
||||
|
||||
.answerbox--answer-text {
|
||||
font-size: 16px;
|
||||
color: #000;
|
||||
line-height: 1.3em;
|
||||
}
|
|
@ -120,4 +120,8 @@
|
|||
|
||||
.panel-badge-warning {
|
||||
background-color: #FF9800;
|
||||
}
|
||||
|
||||
.user--banned {
|
||||
text-decoration: line-through !important;
|
||||
}
|
|
@ -4,6 +4,18 @@ class ApplicationController < ActionController::Base
|
|||
protect_from_forgery with: :exception
|
||||
|
||||
before_filter :configure_permitted_parameters, if: :devise_controller?
|
||||
before_filter :banned?
|
||||
|
||||
# check if user got hit by the banhammer of doom
|
||||
def banned?
|
||||
if current_user.present? && current_user.banned?
|
||||
name = current_user.screen_name
|
||||
# obligatory '2001: A Space Odyssey' reference
|
||||
flash[:notice] = "I'm sorry, #{name}, I'm afraid I can't do that."
|
||||
sign_out current_user
|
||||
redirect_to new_user_session_path
|
||||
end
|
||||
end
|
||||
|
||||
include ApplicationHelper
|
||||
|
||||
|
|
|
@ -7,6 +7,10 @@ class NotificationsController < ApplicationController
|
|||
Notification.for(current_user)
|
||||
else
|
||||
Notification.for(current_user).where('LOWER(target_type) = ?', @type)
|
||||
end
|
||||
end.paginate(page: params[:page])
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.js
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,21 +1,12 @@
|
|||
module MarkdownHelper
|
||||
|
||||
def markdown(content)
|
||||
md = Redcarpet::Markdown.new(FlavoredMarkdown,
|
||||
filter_html: true,
|
||||
escape_html: true,
|
||||
no_images: true,
|
||||
no_styles: true,
|
||||
safe_links_only: true,
|
||||
xhtml: false,
|
||||
hard_wrap: true,
|
||||
no_intra_emphasis: true,
|
||||
tables: true,
|
||||
fenced_code_blocks: true,
|
||||
autolink: true,
|
||||
disable_indented_code_blocks: true,
|
||||
strikethrough: true,
|
||||
superscript: true)
|
||||
md = Redcarpet::Markdown.new(FlavoredMarkdown, MARKDOWN_OPTS)
|
||||
Sanitize.fragment(md.render(content), EVIL_TAGS).html_safe
|
||||
end
|
||||
|
||||
def strip_markdown(content)
|
||||
md = Redcarpet::Markdown.new(Redcarpet::Render::StripDown, MARKDOWN_OPTS)
|
||||
CGI.unescape_html(Sanitize.fragment(md.render(content), EVIL_TAGS)).strip
|
||||
end
|
||||
end
|
|
@ -4,7 +4,7 @@ module UserHelper
|
|||
def user_screen_name(user, anonymous=false, url=true)
|
||||
return APP_CONFIG['anonymous_name'] if user.nil? || anonymous
|
||||
name = user.display_name.blank? ? user.screen_name : user.display_name
|
||||
return link_to(name, show_user_profile_path(user.screen_name)) if url
|
||||
return link_to(name, show_user_profile_path(user.screen_name), class: "#{"user--banned" if user.banned?}") if url
|
||||
name
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
class Services::Tumblr < Service
|
||||
include Rails.application.routes.url_helpers
|
||||
include MarkdownHelper
|
||||
|
||||
def provider
|
||||
"tumblr"
|
||||
end
|
||||
|
||||
def post(answer)
|
||||
Rails.logger.debug "posting to Tumblr {'answer' => #{answer.id}, 'user' => #{self.user_id}}"
|
||||
create_post answer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def client
|
||||
@client ||= Tumblr::Client.new(
|
||||
consumer_key: APP_CONFIG['sharing']['tumblr']['consumer_key'],
|
||||
consumer_secret: APP_CONFIG['sharing']['tumblr']['consumer_secret'],
|
||||
oauth_token: self.access_token,
|
||||
oauth_token_secret: self.access_secret
|
||||
)
|
||||
end
|
||||
|
||||
def create_post(answer)
|
||||
answer_url = show_user_answer_url(
|
||||
id: answer.id,
|
||||
username: answer.user.screen_name,
|
||||
host: APP_CONFIG['hostname'],
|
||||
protocol: (APP_CONFIG['https'] ? :https : :http)
|
||||
)
|
||||
asker = if answer.question.author_is_anonymous?
|
||||
APP_CONFIG['anonymous_name']
|
||||
else
|
||||
answer.question.user.display_name.blank? ? answer.question.user.screen_name : answer.question.user.display_name
|
||||
end
|
||||
client.text(
|
||||
self.uid,
|
||||
title: "#{asker} asked: #{answer.question.content}",
|
||||
body: "#{answer.content}\n\n[Smile or comment on the answer here](#{answer_url})",
|
||||
format: 'markdown',
|
||||
tweet: 'off'
|
||||
)
|
||||
end
|
||||
end
|
|
@ -1,5 +1,6 @@
|
|||
class Services::Twitter < Service
|
||||
include Rails.application.routes.url_helpers
|
||||
include MarkdownHelper
|
||||
|
||||
def provider
|
||||
"twitter"
|
||||
|
@ -27,8 +28,8 @@ class Services::Twitter < Service
|
|||
|
||||
def prepare_tweet(answer)
|
||||
# TODO: improve this.
|
||||
question_content = answer.question.content
|
||||
answer_content = answer.content
|
||||
question_content = strip_markdown answer.question.content
|
||||
answer_content = strip_markdown answer.content
|
||||
answer_url = show_user_answer_url(
|
||||
id: answer.id,
|
||||
username: answer.user.screen_name,
|
||||
|
|
|
@ -31,11 +31,11 @@ class User < ActiveRecord::Base
|
|||
SCREEN_NAME_REGEX = /\A[a-zA-Z0-9_]{1,16}\z/
|
||||
WEBSITE_REGEX = /https?:\/\/([A-Za-z.\-]+)\/?(?:.*)/i
|
||||
|
||||
validates :screen_name, presence: true, format: { with: SCREEN_NAME_REGEX }, uniqueness: { case_sensitive: false }#,
|
||||
#exclusion: { in: %w(justask_admin retrospring_admin admin justask retrospring support about public
|
||||
# notifications inbox sign_in sign_up sidekiq moderation moderator mod administrator
|
||||
# siteadmin site_admin),
|
||||
# message: "%{value} is reserved." }
|
||||
before_validation do
|
||||
screen_name.strip!
|
||||
end
|
||||
|
||||
validates :screen_name, presence: true, format: { with: SCREEN_NAME_REGEX }, uniqueness: { case_sensitive: false }, screen_name: true
|
||||
|
||||
validates :display_name, length: { maximum: 50 }
|
||||
validates :bio, length: { maximum: 200 }
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
class ScreenNameValidator < ActiveModel::EachValidator
|
||||
FORBIDDEN_SCREEN_NAMES = %w(justask_admin retrospring_admin admin justask retrospring support about public
|
||||
notifications inbox sign_in sign_up sidekiq moderation moderator mod administrator
|
||||
siteadmin site_admin help retro_spring retroospring retrosprlng niisding nllsding)
|
||||
|
||||
def validate_each(record, attribute, value)
|
||||
if FORBIDDEN_SCREEN_NAMES.include? value.downcase
|
||||
record.errors[attribute] << "Thou shalt not use this username! Please choose another one."
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,8 +5,13 @@
|
|||
%meta{'http-equiv' => 'X-UA-Compatible' ,content: 'IE=edge'}
|
||||
%meta{name: 'viewport', content: 'width=device-width, initial-scale=1, user-scalable=no'}
|
||||
%meta{name: 'theme-color', content: '#0C84E4'}
|
||||
%meta{name: "mobile-web-app-capable", content: "yes"}
|
||||
%meta{name: "apple-mobile-web-app-capable", content: "yes"}
|
||||
%meta{name: 'apple-mobile-web-app-status-bar-style', content: 'black-translucent'}
|
||||
%link{rel: 'apple-touch-icon', href: '/apple-touch-icon-precomposed.png'}
|
||||
%link{rel: 'icon', href: '/images/favicon/favicon-16.png', sizes: '16x16'}
|
||||
%link{rel: 'icon', href: '/icon-152.png', sizes: '152x152'}
|
||||
%link{rel: 'icon', href: '/images/favicon/favicon-32.png', sizes: '32x32'}
|
||||
%title= APP_CONFIG['site_name']
|
||||
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
|
||||
= javascript_include_tag 'application', 'data-turbolinks-track' => true
|
||||
|
@ -27,19 +32,6 @@
|
|||
= debug params
|
||||
|
||||
- if Rails.env.production?
|
||||
:javascript
|
||||
var _paq = _paq || [];
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
_paq.push(['setCustomUrl', document.location]);
|
||||
_paq.push(['setDocumentTitle', document.title]);
|
||||
(function() {
|
||||
var u="//stat.rrerr.net/";
|
||||
_paq.push(['setTrackerUrl', u+'piwik.php']);
|
||||
_paq.push(['setSiteId', 9]);
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
%noscript
|
||||
%p
|
||||
%img{:alt => "", :src => "//stat.rrerr.net/piwik.php?idsite=9", :style => "border:0;"}/
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
%li.list-group-item{class: (notification.new? ? 'list-group-item-warning' : '')}
|
||||
.media
|
||||
- case notification.target_type
|
||||
- when "Answer"
|
||||
.pull-left
|
||||
%img.img-rounded.notification--img{src: gravatar_url(notification.target.user)}
|
||||
.media-body
|
||||
%h6.media-heading.notification--user
|
||||
= user_screen_name notification.target.user
|
||||
%p.notification--text
|
||||
answered
|
||||
%a{href: show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.id), title: "#{notification.target.content[0..40]}...", data: { toggle: :tooltip, placement: :top }}
|
||||
your question
|
||||
= time_ago_in_words notification.target.created_at
|
||||
ago
|
||||
.notification--icon
|
||||
%i.fa.fa-exclamation
|
||||
- when "Relationship"
|
||||
.pull-left
|
||||
%img.img-rounded.notification--img{src: gravatar_url(notification.target.source)}
|
||||
.media-body
|
||||
%h6.media-heading.notification--user
|
||||
= user_screen_name notification.target.source
|
||||
%p.notification--text
|
||||
followed you
|
||||
= time_ago_in_words notification.target.created_at
|
||||
ago
|
||||
.notification--icon
|
||||
%i.fa.fa-users
|
||||
- when "Smile"
|
||||
.pull-left
|
||||
%img.img-rounded.notification--img{src: gravatar_url(notification.target.user)}
|
||||
.media-body
|
||||
%h6.media-heading.notification--user
|
||||
= user_screen_name notification.target.user
|
||||
%p.notification--text
|
||||
smiled at
|
||||
%a{href: show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id), title: "#{notification.target.answer.content[0..40]}...", data: { toggle: :tooltip, placement: :top }}
|
||||
your answer
|
||||
= time_ago_in_words notification.target.created_at
|
||||
ago
|
||||
.notification--icon
|
||||
%i.fa.fa-smile-o
|
||||
- when "Comment"
|
||||
.pull-left
|
||||
%img.img-rounded.notification--img{src: gravatar_url(notification.target.user)}
|
||||
.media-body
|
||||
%h6.media-heading.notification--user
|
||||
= user_screen_name notification.target.user
|
||||
%p.notification--text
|
||||
commented on
|
||||
%a{href: show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id), title: "#{notification.target.answer.content[0..40]}...", data: { toggle: :tooltip, placement: :top }}
|
||||
your answer
|
||||
= time_ago_in_words notification.target.created_at
|
||||
ago
|
||||
.notification--icon
|
||||
%i.fa.fa-comments
|
|
@ -1,63 +1,13 @@
|
|||
.container.j2-page
|
||||
= render 'notification_tabs'
|
||||
.col-md-9.col-xs-12.col-sm-9
|
||||
%ul.list-group
|
||||
%ul#notifications.list-group
|
||||
- @notifications.each do |notification|
|
||||
%li.list-group-item{class: (notification.new? ? 'list-group-item-warning' : '')}
|
||||
.media
|
||||
- case notification.target_type
|
||||
- when "Answer"
|
||||
.pull-left
|
||||
%img.img-rounded.notification--img{src: gravatar_url(notification.target.user)}
|
||||
.media-body
|
||||
%h6.media-heading.notification--user
|
||||
= user_screen_name notification.target.user
|
||||
%p.notification--text
|
||||
answered
|
||||
%a{href: show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.id), title: "#{notification.target.content[0..40]}...", data: { toggle: :tooltip, placement: :top }}
|
||||
your question
|
||||
= time_ago_in_words notification.target.created_at
|
||||
ago
|
||||
.notification--icon
|
||||
%i.fa.fa-exclamation
|
||||
- when "Relationship"
|
||||
.pull-left
|
||||
%img.img-rounded.notification--img{src: gravatar_url(notification.target.source)}
|
||||
.media-body
|
||||
%h6.media-heading.notification--user
|
||||
= user_screen_name notification.target.source
|
||||
%p.notification--text
|
||||
followed you
|
||||
= time_ago_in_words notification.target.created_at
|
||||
ago
|
||||
.notification--icon
|
||||
%i.fa.fa-users
|
||||
- when "Smile"
|
||||
.pull-left
|
||||
%img.img-rounded.notification--img{src: gravatar_url(notification.target.user)}
|
||||
.media-body
|
||||
%h6.media-heading.notification--user
|
||||
= user_screen_name notification.target.user
|
||||
%p.notification--text
|
||||
smiled at
|
||||
%a{href: show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id), title: "#{notification.target.answer.content[0..40]}...", data: { toggle: :tooltip, placement: :top }}
|
||||
your answer
|
||||
= time_ago_in_words notification.target.created_at
|
||||
ago
|
||||
.notification--icon
|
||||
%i.fa.fa-smile-o
|
||||
- when "Comment"
|
||||
.pull-left
|
||||
%img.img-rounded.notification--img{src: gravatar_url(notification.target.user)}
|
||||
.media-body
|
||||
%h6.media-heading.notification--user
|
||||
= user_screen_name notification.target.user
|
||||
%p.notification--text
|
||||
commented on
|
||||
%a{href: show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id), title: "#{notification.target.answer.content[0..40]}...", data: { toggle: :tooltip, placement: :top }}
|
||||
your answer
|
||||
= time_ago_in_words notification.target.created_at
|
||||
ago
|
||||
.notification--icon
|
||||
%i.fa.fa-comments
|
||||
= render 'notifications/notification', notification: notification
|
||||
|
||||
#pagination= will_paginate @notifications, renderer: BootstrapPagination::Rails, page_links: false
|
||||
|
||||
- if @notifications.next_page
|
||||
%button#load-more-btn.btn.btn-default{type: :button, data: { current_page: @notifications.current_page }}
|
||||
Load more
|
||||
- Notification.for(current_user).update_all(new: false)
|
|
@ -0,0 +1,8 @@
|
|||
$('#notifications').append('<% @notifications.each do |notification|
|
||||
%><%= j render 'notifications/notification', notification: notification
|
||||
%><% end %>');
|
||||
<% if @notifications.next_page %>
|
||||
$('#pagination').html('<%= j will_paginate @notifications, renderer: BootstrapPagination::Rails, page_links: false %>');
|
||||
<% else %>
|
||||
$('#pagination, #load-more-btn').remove();
|
||||
<% end %>
|
|
@ -20,18 +20,20 @@
|
|||
·
|
||||
%a{href: show_user_question_path(a.question.user.screen_name, a.question.id)}
|
||||
#{a.question.answer_count} answers
|
||||
%p.answerbox--question-text
|
||||
.answerbox--question-text
|
||||
= a.question.content
|
||||
.panel-body
|
||||
- if @display_all.nil?
|
||||
= markdown a.content[0..255]
|
||||
- if a.content.length > 255
|
||||
[...]
|
||||
%p
|
||||
%a.btn.btn-primary{href: show_user_answer_path(a.user.screen_name, a.id)}
|
||||
Read the entire answer
|
||||
.answerbox--answer-text
|
||||
= markdown a.content[0..255]
|
||||
- if a.content.length > 255
|
||||
[...]
|
||||
%p
|
||||
%a.btn.btn-primary{href: show_user_answer_path(a.user.screen_name, a.id)}
|
||||
Read the entire answer
|
||||
- else
|
||||
= markdown a.content
|
||||
.answerbox--answer-text
|
||||
= markdown a.content
|
||||
- if @user.nil?
|
||||
.row
|
||||
.col-md-6.col-sm-4.col-xs-7.text-left.text-muted
|
||||
|
|
|
@ -6,47 +6,52 @@
|
|||
- else
|
||||
= @user.motivation_header
|
||||
.panel-body
|
||||
- if user_signed_in? or @user.privacy_allow_anonymous_questions?
|
||||
#question-box
|
||||
.row
|
||||
.col-xs-12
|
||||
%textarea.form-control{:name => "qb-question", :placeholder => "Type your question here…"}
|
||||
.row{:style => "padding-top: 5px; padding-left: 5px; padding-right: 5px;"}
|
||||
.col-xs-6
|
||||
- if user_signed_in?
|
||||
- if @user.privacy_allow_anonymous_questions?
|
||||
%input{:name => "qb-anonymous", :type => "checkbox"}/
|
||||
Hide your name
|
||||
%br/
|
||||
- else
|
||||
%input{:name => "qb-anonymous", :type => "hidden", :value => "false"}/
|
||||
.col-xs-6
|
||||
%p.pull-right
|
||||
%input{name: 'qb-to', type: 'hidden', :value => @user.id}/
|
||||
%button.btn.btn-primary{name: 'qb-ask', :type => "button", data: {loading_text: 'Asking...', promote: user_signed_in? ? "false" : "true" }} Ask
|
||||
- unless user_signed_in?
|
||||
- if @user.privacy_allow_anonymous_questions?
|
||||
#question-box-promote.row{:style => "display: none;"}
|
||||
- if @user.banned?
|
||||
.row
|
||||
.col-xs-12.text-center
|
||||
%strong This user got hit with ye olde banhammer.
|
||||
- else
|
||||
- if user_signed_in? or @user.privacy_allow_anonymous_questions?
|
||||
#question-box
|
||||
.row
|
||||
.col-xs-12.text-center
|
||||
%strong Your question has been sent.
|
||||
.row
|
||||
.col-sm-1
|
||||
.col-sm-5
|
||||
%button#create-account.btn.btn-block.btn-primary Create an account
|
||||
.col-sm-5
|
||||
%button#new-question.btn.btn-block.btn-default Ask another question
|
||||
.col-sm-1
|
||||
.row
|
||||
.col-sm-1
|
||||
.col-xs-12.col-sm-10
|
||||
%small
|
||||
Join
|
||||
= APP_CONFIG['site_name']
|
||||
today! You'll be able to follow and ask people you know and a lot more.
|
||||
.col-sm-1
|
||||
- else
|
||||
%p
|
||||
This user does not want to get asked by strangers. Why don't you
|
||||
= succeed "?" do
|
||||
%a{:href => "{{ url_for('register') }}"} sign up
|
||||
.col-xs-12
|
||||
%textarea.form-control{:name => "qb-question", :placeholder => "Type your question here…"}
|
||||
.row{:style => "padding-top: 5px; padding-left: 5px; padding-right: 5px;"}
|
||||
.col-xs-6
|
||||
- if user_signed_in?
|
||||
- if @user.privacy_allow_anonymous_questions?
|
||||
%input{:name => "qb-anonymous", :type => "checkbox"}/
|
||||
Hide your name
|
||||
%br/
|
||||
- else
|
||||
%input{:name => "qb-anonymous", :type => "hidden", :value => "false"}/
|
||||
.col-xs-6
|
||||
%p.pull-right
|
||||
%input{name: 'qb-to', type: 'hidden', :value => @user.id}/
|
||||
%button.btn.btn-primary{name: 'qb-ask', :type => "button", data: {loading_text: 'Asking...', promote: user_signed_in? ? "false" : "true" }} Ask
|
||||
- unless user_signed_in?
|
||||
- if @user.privacy_allow_anonymous_questions?
|
||||
#question-box-promote.row{:style => "display: none;"}
|
||||
.row
|
||||
.col-xs-12.text-center
|
||||
%strong Your question has been sent.
|
||||
.row
|
||||
.col-sm-1
|
||||
.col-sm-5
|
||||
%button#create-account.btn.btn-block.btn-primary Create an account
|
||||
.col-sm-5
|
||||
%button#new-question.btn.btn-block.btn-default Ask another question
|
||||
.col-sm-1
|
||||
.row
|
||||
.col-sm-1
|
||||
.col-xs-12.col-sm-10
|
||||
%small
|
||||
Join
|
||||
= APP_CONFIG['site_name']
|
||||
today! You'll be able to follow and ask people you know and a lot more.
|
||||
.col-sm-1
|
||||
- else
|
||||
%p
|
||||
This user does not want to get asked by strangers. Why don't you
|
||||
= succeed "?" do
|
||||
%a{:href => "{{ url_for('register') }}"} sign up
|
|
@ -106,9 +106,7 @@
|
|||
People that believe in our vision, and that's why we love them <3
|
||||
%ul.about--moderator
|
||||
- User.where(supporter: true).each do |sup|
|
||||
%li
|
||||
%a{href: show_user_profile_path(sup.screen_name)}
|
||||
%img.answerbox--img-small{src: User.find_by_screen_name(sup.screen_name).profile_picture.url(:medium)}
|
||||
= sup.screen_name
|
||||
%a{href: show_user_profile_path(sup.screen_name), title: sup.screen_name, data: { toggle: :tooltip, placement: :top }}
|
||||
%img.img-rounded.answerbox--img-small{src: sup.profile_picture.url(:medium)}
|
||||
|
||||
= render "shared/links"
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
.profile--panel-badge.panel-badge-warning
|
||||
%i.fa.fa-star
|
||||
Supporter
|
||||
- if @user.banned?
|
||||
.profile--panel-badge.panel-badge-default
|
||||
%i.fa.fa-ban
|
||||
Banned
|
||||
- if @user.following? current_user
|
||||
.profile--panel-badge.panel-badge-default
|
||||
Follows you
|
||||
|
|
|
@ -19,5 +19,6 @@ module Justask
|
|||
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
||||
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
||||
# config.i18n.default_locale = :de
|
||||
config.autoload_paths += %W["#{config.root}/app/validators"]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
Rails.application.config.middleware.use OmniAuth::Builder do
|
||||
if APP_CONFIG['sharing']['twitter']['enabled']
|
||||
provider :twitter, APP_CONFIG['sharing']['twitter']['consumer_key'], APP_CONFIG['sharing']['twitter']['consumer_secret']
|
||||
%w(facebook twitter tumblr).each do |service|
|
||||
if APP_CONFIG['sharing'][service]['enabled']
|
||||
provider service.to_sym, APP_CONFIG['sharing'][service]['consumer_key'], APP_CONFIG['sharing'][service]['consumer_secret']
|
||||
end
|
||||
end
|
||||
end
|
|
@ -41,6 +41,7 @@ RailsAdmin.config do |config|
|
|||
Report
|
||||
Service
|
||||
Services::Twitter
|
||||
Services::Tumblr
|
||||
Smile
|
||||
User
|
||||
]
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
require 'redcarpet/render_strip'
|
||||
|
||||
MARKDOWN_OPTS = {
|
||||
filter_html: true,
|
||||
escape_html: true,
|
||||
no_images: true,
|
||||
no_styles: true,
|
||||
safe_links_only: true,
|
||||
xhtml: false,
|
||||
hard_wrap: true,
|
||||
no_intra_emphasis: true,
|
||||
tables: true,
|
||||
fenced_code_blocks: true,
|
||||
autolink: true,
|
||||
disable_indented_code_blocks: true,
|
||||
strikethrough: true,
|
||||
superscript: false
|
||||
}
|
|
@ -21,6 +21,11 @@ sharing:
|
|||
consumer_secret: ''
|
||||
facebook:
|
||||
enabled: false
|
||||
tumblr:
|
||||
enabled: true
|
||||
# Get the tokens from https://www.tumblr.com/oauth/apps
|
||||
consumer_key: ''
|
||||
consumer_secret: ''
|
||||
|
||||
# Redis
|
||||
redis_url: "redis://localhost:6379"
|
|
@ -0,0 +1,5 @@
|
|||
class AddBannedToUsers < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :banned, :boolean, default: false
|
||||
end
|
||||
end
|
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20150108121010) do
|
||||
ActiveRecord::Schema.define(version: 20150112210755) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -197,6 +197,7 @@ ActiveRecord::Schema.define(version: 20150108121010) do
|
|||
t.boolean "privacy_allow_public_timeline", default: true
|
||||
t.boolean "privacy_allow_stranger_answers", default: true
|
||||
t.boolean "privacy_show_in_search", default: true
|
||||
t.boolean "banned", default: false
|
||||
end
|
||||
|
||||
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
|
||||
|
|
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.4 KiB |