Merge pull request #68 from Retrospring/feature/bootstrap

This commit is contained in:
Andreas Nedbal 2020-05-09 03:34:58 +02:00 committed by GitHub
commit 6bdaff83c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
230 changed files with 3058 additions and 3796 deletions

View File

@ -47,7 +47,7 @@ jobs:
with:
ruby-version: 2.7.x
- name: Install dependencies
run: sudo apt-get install -y libpq-dev libxml2-dev libxslt1-dev libmagickwand-dev imagemagick
run: sudo apt update && sudo apt-get install -y libpq-dev libxml2-dev libxslt1-dev libmagickwand-dev imagemagick
- name: Copy default configuration
run: |
cp config/database.yml.postgres config/database.yml

View File

@ -19,8 +19,7 @@ gem 'jbuilder', '~> 2.10'
gem 'bcrypt', '~> 3.1.7'
gem 'haml', '~> 5.0'
gem 'bootstrap-sass', '~> 3.4.0'
gem 'bootswatch-rails'
gem 'bootstrap', '~> 4.4', '>= 4.4.1'
gem 'sweetalert-rails'
gem 'devise', '~> 4.0'
gem 'devise-i18n'
@ -35,7 +34,8 @@ gem 'fog-core'
gem 'fog-aws'
gem 'fog-local'
gem 'momentjs-rails', '>= 2.9.0'
gem 'bootstrap3-datetimepicker-rails', '~> 4.7.14'
gem 'moment-timezone-rails', '~> 1.0'
gem 'bootstrap4-datetime-picker-rails'
gem 'tiny-color-rails'
gem 'jquery-minicolors-rails'
gem 'colorize'

View File

@ -76,16 +76,17 @@ GEM
erubi (>= 1.0.0)
rack (>= 0.9.0)
bindex (0.8.1)
bootstrap-sass (3.4.1)
autoprefixer-rails (>= 5.2.1)
sassc (>= 2.0.0)
bootstrap3-datetimepicker-rails (4.7.14)
momentjs-rails (>= 2.8.1)
bootstrap (4.4.1)
autoprefixer-rails (>= 9.1.0)
popper_js (>= 1.14.3, < 2)
sassc-rails (>= 2.0.0)
bootstrap4-datetime-picker-rails (0.3.1)
jquery-rails (~> 4.2, >= 4.2.0)
moment-timezone-rails (~> 1.0)
momentjs-rails (>= 2.10.5, <= 3.0.0)
bootstrap_form (4.4.0)
actionpack (>= 5.0)
activemodel (>= 5.0)
bootswatch-rails (3.3.5)
railties (>= 3.1)
brakeman (4.8.1)
buftok (0.2.0)
builder (3.2.4)
@ -269,6 +270,8 @@ GEM
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.14.0)
moment-timezone-rails (1.0.0)
momentjs-rails (>= 2.10.5, <= 3.0.0)
momentjs-rails (2.20.1)
railties (>= 3.1)
multi_json (1.14.1)
@ -314,6 +317,7 @@ GEM
capybara (>= 2.1, < 4)
cliver (~> 0.3.1)
websocket-driver (>= 0.2.0)
popper_js (1.16.0)
pry (0.13.1)
coderay (~> 1.1)
method_source (~> 1.0)
@ -511,10 +515,9 @@ PLATFORMS
DEPENDENCIES
bcrypt (~> 3.1.7)
better_errors
bootstrap-sass (~> 3.4.0)
bootstrap3-datetimepicker-rails (~> 4.7.14)
bootstrap (~> 4.4, >= 4.4.1)
bootstrap4-datetime-picker-rails
bootstrap_form
bootswatch-rails
brakeman
byebug
capybara
@ -543,6 +546,7 @@ DEPENDENCIES
jquery-rails
jquery-turbolinks
letter_opener
moment-timezone-rails (~> 1.0)
momentjs-rails (>= 2.9.0)
newrelic_rpm
nprogress-rails

View File

@ -3,7 +3,7 @@ $(document).on "click", "button[name=ab-smile-comment]", ->
cid = btn[0].dataset.cId
action = btn[0].dataset.action
count = Number $("span#ab-comment-smile-count-#{cid}").html()
btn[0].dataset.loadingText = "<i class=\"fa fa-meh-o fa-spin\"></i> <span id=\"ab-smile-count-#{cid}\">#{count}</span>"
btn[0].dataset.loadingText = "<i class=\"fa fa-fw fa-meh-o fa-spin\"></i> <span id=\"ab-smile-count-#{cid}\">#{count}</span>"
btn.button "loading"
target_url = switch action
@ -36,8 +36,8 @@ $(document).on "click", "button[name=ab-smile-comment]", ->
switch action
when 'smile'
btn[0].dataset.action = 'unsmile'
btn.html "<i class=\"fa fa-frown-o\"></i> <span id=\"ab-comment-smile-count-#{cid}\">#{count}</span>"
btn.html "<i class=\"fa fa-fw fa-frown-o\"></i> <span id=\"ab-comment-smile-count-#{cid}\">#{count}</span>"
when 'unsmile'
btn[0].dataset.action = 'smile'
btn.html "<i class=\"fa fa-smile-o\"></i> <span id=\"ab-comment-smile-count-#{cid}\">#{count}</span>"
btn.html "<i class=\"fa fa-fw fa-smile-o\"></i> <span id=\"ab-comment-smile-count-#{cid}\">#{count}</span>"
, 20

View File

@ -3,7 +3,7 @@ $(document).on "click", "button[name=ab-smile]", ->
aid = btn[0].dataset.aId
action = btn[0].dataset.action
count = Number $("span#ab-smile-count-#{aid}").html()
btn[0].dataset.loadingText = "<i class=\"fa fa-meh-o fa-spin\"></i> <span id=\"ab-smile-count-#{aid}\">#{count}</span>"
btn[0].dataset.loadingText = "<i class=\"fa fa-fw fa-meh-o fa-spin\"></i> <span id=\"ab-smile-count-#{aid}\">#{count}</span>"
btn.button "loading"
target_url = switch action
@ -36,8 +36,8 @@ $(document).on "click", "button[name=ab-smile]", ->
switch action
when 'smile'
btn[0].dataset.action = 'unsmile'
btn.html "<i class=\"fa fa-frown-o\"></i> <span id=\"ab-smile-count-#{aid}\">#{count}</span>"
btn.html "<i class=\"fa fa-fw fa-frown-o\"></i> <span id=\"ab-smile-count-#{aid}\">#{count}</span>"
when 'unsmile'
btn[0].dataset.action = 'smile'
btn.html "<i class=\"fa fa-smile-o\"></i> <span id=\"ab-smile-count-#{aid}\">#{count}</span>"
btn.html "<i class=\"fa fa-fw fa-smile-o\"></i> <span id=\"ab-smile-count-#{aid}\">#{count}</span>"
, 20

View File

@ -1,8 +1,8 @@
#= require jquery
#= require jquery3
#= require jquery_ujs
#= require jquery.turbolinks
#= require jquery.arctic_scroll
#= require turbolinks
#= require popper
#= require bootstrap
#= require nprogress
#= require nprogress-turbolinks
@ -24,7 +24,6 @@
#= require memes
#= require notifications
#= require pagination
#= require piwik
#= require question
#= require settings
#= require user
@ -74,18 +73,16 @@ _ready = ->
lineColor: bodyColor
density: 23000
$(".alert-announcement").each ->
$(".announcement").each ->
aId = $(this)[0].dataset.announcementId
unless (window.localStorage.getItem("announcement#{aId}"))
$(this).toggleClass("hidden")
$(this).toggleClass("d-none")
$(document).on "click", ".alert-announcement button.close", (evt) ->
announcement = event.target.closest(".alert-announcement")
$(document).on "click", ".announcement button.close", (evt) ->
announcement = event.target.closest(".announcement")
aId = announcement.dataset.announcementId
window.localStorage.setItem("announcement#{aId}", true)
$('.arctic_scroll').arctic_scroll speed: 500
$(document).ready _ready
$(document).on 'page:load', _ready

View File

@ -1,3 +1,3 @@
cheet 'up up down down left right left right b a', ->
($ "body").addClass 'fa-spin'
($ "p.answerbox--question-text").each (i) -> ($ this).html ":^)"
($ "p.answerbox__question-text").each (i) -> ($ this).html ":^)"

View File

@ -1,3 +1,5 @@
#= require moment
#= require bootstrap-datetimepicker
#= require tempusdominus-bootstrap-4
#= require_tree ./moderation
$('.datetimepicker-input').datetimepicker({});

View File

@ -19,21 +19,6 @@ load = ->
else
$("#ban-controls-time").show()
untilInput = $ modalForm.elements["until"]
untilInput.datetimepicker
defaultDate: untilInput.val()
sideBySide: true
icons:
time: "fa fa-clock-o"
date: "fa fa-calendar"
up: "fa fa-chevron-up"
down: "fa fa-chevron-down"
previous: "fa fa-chevron-left"
next: "fa fa-chevron-right"
today: "fa fa-home"
clear: "fa fa-trash-o"
close: "fa fa-times"
modalForm.addEventListener "submit", (event) ->
event.preventDefault();

View File

@ -1,5 +1,5 @@
jQuery ->
if $('#pagination').size() > 0
if $('#pagination').length > 0
$('#pagination').hide()
loading_posts = false

View File

@ -1,16 +0,0 @@
<% 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);
})();
<% elsif !Rails.env.test? %>
console.log("i track'd ur bich");
<% end %>

View File

@ -102,40 +102,17 @@ if window.URL? or window.webkitURL?
# theming
previewStyle = document.createElement 'style'
document.head.appendChild previewStyle
previewTimeout = null
previewTheme = ->
payload = {}
$('#update_theme').find('.color').each ->
n = this.name.substr 6, this.name.length - 7
payload[n] = parseInt this.value.substr(1, 6), 16
$.post '/settings/theme/preview.css', payload, (data) ->
previewStyle.innerHTML = data
, 'text'
null
themePresets = {
rs: [0x5E35B1, 0xFFFFFF, 0xFF0039, 0xFFFFFF, 0x3FB618, 0xFFFFFF, 0xFF7518, 0xFFFFFF, 0x9954BB, 0xFFFFFF, 0x222222, 0xEEEEEE, 0xF9F9F9, 0x151515, 0x5E35B1, 0xFFFFFF, 0x222222, 0xbbbbbb, 0xFFFFFF, 0x000000, 0x5E35B1],
dc: [0x141414, 0xeeeeee, 0x362222, 0xeeeeee, 0x1d2e1d, 0xeeeeee, 0x404040, 0xeeeeee, 0xb8b8b8, 0x3b3b3b, 0x303030, 0xEEEEEE, 0x202020, 0xeeeeee, 0x9c9a9a, 0x363636, 0xe6e6e6, 0xbbbbbb, 0x383838, 0xebebeb, 0x787676],
lc: [0xebebeb, 0x111111, 0xf76363, 0x111111, 0x8aff94, 0x111111, 0xffbd7f, 0x111111, 0x474747, 0xc4c4c4, 0xcfcfcf, 0x111111, 0xdfdfdf, 0x111111, 0x636565, 0xc9c9c9, 0x191919, 0x444444, 0xc7c7c7, 0x141414, 0x878989]
}
$(document).on 'submit', '#update_theme', (event) ->
$this = $ this
$this.find('.color').each ->
this.value = parseInt this.value.substr(1, 6), 16
true
previewStyle = null
$(document).ready ->
previewStyle = document.createElement 'style'
document.body.appendChild previewStyle
previewTimeout = null
$('#update_theme .color').each ->
$this = $ this
this.value = '#' + ('000000' + parseInt(this.value).toString(16)).substr(-6, 6)
this.value = '#' + getHexColorFromThemeValue(this.value)
$this.minicolors
control: 'hue'
@ -152,4 +129,72 @@ $(document).ready ->
$(document).on 'click', 'a.theme_preset', (event) ->
preset = [].concat themePresets[this.dataset.preset]
$('#update_theme .color').each ->
$(this).minicolors 'value', '#' + ('000000' + parseInt(preset.shift()).toString(16)).substr(-6, 6)
$(this).minicolors 'value', '#' + getHexColorFromThemeValue(preset.shift())
previewTheme = ->
payload = {}
$('#update_theme').find('.color').each ->
n = this.name.substr 6, this.name.length - 7
payload[n] = parseInt this.value.substr(1, 6), 16
generateTheme payload
null
generateTheme = (payload) ->
theme_attribute_map = {
'primary_color': 'primary',
'primary_text': 'primary-text',
'danger_color': 'danger',
'danger_text': 'danger-text',
'warning_color': 'warning',
'warning_text': 'warning-text',
'info_color': 'info',
'info_text': 'info-text',
'success_color': 'success',
'success_text': 'success-text',
'dark_color': 'dark',
'dark_text': 'dark-text',
'light_color': 'light',
'light_text': 'light-text',
'raised_background': 'raised-bg',
'raised_accent': 'raised-accent',
'background_color': 'background',
'body_text': 'body-text',
'input_color': 'input-bg',
'input_text': 'input-text',
'muted_text': 'muted-text'
}
body = ":root {\n"
(Object.keys(payload)).forEach (plKey) ->
if theme_attribute_map[plKey]
if theme_attribute_map[plKey].includes 'text'
hex = getHexColorFromThemeValue(payload[plKey])
body += "--#{theme_attribute_map[plKey]}: #{getDecimalTripletsFromHex(hex)};\n"
else
body += "--#{theme_attribute_map[plKey]}: ##{getHexColorFromThemeValue(payload[plKey])};\n"
body += "}"
previewStyle.innerHTML = body
getHexColorFromThemeValue = (themeValue) ->
return ('000000' + parseInt(themeValue).toString(16)).substr(-6, 6)
getDecimalTripletsFromHex = (hex) ->
return hex.match(/.{1,2}/g).map((value) -> parseInt(value, 16)).join(', ')
themePresets = {
rs: [0x5E35B1, 0xFFFFFF, 0xFF0039, 0xFFFFFF, 0x3FB618, 0xFFFFFF, 0xFF7518, 0xFFFFFF, 0x9954BB, 0xFFFFFF, 0x222222, 0xEEEEEE, 0xF9F9F9, 0x151515, 0x5E35B1, 0xFFFFFF, 0x222222, 0xbbbbbb, 0xFFFFFF, 0x000000, 0x5E35B1],
dc: [0x141414, 0xeeeeee, 0x362222, 0xeeeeee, 0x1d2e1d, 0xeeeeee, 0x404040, 0xeeeeee, 0xb8b8b8, 0x3b3b3b, 0x303030, 0xEEEEEE, 0x202020, 0xeeeeee, 0x9c9a9a, 0x363636, 0xe6e6e6, 0xbbbbbb, 0x383838, 0xebebeb, 0x787676],
lc: [0xebebeb, 0x111111, 0xf76363, 0x111111, 0x8aff94, 0x111111, 0xffbd7f, 0x111111, 0x474747, 0xc4c4c4, 0xcfcfcf, 0x111111, 0xdfdfdf, 0x111111, 0x636565, 0xc9c9c9, 0x191919, 0x444444, 0xc7c7c7, 0x141414, 0x878989]
}
$(document).on 'submit', '#update_theme', (event) ->
$this = $ this
$this.find('.color').each ->
this.value = parseInt this.value.substr(1, 6), 16
true

View File

@ -0,0 +1,3 @@
.ios-web-app {
padding-top: 1em;
}

View File

@ -0,0 +1,95 @@
// Font settings
@import url(https://fonts.googleapis.com/css?family=Lato:400,700);
$font-family-sans-serif: "Lato","Open Sans", "Helvetica Neue", Helvetica, "DejaVu Sans", Arial, sans-serif;
$font-family-serif: Georgia, "DejaVu Serif", "Times New Roman", Times, serif;
$font-family-monospace: "PragmataPro", Monaco, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace;
$font-family-base: $font-family-sans-serif;
$font-size-base: 1rem;
$font-size-large: ceil(($font-size-base * 1.25)); // ~18px
$font-size-small: ceil(($font-size-base * 0.85)); // ~12px
$font-size-h1: floor(($font-size-base * 2.6)); // ~36px
$font-size-h2: floor(($font-size-base * 2.15)); // ~30px
$font-size-h3: ceil(($font-size-base * 1.7)); // ~24px
$font-size-h4: ceil(($font-size-base * 1.25)); // ~18px
$font-size-h5: $font-size-base;
$font-size-h6: ceil(($font-size-base * 0.85)); // ~12px
// Usual navbar height
$navbar-height: 56px;
// Color overrides for Bootstrap
$primary: #5e35b1;
// Cards
$card-border-width: 0;
// List Groups
$list-group-border-width: 0;
// nProgress
$nprogress-color: lighten($primary, 25%);
// Color names for theme generation
$color-names: (
"primary",
"danger",
"warning",
"info",
"success",
"dark",
"light"
);
// Avatar variables
$avatar-border-radius: 4px;
$avatar-sizes: (
"xs": 20px,
"sm": 30px,
"md": 40px,
"lg": 80px,
"xl": 160px,
);
:root {
--background: #f0edf4;
--input-bg: var(--background);
--raised-bg: #ffffff;
--raised-accent: #f7f7f7;
/**
NOTE for all *-text variables
----------------------------------------------
The text-variables are present as triplets
because in some places it's required to adjust
their transparency.
So, for general usage, use:
color: RGB(var(--*-text));
And for transparent usage, use:
color: rgba(var(--*-text), .7);
The uppercase RGB is required because internally
SassC wants more than one argument for rgb(),
hence writing RGB() bypasses that check, but
browsers interpret it correctly.
*/
--primary-text: 255, 255, 255;
--danger-text: 255, 255, 255;
--warning-text: 41, 41, 41;
--info-text: 255, 255, 255;
--success-text: 255, 255, 255;
--dark-text: 255, 255, 255;
--light-text: 0, 0, 0;
--body-text: 0, 0, 0;
--muted-text: 108, 117, 125;
--input-text: 0, 0, 0;
}
$gray: #e2e2e2;

View File

@ -1,74 +0,0 @@
/*
*= require rails_bootstrap_forms
*= require growl
*= require jquery.guillotine
*= require sweetalert
*= require jquery.minicolors
*= require flags
*= require_self
*/
@import url(https://fonts.googleapis.com/css?family=Lato:400,700);
$font-family-sans-serif: "Lato","Open Sans", "Helvetica Neue", Helvetica, "DejaVu Sans", Arial, sans-serif;
$font-family-serif: Georgia, "DejaVu Serif", "Times New Roman", Times, serif;
//** Default monospace fonts for `<code>`, `<kbd>`, and `<pre>`.
$font-family-monospace: "PragmataPro", Monaco, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace;
$font-family-base: $font-family-sans-serif;
$font-size-base: 14px;
$font-size-large: ceil(($font-size-base * 1.25)); // ~18px
$font-size-small: ceil(($font-size-base * 0.85)); // ~12px
$font-size-h1: floor(($font-size-base * 2.6)); // ~36px
$font-size-h2: floor(($font-size-base * 2.15)); // ~30px
$font-size-h3: ceil(($font-size-base * 1.7)); // ~24px
$font-size-h4: ceil(($font-size-base * 1.25)); // ~18px
$font-size-h5: $font-size-base;
$font-size-h6: ceil(($font-size-base * 0.85)); // ~12px
$brand-primary: #5e35b1;
$navbar-inverse-bg: #5e35b1;
$navbar-inverse-link-color: #ffffff;
$navbar-inverse-link-hover-color: #ffffff;
$navbar-inverse-link-hover-bg: transparent;
$navbar-inverse-link-active-color: #ffffff;
$navbar-inverse-link-active-bg: transparent;
$navbar-inverse-link-active-bg-mobile: darken(#5e35b1, 7%);
$navbar-inverse-link-disabled-color: darken(#fff, 12.5%);
$navbar-inverse-link-disabled-bg: transparent;
$navbar-inverse-brand-color: $navbar-inverse-link-color;
$navbar-inverse-brand-hover-color: darken($navbar-inverse-link-color, 10%);
$navbar-inverse-brand-hover-bg: transparent;
$navbar-inverse-toggle-hover-bg: #512da8;
$navbar-inverse-toggle-icon-bar-bg: #7e57c2;
$navbar-inverse-toggle-border-color: #512da8;
@import "bootswatch/cosmo/variables";
@import "bootstrap";
body { padding-top: $navbar-height; }
@import 'bootstrap-datetimepicker';
.remove-native-picker::-webkit-calendar-picker-indicator{
display: none
}
@import "bootswatch/cosmo/bootswatch";
@import "base";
@import "font-awesome";
$nprogress-color: lighten($navbar-inverse-bg, 25%);
@import 'nprogress';
@import 'nprogress-bootstrap';
.minicolors-theme-bootstrap .minicolors-swatch {
top: 0;
left: 0;
width: 42px;
height: 42px;
border-radius: 0;
}

View File

@ -0,0 +1,103 @@
/*
*= require rails_bootstrap_forms
*= require growl
*= require jquery.guillotine
*= require sweetalert
*= require jquery.minicolors
*= require flags
*= require_self
*/
/**
SETTINGS
----------------------------------------------
Variable definitions, tools and mixins used
across all styling definitions.
*/
@import
"variables";
/**
VENDOR
----------------------------------------------
Imported vendor assets used by Retrospring.
*/
@import
"bootstrap",
"tempusdominus-bootstrap-4",
"font-awesome",
"nprogress",
"nprogress-bootstrap";
/**
OVERRIDES
----------------------------------------------
The imports from "overrides/" define almost barely
any style adjustments but rather override default
Bootstrap behaviour.
The largest change to regular bootstrap is the switch
to using the available CSS variables for most elements
used on the site, so theming can be done with changing
only those.
*/
@import
"overrides/alerts",
"overrides/bootstrap-datetimepicker",
"overrides/buttons",
"overrides/colors",
"overrides/card",
"overrides/dropdown",
"overrides/growls",
"overrides/inputs",
"overrides/links",
"overrides/list-group",
"overrides/minicolors",
"overrides/modal",
"overrides/navbar",
"overrides/sweet-alert";
/**
ELEMENTS
----------------------------------------------
Styles directly applied to HTML elements
*/
@import
"elements/body";
/**
COMPONENTS
----------------------------------------------
Custom components defined for Retrospring.
*/
@import
"components/announcements",
"components/answerbox",
"components/avatars",
"components/buttons",
"components/comments",
"components/container",
"components/entry",
"components/icons",
"components/inbox-entry",
"components/jumbotron",
"components/locales",
"components/notifications",
"components/profile",
"components/question",
"components/smiles",
"components/userbox";
/**
UTILITIES
----------------------------------------------
Classes used for very specific cases
*/
@import
"utilities";

View File

@ -1,305 +0,0 @@
/* all custom SCSS should go into here */
body {
overflow-y: scroll;
word-wrap: break-word;
background-color: #fafafa;
}
@import "scss/flags";
@import "scss/variable";
@import "scss/generic";
@import "scss/answerbox";
@import "scss/comments";
@import "scss/entry";
@import "scss/navbar";
@import "scss/panel";
@import "scss/user";
@import "scss/notifications";
@import "scss/groups";
@import "scss/data";
@import "scss/mobile";
.j2-page {
padding-top: 30px;
}
.centre {
text-align: center;
}
.ios-web-app {
padding-top: 1em;
}
#load-more-btn {
margin-bottom: 1.5em;
}
.j2-jumbo {
background-color: darken($navbar-inverse-bg, 10%);
color: #fff;
}
.j2-jumbo h1, .j2-jumbo h2, .j2-jumbo h3, .j2-jumbo h4, .j2-jumbo h5, .j2-jumbo h6 {
color: #fff;
}
.j2-jumbo a, .j2-jumbo a:hover {
color: #fff;
opacity: 0.6;
}
.j2-jumbo a:hover {
opacity: 1;
}
.j2-jumbo a .btn {
opacity: 1;
}
.smiles {
margin-bottom: 7px;
}
.j2-lh {
margin-top: 48px;
}
.about--moderator {
padding-left: 0px;
}
.about--moderator li {
list-style: none;
}
.about--moderator a {
text-decoration: none;
}
.about--moderator a:hover {
text-decoration: none;
}
.j2-up {
text-transform: uppercase;
}
.j2-label {
display: inline-block;
}
.j2-table {
display: table;
}
.input--center {
display: table-cell;
vertical-align: middle;
}
.sweet-overlay {
z-index: 1031;
}
#create-group {
margin-top: 5px;
}
.j2-delete {
color: $brand-danger;
text-decoration: none;
}
.j2-navbar {
margin-bottom: 0px;
}
@media (max-width: $screen-xs-max) {
.j2-col-reset {
padding-left: 0px;
padding-right: 0px;
}
}
#growls.default{
top:64px;
right:10px
}
.links {
padding-bottom: 10px;
}
.panel {
box-shadow: 0px 0px 20px rgba(0,0,0,0.1);
}
.panel-default > .panel-heading {
box-shadow: inset 0 -10px 10px -10px rgba(0,0,0,0.1);
}
.panel-default > .panel-footer {
box-shadow: inset 0 10px 10px -10px rgba(0,0,0,0.1);
}
#profile {
border-color: transparent;
border-width: 0px;
}
.panel {
border-radius: 2px;
}
.panel > .panel-heading {
border-top-left-radius: 2px;
border-top-right-radius: 2px;
}
.panel > .panel-footer {
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
}
.frontpage {
margin-top: -50px;
height: 100vh;
display: table;
}
.frontpage-scroll {
display: block;
position: absolute;
bottom: 0;
margin: 0 auto;
padding: 20px;
text-align: center;
z-index: 1000;
font-size: 32px;
width: 100%;
}
.frontpage-content {
display: table-cell;
vertical-align: middle;
}
.frontpage-features {
padding-top: 20px;
padding-bottom: 10px;
}
.features-heading {
margin-bottom: 20px;
}
.frontpage-fluid {
background-color: darken($navbar-inverse-bg, 10%);
color: #fff;
a {
color: #fff;
font-weight: bold;
&:hover {
opacity: 0.8;
}
}
p {
margin: 20px;
text-align: center;
}
}
.frontpage-heading {
margin-top: 0px;
}
#content {
padding-bottom: 30px;
}
#register {
padding: 20px;
}
.register-now {
margin: 10px;
}
.btn-register {
opacity: 1 !important;
background: transparent;
color: #fff;
border: 4px #fff solid;
border-radius: 4px;
transition: background-color .25s ease-in-out;
&:hover {
background-color: #fff;
color: darken($navbar-inverse-bg, 10%) !important;
transition: background-color .25s ease-in-out;
}
}
.lead {
margin-bottom: 3px;
}
.particle-jumbotron {
padding: 0px;
overflow: hidden;
position: relative;
width: 100%;
}
.particle-content {
position: relative;
top: 0;
padding-top: 48px;
padding-bottom: 48px;
padding-left: 30px;
padding-right: 30px;
}
#particles {
position: absolute;
width: 100%;
height: 100%;
}
.icon-showcase {
font-size: 78px;
text-align: center;
display: block;
}
.colored-icon:before {
color: $brand-primary;
}
.colored-icon {
padding-left: 3px;
padding-right: 5px;
}
.heading-showcase {
margin-top: 5px;
}
.heading-about {
margin-top: 0px;
}
.discover {
padding-top: 20px;
}
.row-eq-height {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}

View File

@ -0,0 +1,16 @@
.announcement {
width: 100%;
border-radius: 0;
text-align: center;
p {
margin-bottom: 0;
}
&__container {
position: fixed;
top: $navbar-height;
width: 100%;
z-index: 1024;
}
}

View File

@ -0,0 +1,64 @@
.answerbox {
&__question-text,
&__question-user,
&__answer-user,
&__answer-date {
margin-bottom: 0px;
overflow: hidden;
}
&__answer-date {
font-size: .8rem;
line-height: .8;
overflow: visible;
}
&__answer-text {
margin-bottom: map-get($spacers, 3);
}
&__question-user-avatar,
&__answer-user-avatar {
margin-right: map-get($spacers, 2);
border-radius: $avatar-border-radius;
}
& .text-muted a,
& .text-muted a:hover {
color: var(--muted-text);
text-decoration: none;
}
&__action {
padding-left: 0;
padding-right: map-get($spacers, 1);
& i {
font-size: 1.4rem;
vertical-align: top;
}
&:hover,
&:focus,
&:active {
text-decoration: none;
}
&[name="ab-smile"],
&[name="ab-smile-comment"] {
color: var(--primary);
&:hover {
color: var(--success);
}
&[data-action="unsmile"] {
color: var(--success);
&:hover {
color: var(--danger);
}
}
}
}
}

View File

@ -0,0 +1,12 @@
[class^="avatar-"] {
border-radius: $avatar-border-radius;
}
@each $name, $size in $avatar-sizes {
.avatar-#{$name} {
min-height: $size;
min-width: $size;
height: $size;
width: $size;
}
}

View File

@ -0,0 +1,19 @@
.btn-fab {
border-radius: 100%;
box-shadow: 0px 1px 6px rgba(0, 0, 0, 0.12), 0px 1px 6px rgba(0, 0, 0, 0.12);
margin: 0px;
padding: 3px 5px 4px 8px;
font-size: 26px;
width: 56px;
height: 56px;
transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1) 0s;
outline: medium none !important;
text-transform: uppercase;
text-decoration: none;
position: fixed;
bottom: 0px;
right: 0px;
margin-right: 7px;
margin-bottom: 7px;
z-index: 99;
}

View File

@ -0,0 +1,35 @@
.comment {
list-style-type: none;
margin-bottom: map-get($spacers, 2);
&__container {
padding-left: 0;
}
&__user,
&__content {
margin-bottom: 0px;
}
&__user-avatar {
margin-right: map-get($spacers, 2);
border-radius: $avatar-border-radius;
}
&__input-group {
position: relative;
}
&__input {
z-index: 99;
padding-right: 2.5rem;
}
&__character-count {
position: absolute;
z-index: 100;
right: .5rem;
top: .5rem;
}
}

View File

@ -0,0 +1,4 @@
.container--main {
padding-top: map-get($spacers, 3);
padding-bottom: map-get($spacers, 3);
}

View File

@ -0,0 +1,48 @@
.entry {
$this: &;
&__value {
margin-bottom: 0;
}
&__description {
color: var(--primary);
text-transform: uppercase;
font-weight: bold;
font-size: .8rem;
margin-top: 0px;
}
&--statistics {
#{$this}__value,
#{$this}__description {
display: block;
text-align: center;
}
#{$this}__value {
margin-top: map-get($spacers, 3);
}
#{$this}__description {
margin-bottom: map-get($spacers, 3);
}
}
&--users {
#{$this}__value,
#{$this}__description {
display: block;
text-align: center;
}
#{$this}__value {
font-size: 4rem;
margin-top: map-get($spacers, 3);
}
#{$this}__description {
margin-bottom: map-get($spacers, 3);
}
}
}

View File

@ -0,0 +1,4 @@
.icon--showcase {
text-align: center;
font-size: 5rem;
}

View File

@ -0,0 +1,14 @@
.inbox-entry {
&--new {
box-shadow: 0 0.125rem 0.25rem var(--primary);
.card-header {
background-color: var(--primary);
color: RGB(var(--primary-text));
.text-muted {
color: RGBA(var(--primary-text), 0.8) !important;
}
}
}
}

View File

@ -0,0 +1,74 @@
.jumbotron {
$this: &;
display: flex;
background-color: var(--primary);
color: RGB(var(--primary-text));
text-align: center;
border-radius: 0;
h1,
h2,
h3,
h4,
h5,
h6 {
color: RGB(var(--primary-text));
}
a:not(.btn) {
color: RGB(var(--primary-text));
opacity: 0.6;
&:hover {
opacity: 1;
}
.btn {
opacity: 1;
}
}
&__scroller {
display: block;
position: absolute;
bottom: 0;
margin: 0 auto;
padding: 20px;
text-align: center;
z-index: 1000;
font-size: 32px;
width: 100%;
}
&__content {
width: 100%;
align-self: center;
}
&--frontpage {
margin-top: -50px;
height: 100vh;
}
&--particles {
padding: 0px;
overflow: hidden;
position: relative;
width: 100%;
#{$this}__particles {
position: absolute;
width: 100%;
height: 100%;
}
#{$this}__content {
position: relative;
top: 0;
padding-top: 48px;
padding-bottom: 48px;
padding-left: 30px;
padding-right: 30px;
}
}
}

View File

@ -1,16 +1,15 @@
.locales {
text-align: center;
#locales-panel {
&__panel {
position: relative;
display: none;
padding: 5px;
ul {
border-top: 1px solid #aaa;
margin: 0;
padding: 0;
padding-top: 5px;
padding-top: map-get($spacers, 3);
width: 100%;
list-style: none;
display: inline-flex;
@ -18,9 +17,9 @@
flex-wrap: wrap;
align-items: center;
justify-content: center;
li {
margin: 5px 10px;
margin-top: 0;
margin: 0 5px 10px 5px;
flex: 0 0 auto;
* {

View File

@ -0,0 +1,56 @@
.notification {
&__user {
margin-top: 0;
}
&__user,
&__text {
margin-bottom: 0;
}
&__icon {
margin-right: map-get($spacers, 2);
min-width: 40px;
}
&__heading {
margin-bottom: 0;
}
&__list-heading {
margin: 0px;
text-transform: uppercase;
font-weight: bold;
color: RGB(var(--muted-text));
}
&__bell-icon:before {
font-size: 64px;
text-align: center;
display: block;
margin-bottom: 2px;
}
&-dropdown {
min-width: 400px;
& .dropdown-item:hover,
& .dropdown-item:active {
background: transparent;
color: RGB(var(--body-text));
}
}
.dropdown-item > & {
padding: 5px 10px;
}
.list-group-item {
margin-top: map-get($spacers, 2);
background-color: var(--raised-accent);
p {
margin-bottom: 0;
}
}
}

View File

@ -0,0 +1,61 @@
.profile {
&__avatar {
display: block;
width: map-get($avatar-sizes, "xl");
height: map-get($avatar-sizes, "xl");
margin: -(map-get($avatar-sizes, "xl") / 2) auto 0;
border-radius: $avatar-border-radius;
box-shadow: $box-shadow;
}
&__header-container {
margin-bottom: map-get($spacers, 3);
position: relative;
z-index: -1;
width: 100%;
overflow: hidden;
background: linear-gradient(
to top,
rgba(0, 0, 0, 0.10),
rgba(0, 0, 0, 0.10)
) var(--primary);
max-height: 440px;
}
&__header-image {
display: block;
width: 100%;
}
&__name,
&__biography,
&__website,
&__location {
margin-bottom: map-get($spacers, 3);
}
&__actions,
&__biography {
margin-top: map-get($spacers, 3);
}
&__display-name {
font-weight: bold;
font-size: 1.1em;
}
&__screen-name {
&:only-child {
@extend .profile__display-name;
}
&:not(:only-child) {
font-size: 0.9em;
color: RGB(var(--muted-text));
}
}
}
.user--banned {
text-decoration: line-through !important;
}

View File

@ -0,0 +1,14 @@
.question {
&--fixed {
position: fixed;
width: 100%;
z-index: 999;
}
&--hidden {
visibility: hidden;
position: relative;
box-shadow: none;
z-index: -1;
}
}

View File

@ -0,0 +1,27 @@
.smiles {
margin-bottom: map-get($spacers, 2);
&__user-list {
margin: 0;
padding: 0;
}
&__user-list-entry {
margin-bottom: map-get($spacers, 3);
* {
display: inline-block;
vertical-align: middle;
}
img {
height: map-get($avatar-sizes, "lg");
width: map-get($avatar-sizes, "lg");
border-radius: $avatar-border-radius;
}
span {
margin-left: 5px;
}
}
}

View File

@ -0,0 +1,39 @@
.userbox {
overflow: hidden;
&__header {
width: 100%;
height: auto;
max-height: 70px;
@include media-breakpoint-up(sm) {
max-height: 60px;
}
}
&__avatar {
display: block;
width: map-get($avatar-sizes, "lg");
height: map-get($avatar-sizes, "lg");
margin-top: -(map-get($avatar-sizes, "lg") / 2);
margin-left: auto;
margin-right: auto;
border-radius: $avatar-border-radius;
box-shadow: $box-shadow;
}
.profile__name {
display: block;
margin: map-get($spacers, 3) 0;
text-align: center;
}
.card-body {
display: flex;
flex-direction: column;
}
.profile__actions {
margin-top: auto;
}
}

View File

@ -0,0 +1,7 @@
body {
overflow-y: scroll;
word-wrap: break-word;
color: RGB(var(--body-text));
background-color: var(--background);
padding-top: $navbar-height;
}

View File

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

View File

@ -0,0 +1,11 @@
@each $color in $color-names {
.alert-#{$color} {
color: RGB(var(--#{$color}-text));
background-color: var(--#{$color});
border-color: var(--#{$color});
.alert-link {
color: RGB(var(--#{$color}-text));
}
}
}

View File

@ -0,0 +1,3 @@
.remove-native-picker::-webkit-calendar-picker-indicator{
display: none
}

View File

@ -0,0 +1,58 @@
.btn {
color: RGB(var(--body-text));
}
.btn-link:hover {
color: RGB(var(--body-text));
}
@each $color in $color-names {
.btn-#{$color} {
color: RGB(var(--#{$color}-text));
background-color: var(--#{$color});
border-color: var(--#{$color});
border-width: 0;
&:hover {
background: linear-gradient(
to top,
rgba(0, 0, 0, 0.10),
rgba(0, 0, 0, 0.10)
) var(--#{$color});
}
&:not(:disabled):not(.disabled):active,
&:not(:disabled):not(.disabled).active {
border: none;
background: linear-gradient(
to top,
rgba(0, 0, 0, 0.25),
rgba(0, 0, 0, 0.25)
) var(--#{$color});
&:focus {
background: linear-gradient(
to top,
rgba(0, 0, 0, 0.30),
rgba(0, 0, 0, 0.30)
) var(--#{$color});
box-shadow: none;
}
}
&:focus,
&:focus:hover {
background: linear-gradient(
to top,
rgba(0, 0, 0, 0.30),
rgba(0, 0, 0, 0.30)
) var(--#{$color});
box-shadow: none;
}
}
.btn-outline-#{$color} {
color: var(--#{$color});
}
}

View File

@ -0,0 +1,14 @@
.card {
margin-bottom: map-get($spacers, 3);
box-shadow: $box-shadow-sm;
background-color: var(--raised-bg);
p:only-child {
margin-bottom: 0;
}
}
.card-header,
.card-footer {
background-color: var(--raised-accent);
}

View File

@ -0,0 +1,13 @@
@each $color in $color-names {
.bg-#{$color} {
background-color: var(--#{$color}) !important;
}
.text-#{$color} {
color: var(--#{$color}) !important;
}
}
.text-muted {
color: RGB(var(--muted-text)) !important;
}

View File

@ -0,0 +1,29 @@
.dropdown-menu {
color: RGB(var(--body-text));
background-color: var(--raised-bg);
box-shadow: $box-shadow-lg;
border: none;
}
.dropdown-item {
color: RGB(var(--body-text));
&.active,
&:active,
&:active:hover {
color: RGB(var(--primary-text));
background-color: var(--primary);
}
&:hover {
background-color: var(--raised-accent);
}
}
.dropdown-divider {
border-top: 1px solid var(--raised-accent);
}
.dropdown-toggle {
-webkit-appearance: none;
}

View File

@ -0,0 +1,4 @@
#growls.default{
top:64px;
right:10px
}

View File

@ -0,0 +1,18 @@
.form-control {
background-color: var(--input-bg);
color: RGB(var(--input-text));
border: 0;
&:focus {
background-color: var(--input-bg);
color: RGB(var(--input-text));
border-color: var(--primary);
box-shadow: .5px 0 0 0.1rem var(--primary);
}
}
.input-group-text {
color: RGB(var(--body-text));
background-color: var(--raised-accent);
border: 0;
}

View File

@ -0,0 +1,7 @@
a {
color: var(--primary);
&:hover {
color: var(--primary);
}
}

View File

@ -0,0 +1,17 @@
.list-group-item {
background-color: transparent;
&.active,
&.active:hover {
background-color: var(--primary);
border-color: var(--primary);
}
}
.list-group-item-action {
color: RGB(var(--body-text));
&:hover, &:focus {
background-color: var(--raised-accent);
}
}

View File

@ -0,0 +1,10 @@
.minicolors-theme-bootstrap .minicolors-swatch {
top: 0;
left: 0;
width: 38px;
height: 38px;
border: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
border-right: 2px solid var(--raised-bg);
}

View File

@ -0,0 +1,13 @@
.modal-content {
background-color: var(--raised-bg);
border: 0;
}
.modal-header {
border-bottom: 0;
}
.modal-footer {
background-color: var(--raised-accent);
border-top: 0;
}

View File

@ -0,0 +1,50 @@
.navbar-themed {
.navbar-brand {
color: RGB(var(--primary-text));
&:hover,
&:focus {
color: RGB(var(--primary-text));
}
}
.navbar-nav {
.nav-link {
color: rgba(var(--primary-text), .5);
&:hover,
&:focus {
color: rgba(var(--primary-text), .75);
}
&.disabled {
color: rgba(var(--primary-text), .25);
}
}
.show > .nav-link,
.active > .nav-link,
.nav-link.show,
.nav-link.active {
color: RGB(var(--primary-text));
}
}
.navbar-toggler {
color: RGB(var(--primary-text));
border-color: RGB(var(--primary-text));
}
.navbar-toggler-icon {
background-image: escape-svg($navbar-dark-toggler-icon-bg);
}
.navbar-text {
color: RGB(var(--primary-text));
a,
a:hover,
a:focus {
color: RGB(var(--primary-text));
}
}
}

View File

@ -0,0 +1,3 @@
.sweet-overlay {
z-index: 1031;
}

View File

@ -1,59 +0,0 @@
.answerbox .text-muted a, .answerbox .text-muted a:hover {
color: $gray;
text-decoration: none;
}
.answerbox--img {
min-height: 32px;
min-width: 32px;
height: 32px;
width: 32px;
}
.answerbox--img-small {
min-height: 20px;
min-width: 20px;
height: 20px;
width: 20px;
}
.answerbox--question-text, .answerbox--question-user, .answerbox--answer-user, .answerbox--answer-date {
margin-bottom: 0px;
overflow: hidden;
}
.answerbox--question-text {
color: $gray;
}
.answerbox--answer-text {
font-size: 16px;
color: #000;
line-height: 1.3em;
}
.answerbox--question-text {
line-height: 1.3em;
overflow: hidden;
}
.answerbox--answer-date {
font-size: 12px;
line-height: 1.3em;
}
.answerbox [name="ab-smile"], .answerbox [name="ab-smile-comment"] {
padding: 6px 11px;
padding-left: 21px;
position: relative;
overflow: hidden;
border: none;
i.fa.fa-smile-o, i.fa.fa-frown-o, i.fa.fa-meh-o {
position: absolute;
font-size: 3em;
left: -13px;
top: -10px;
display: block;
}
}

View File

@ -1,37 +0,0 @@
.comments {
padding-left: 0;
}
.comments li {
list-style-type: none;
}
.comments .pull-right {
margin-top: -13px;
}
.comments--box {
z-index: 99;
}
.comments--count {
z-index: 0;
margin-top: -2em;
}
.comments--body {
overflow: visible !important;
}
.comments--content {
overflow: hidden;
word-break: normal;
}
.comments--content p {
margin-bottom: 0px;
}
.comments--media {
overflow: visible !important;
}

View File

@ -1,10 +0,0 @@
.data-heading {
margin-bottom: 0;
font-weight: bold;
font-size: 1.1em;
}
.data-header-preview {
height: auto;
width: 100%;
}

View File

@ -1,45 +0,0 @@
.entry-subtext {
color: $navbar-inverse-bg;
margin-top: 0px;
text-transform: uppercase;
font-weight: bold;
font-size: 80%;
}
.entry-text {
margin-bottom: 0px;
}
.entry-about {
margin-top: 0px;
}
.statistics {
.entry-text {
display: block;
text-align: center;
margin-top: 5px;
}
.entry-subtext {
text-align: center;
display: block;
margin-bottom: 5px;
}
}
.users {
.entry-text {
display: block;
text-align: center;
margin-top: 7px;
font-size: 78px;
line-height: 1;
}
.entry-subtext {
text-align: center;
display: block;
margin-bottom: 5px;
}
}

View File

@ -1,26 +0,0 @@
.user-list {
margin: 0;
padding: 0;
}
.user-list-entry-smiles {
* {
display: inline-block;
vertical-align: middle;
}
img {
height: 64px
}
span {
margin-left: 5px;
}
a:hover {
text-decoration: none;
span {
text-decoration: underline;
}
}
}

View File

@ -1,14 +0,0 @@
.groups--list .list-group-item-heading {
margin-top: 0px;
margin-bottom: 0px;
line-height: 1.3;
}
.groups--list .list-group-item {
padding: 5px 7px;
}
a[role="tab"] {
outline: 0px none;
border: none !important;
}

View File

@ -1,4 +0,0 @@
@media (max-width: 768px) {
@import "mobile/settings";
@import "mobile/profile";
}

View File

@ -1,76 +0,0 @@
.container.headerable:not(.profile--no-header) {
margin-top: 0;
padding-top: 0;
}
#profile--header:not(.profile--no-header) {
min-width: 0px;
* {
min-width: 0px;
}
}
.container.headerable {
#profile-info {
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.1);
margin-bottom: 15px;
#profile.panel, #profile-stats.panel {
box-shadow: none;
margin-bottom: 0;
}
#profile.panel {
font-size: 0;
.profile--avatar {
width: 64px;
position: relative;
top: -15px;
left: 5px;
display: inline;
}
.profile--panel-badge {
display: inline-block;
padding: 0 5px;
vertical-align: top;
width: auto;
margin-top: -15px;
&:nth-child(2) {
margin-left: 5px;
}
.fa {
font-size: 15px;
}
}
.panel-body {
font-size: 15px;
.profile--panel-name {
margin-top: -75px;
margin-left: 60px
}
}
}
#profile-stats {
border: none;
.panel-heading {
display: none;
}
.panel-body {
font-size: 0px;
padding: 0;
.row {
width: 50%;
display: inline-block;
font-size: 12px;
margin: 0;
}
}
}
}
}

View File

@ -1,11 +0,0 @@
#profile-header-media {
clear: both;
display: block;
.pull-left {
float: none !important;
clear: both;
img {
width: 100%
}
}
}

View File

@ -1,190 +0,0 @@
.navbar .nav .badge {
padding: 3px 6px 3px;
background-color: $navbar-inverse-link-active-bg;
color: #fff;
}
.navbar .nav .active .badge, li.dropdown.open a.dropdown-toggle span.badge {
padding: 3px 6px 3px;
background-color: $navbar-inverse-bg;
color: #fff;
}
.navbar--inbox-animation {
animation: animationFrames ease-in-out 1.5s;
animation-iteration-count: infinite;
-webkit-animation: animationFrames ease-in-out 1.5s;
-webkit-animation-iteration-count: infinite;
-moz-animation: animationFrames ease-in-out 1.5s;
-moz-animation-iteration-count: infinite;
-o-animation: animationFrames ease-in-out 1.5s;
-o-animation-iteration-count: infinite;
-ms-animation: animationFrames ease-in-out 1.5s;
-ms-animation-iteration-count: infinite;
}
@keyframes animationFrames{
0% {
background-color: #fff;
}
100% {
background-color: $navbar-inverse-toggle-border-color;
}
}
@-moz-keyframes animationFrames{
0% {
background-color: #fff;
}
100% {
background-color: $navbar-inverse-toggle-border-color;
}
}
@-webkit-keyframes animationFrames {
0% {
background-color: #fff;
}
100% {
background-color: $navbar-inverse-toggle-border-color;
}
}
@-o-keyframes animationFrames {
0% {
background-color: #fff;
}
100% {
background-color: $navbar-inverse-toggle-border-color;
}
}
@-ms-keyframes animationFrames {
0% {
background-color: #fff;
}
100% {
background-color: $navbar-inverse-toggle-border-color;
}
}
.btn-fab {
border-radius: 100%;
box-shadow: 0px 1px 6px rgba(0, 0, 0, 0.12), 0px 1px 6px rgba(0, 0, 0, 0.12);
margin: 0px;
padding: 3px 5px 4px 8px;
font-size: 26px;
width: 56px;
height: 56px;
transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1) 0s;
outline: medium none !important;
text-transform: uppercase;
text-decoration: none;
position: fixed;
bottom: 0px;
right: 0px;
margin-right: 7px;
margin-bottom: 7px;
z-index: 99;
}
.profile--dropdown {
min-width: 220px;
margin-top: 0px !important;
}
.profile--dropdown-media {
padding: 3px 15px;
}
.profile--dropdown-img {
min-height: 45px;
min-width: 45px;
height: 45px;
width: 45px;
}
.profile--dropdown-username {
font-weight: 700;
font-size: 1.2em;
line-height: 1.33em;
margin-top: 10px;
}
.profile--dropdown-displayname {
font-weight: 700;
font-size: 1.2em;
line-height: 1.33em;
margin-top: 2px;
}
.profile--image-dropdown > a {
padding: 0px !important;
}
.profile--image-avatar {
min-height: 50px;
min-width: 50px;
height: 50px;
width: 50px;
}
.navbar-inverse {
border: none;
}
@media (min-width: 769px) {
nav.navbar .nav > li:not(.profile--image-dropdown) {
-moz-osx-font-smoothing: grayscale;
position: relative;
&:before {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: 0;
background: $navbar-inverse-link-color;
height: 0px;
-webkit-transition-property: height;
transition-property: height;
-webkit-transition-duration: 0.3s;
transition-duration: 0.3s;
-webkit-transition-timing-function: ease-out;
transition-timing-function: ease-out;
}
&:hover, &:focus, &:active {
&:before {
height: 4px
}
}
&.active:before {
height: 4px;
}
}
}
@media (max-width: 768px) {
nav.navbar .nav {
margin-bottom: 0;
margin-top: 0;
& > li {
&.active a {
background-color: $navbar-inverse-link-active-bg-mobile !important;
}
&.dropdown.profile--image-dropdown a .visible-xs {
padding-left: 15px;
line-height: 40px;
margin: 0;
}
}
}
body {
padding-bottom: 60px;
}
}

View File

@ -1,110 +0,0 @@
.notification--img {
min-height: 32px;
min-width: 32px;
height: 32px;
width: 32px;
}
.notification--img-sm {
min-height: 18px;
min-width: 18px;
height: 18px;
width: 18px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.notification--user, .notification--text {
z-index: 99;
margin-bottom: 0px;
}
.notification--icon {
position: absolute;
right: 0px;
bottom: 0px;
padding: 5px;
font-size: 36px;
color: $gray;
opacity: 0.4;
z-index: 0;
}
.notification--dropdown {
min-width: 370px;
margin-top: 0px !important;
}
.notification--dropdown-media {
padding: 5px 10px;
}
.notification--dropdown-user, .notification--dropdown-text {
margin-bottom: 0px;
overflow: hidden;
line-height: 1.3em;
}
.notification--dropdown-user {
margin-top: 0px;
}
.notification--dropdown-img {
min-height: 32px;
min-width: 32px;
height: 32px;
width: 32px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.notification-center {
min-width: 400px;
margin-top: 0px !important;
}
.no-notifications:before {
font-size: 64px;
text-align: center;
display: block;
margin-bottom: 2px;
}
.notification--heading {
margin-bottom: 4px;
a {
border-bottom: 1px dotted $link-color;
&:hover {
text-decoration: none;
border-bottom: 1px solid $link-color;
}
}
}
.notification--list-heading {
margin: 0px;
position: absolute;
top: 1px;
left: 3px;
margin: 0px;
text-transform: uppercase;
font-weight: bold;
opacity: 0.3;
}
.notification--list-content {
line-height: 1.3em;
padding-top: 3px;
}
.notification--list {
margin: 0px;
}
.notifications--none {
padding: 10px;
}

View File

@ -1,39 +0,0 @@
.panel-primary .text-muted a, .panel-primary .text-muted a:hover {
color: #fff;
text-decoration: none;
opacity: 1;
}
.panel-primary .text-muted {
color: #fff;
opacity: 0.7;
}
.panel-primary .answerbox--question-text {
color: #fff;
}
#questions .panel-body .media {
&, .media-body {
overflow: visible;
}
}
.panel-question {
position: fixed;
border-top: 1px solid #fff;
width: 100%;
z-index: 999;
border-color: #fff;
}
.panel-question.question-hidden {
visibility: hidden;
position: relative;
box-shadow: none;
z-index: -1;
}
.answerbox--question-media, .question-media, .question-body {
overflow: visible !important;
}

View File

@ -1,142 +0,0 @@
.profile--img {
min-height: 80px;
min-width: 80px;
height: 80px;
width: 8px;
}
.profile--displayname {
font-weight: 700;
font-size: 1.2em;
margin-top: -0.165em;
line-height: 1.33em;
}
.profile--username {
font-size: 0.9em;
color: rgba(0, 0, 0, 0.4);
line-height: 1.33;
}
.profile--followtag {
margin: 0px 0px 0.2em;
}
.profile--text {
margin-bottom: 2px;
line-height: 1.5em;
margin-top: 0.65em;
}
#profile--header {
position: relative;
z-index: -1;
width: 100%;
overflow: hidden;
background-color: darken($navbar-inverse-bg, 10%);
max-height: 440px;
}
#profile--header.profile--no-header {
position: absolute;
}
.profile--panel .panel-heading {
color: $brand-primary;
border-bottom: 2px solid $brand-primary;
background-color: #fff;
text-transform: uppercase;
}
.profile--panel .panel-body {
padding-top: 0px;
}
.inbox--panel .panel-heading {
color: $brand-info;
border-bottom: 2px solid $brand-info;
background-color: #fff;
text-transform: uppercase;
}
.warning--panel .panel-heading {
color: $brand-danger;
border-bottom: 2px solid $brand-danger;
background-color: #fff;
text-transform: uppercase;
}
.profile--follow-btn {
margin-top: 5px;
}
.profile--avatar {
width: 100%;
height: auto;
border: medium none;
}
.profile--panel-badge {
width: 100%;
text-align: center;
padding-top: 0.15em;
padding-bottom: 0.15em;
text-transform: uppercase;
font-weight: bold;
margin: 0;
color: #fff;
}
$colours: danger $brand-danger,
default #BBB,
success $brand-success,
warning $brand-warning,
primary $brand-primary,
info #2980b9;
@each $colour in $colours {
.panel-badge-#{nth($colour, 1)} {
background-color: nth($colour, 2);
}
}
.user--banned {
text-decoration: line-through !important;
}
.profile--panel-push-inner:not(.profile--no-header) {
display: block;
height: 60px;
}
.profile--header-img {
display: block;
min-width: 900px;
width: 100%;
}
@media(min-width: 767px) {
.container.headerable:not(.profile--no-header) {
padding-top: 0;
margin-top: -30px;
}
}
.userbox--header {
width: 100%;
height: auto;
}
.userbox--avatar {
display: block;
margin-left: auto;
margin-right: auto;
margin-top: -60px;
border-radius: 5px;
}
.userbox--username {
text-align: center;
margin-top: 10px;
margin-bottom: 5px;
}

View File

@ -1,2 +0,0 @@
$main-color: #5e35b1;
$black: #000;

View File

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

View File

@ -57,7 +57,7 @@ class Ajax::AnswerController < AjaxController
unless inbox
# this assign is needed because shared/_answerbox relies on it, I think
@question = 1
@response[:render] = render_to_string(partial: 'shared/answerbox', locals: { a: answer, show_question: false })
@response[:render] = render_to_string(partial: 'answerbox', locals: { a: answer, show_question: false })
end
end

View File

@ -17,7 +17,7 @@ class Ajax::CommentController < AjaxController
@response[:status] = :okay
@response[:message] = I18n.t('messages.comment.create.okay')
@response[:success] = true
@response[:render] = render_to_string(partial: 'shared/comments', locals: { a: answer })
@response[:render] = render_to_string(partial: 'answerbox/comments', locals: { a: answer })
@response[:count] = answer.comment_count
end

View File

@ -41,7 +41,7 @@ class Ajax::GroupController < AjaxController
@response[:status] = :okay
@response[:success] = true
@response[:message] = I18n.t('messages.group.create.okay')
@response[:render] = render_to_string(partial: 'user/modal_group_item', locals: { group: group, user: target_user })
@response[:render] = render_to_string(partial: 'modal/group/item', locals: { group: group, user: target_user })
end
def destroy

View File

@ -107,30 +107,7 @@ class UserController < ApplicationController
def delete_theme
current_user.theme.destroy!
redirect_to edit_user_profile_path
end
# NOTE: Yes, I am storing and transmitting values as 3 byte numbers because false sense of security.
def preview_theme
attrib = params.permit([
:primary_color, :primary_text,
:danger_color, :danger_text,
:success_color, :success_text,
:warning_color, :warning_text,
:info_color, :info_text,
:default_color, :default_text,
:panel_color, :panel_text,
:link_color, :background_color,
:background_text, :background_muted,
:input_color, :input_text,
:outline_color
])
attrib.each do |k ,v|
attrib[k] = v.to_i
end
render plain: render_theme_with_context(attrib)
redirect_to edit_user_theme_path
end
def update_theme
@ -140,12 +117,12 @@ class UserController < ApplicationController
:success_color, :success_text,
:warning_color, :warning_text,
:info_color, :info_text,
:default_color, :default_text,
:panel_color, :panel_text,
:link_color, :background_color,
:background_text, :background_muted,
:input_color, :input_text,
:outline_color
:dark_color, :dark_text,
:light_color, :light_text,
:raised_background, :raised_accent,
:background_color, :body_text,
:muted_text, :input_color,
:input_text
])
if current_user.theme.nil?

View File

@ -1,2 +0,0 @@
module AnnouncementHelper
end

View File

@ -1,2 +0,0 @@
module AnswerHelper
end

View File

@ -7,6 +7,12 @@ module ApplicationHelper
class: ''
}.merge(options)
classes = [
"nav-item",
current_page?(path) ? "active" : nil,
options[:class]
].compact.join(" ")
unless options[:icon].nil?
body = "#{content_tag(:i, '', class: "mdi-#{options[:icon]}")} #{body}"
end
@ -18,7 +24,7 @@ module ApplicationHelper
}"))}"
end
content_tag(:li, link_to(body.html_safe, path), class: ("#{'active ' if current_page? path}#{options[:class]}"))
content_tag(:li, link_to(body.html_safe, path, class: "nav-link"), class: classes)
end
def list_group_item(body, path, options = {})
@ -28,6 +34,13 @@ module ApplicationHelper
class: ''
}.merge(options)
classes = [
"list-group-item",
"list-group-item-action",
current_page?(path) ? "active" : nil,
options[:class]
].compact.join(" ")
unless options[:badge].nil? or options[:badge] == 0
# TODO: make this prettier?
body << " #{
@ -36,7 +49,7 @@ module ApplicationHelper
}"))}"
end
content_tag(:a, body.html_safe, href: path, class: ("list-group-item #{'active ' if current_page? path}#{options[:class]}"))
content_tag(:a, body.html_safe, href: path, class: classes)
end
def tooltip(body, tooltip_content, placement = "bottom")
@ -48,7 +61,7 @@ module ApplicationHelper
end
def hidespan(body, hide)
content_tag(:span, body, class: "hidden-#{hide}")
content_tag(:span, body, class: hide)
end
##

View File

@ -1,2 +0,0 @@
module DiscoverHelper
end

View File

@ -1,2 +0,0 @@
module InboxHelper
end

View File

@ -0,0 +1,10 @@
# frozen_string_literal: true
module LayoutsHelper
def parent_layout(layout)
@view_flow.set(:layout, output_buffer)
output = render(file: "layouts/#{layout}")
@haml_buffer.buffer.replace output
self.output_buffer = ActionView::OutputBuffer.new(output)
end
end

View File

@ -1,2 +0,0 @@
module NotificationsHelper
end

View File

@ -1,2 +0,0 @@
module PublicHelper
end

View File

@ -1,2 +0,0 @@
module ServicesHelper
end

View File

@ -1,2 +0,0 @@
module StaticHelper
end

View File

@ -1,2 +0,0 @@
module SubscribeHelper
end

View File

@ -1,54 +1,73 @@
module ThemeHelper
def render_theme_with_context(context = {})
klass = Class.new do
def initialize(hash = {})
if hash.is_a? ApplicationRecord
x = [
:primary_color, :primary_text,
:danger_color, :danger_text,
:success_color, :success_text,
:warning_color, :warning_text,
:info_color, :info_text,
:default_color, :default_text,
:panel_color, :panel_text,
:link_color, :background_color,
:background_text, :background_muted,
:input_color, :input_text,
:outline_color
]
ATTRIBUTE_MAP = {
'primary_color' => 'primary',
'primary_text' => 'primary-text',
'danger_color' => 'danger',
'danger_text' => 'danger-text',
'warning_color' => 'warning',
'warning_text' => 'warning-text',
'info_color' => 'info',
'info_text' => 'info-text',
'success_color' => 'success',
'success_text' => 'success-text',
'dark_color' => 'dark',
'dark_text' => 'dark-text',
'light_color' => 'light',
'light_text' => 'light-text',
'raised_background' => 'raised-bg',
'raised_accent' => 'raised-accent',
'background_color' => 'background',
'body_text' => 'body-text',
'input_color' => 'input-bg',
'input_text' => 'input-text',
'muted_text' => 'muted-text'
}.freeze
x.each do |v|
next if hash[v].nil?
self.instance_variable_set "@#{v}", ('#' + ('0000000' + hash[v].to_s(16))[-6, 6])
end
elsif hash.is_a? Hash
hash.each do |k, v|
next unless v.is_a? Integer
def render_theme
theme = get_active_theme
self.instance_variable_set "@#{k}", ('#' + ('0000000' + hash[k].to_s(16))[-6, 6])
end
end
end
return unless theme
def render
style = if Rails.env == 'production'
:compressed
else
:compact
end.freeze
body = ":root {\n"
css = if $__THEME_CSS_CACHE_V1.nil?
File.read Rails.root.join 'app/views/user/theme.css.scss.erb'
else
$__THEME_CSS_CACHE_V1
end
theme.attributes.each do |k, v|
next unless ATTRIBUTE_MAP.key?(k)
erb = ERB.new css
sass = Sass::Engine.new erb.result(binding), style: style, cache: false, load_paths: [], syntax: :scss
return sass.render.to_s
if k.include? "text"
hex = get_hex_color_from_theme_value(v)
body += "\t--#{ATTRIBUTE_MAP[k]}: #{get_decimal_triplet_from_hex(hex)};\n"
else
body += "\t--#{ATTRIBUTE_MAP[k]}: ##{get_hex_color_from_theme_value(v)};\n"
end
end
return klass.new(context).render
body += "}"
content_tag(:style, body)
end
def get_active_theme
if @user&.theme
if user_signed_in?
if current_user&.show_foreign_themes?
@user.theme
else
current_user&.theme
end
else
@user.theme
end
elsif current_user&.theme
current_user.theme
end
end
def get_hex_color_from_theme_value(value)
('0000000' + value.to_s(16))[-6, 6]
end
def get_decimal_triplet_from_hex(value)
hexes = value.split(/(.{2})/).reject { |c| c.empty? }
hexes.map(&:hex).join(", ")
end
end

View File

@ -8,35 +8,15 @@ class Theme < ApplicationRecord
:success_color, :success_text,
:warning_color, :warning_text,
:info_color, :info_text,
:default_color, :default_text,
:panel_color, :panel_text,
:link_color, :background_color,
:background_text, :background_muted,
:input_color, :input_text,
:outline_color,
:dark_color, :dark_text,
:light_color, :light_text,
:raised_background, :raised_accent,
:background_color, :body_text,
:muted_text, :input_color,
:input_text,
greater_than_or_equal_to: 0, less_than_or_equal_to: 0xFFFFFF,
allow_nil: true, only_integer: true
has_attached_file :css, use_timestamp: false, s3_headers: {
'Content-Type' => 'text/css'
}, fog_file: {
content_type: 'text/css'
}
validates_attachment_content_type :css, content_type: /^text\//
before_save do
self.css = nil
style = StringIO.new(render_theme_with_context(self))
style.class.class_eval { attr_accessor :original_filename, :content_type }
style.content_type = 'text/css'
style.original_filename = 'theme.css'
self.css = style
end
def theme_color
('#' + ('0000000' + primary_color.to_s(16))[-6, 6])
end

View File

@ -1,29 +1,31 @@
- provide(:title, generate_title("Edit announcement"))
.container.j2-page
= bootstrap_form_for(@announcement, url: {action: "update"}, method: "PATCH") do |f|
- if @announcement.errors.any?
.row
.col-md-12
.alert.alert-danger
%strong
= pluralize(@announcement.errors.count, "error")
prohibited this announcement from being saved:
%ul
- @announcement.errors.full_messages.each do |err|
%li= err
.row
.col-md-12
= f.text_area :content, label: "Content"
.row
.col-md-6
= f.url_field :link_href, label: "Link URL"
.col-md-6
= f.datetime_field :link_text, label: "Link text"
.row
.col-md-6
= f.datetime_field :starts_at, label: "Start time"
.col-md-6
= f.datetime_field :ends_at, label: "End time"
.row
.col-md-12.text-right
= f.submit class: "btn btn-primary"
.container.container--main
.card
.card-body
= bootstrap_form_for(@announcement, url: {action: "update"}, method: "PATCH") do |f|
- if @announcement.errors.any?
.row
.col-md-12
.alert.alert-danger
%strong
= pluralize(@announcement.errors.count, "error")
prohibited this announcement from being saved:
%ul
- @announcement.errors.full_messages.each do |err|
%li= err
.row
.col-md-12
= f.text_area :content, label: "Content"
.row
.col-md-6
= f.url_field :link_href, label: "Link URL"
.col-md-6
= f.text_field :link_text, label: "Link text"
.row
.col-md-6
= f.datetime_field :starts_at, label: "Start time", class: "datetimepicker-input", data: { toggle: "datetimepicker", target: "#announcement_starts_at", "date-format": "YYYY-MM-DD hh:mm A" }
.col-md-6
= f.datetime_field :ends_at, label: "End time", class: "datetimepicker-input", data: { toggle: "datetimepicker", target: "#announcement_ends_at", "date-format": "YYYY-MM-DD hh:mm A" }
.row
.col-md-12.text-right
= f.submit class: "btn btn-primary"

View File

@ -1,14 +1,16 @@
- provide(:title, generate_title("Announcements"))
.container.j2-page
.container.container--main
- @announcements.each do |announcement|
.card
.card-body
.d-flex.w-100.justify-content-between
%p.mb-3= announcement.content
%small.text-muted= announcement.starts_at
.d-flex.w-100
= link_to "Edit", announcement_edit_path(id: announcement.id), class: 'btn btn-link text-primary'
= button_to "Delete", announcement_destroy_path(id: announcement.id), method: :delete, class: 'btn btn-link text-danger', confirm: 'Are you sure you want to delete this announcement?'
.row
.col-md-12
= link_to "Add new", :announcement_new, class: "btn btn-default"
- @announcements.each do |announcement|
.panel.panel-default
.panel-heading
= announcement.starts_at
.panel-body
= announcement.content
.panel-footer
= button_to "Edit", announcement_edit_path(id: announcement.id), method: :get, class: 'btn btn-link'
= button_to "Delete", announcement_destroy_path(id: announcement.id), method: :delete, class: 'btn btn-link', confirm: 'Are you sure you want to delete this announcement?'
= link_to "Add new", :announcement_new, class: "btn btn-primary"

View File

@ -1,29 +1,31 @@
- provide(:title, generate_title("Add new announcement"))
.container.j2-page
= bootstrap_form_for(@announcement, url: {action: "create"}) do |f|
- if @announcement.errors.any?
.row
.col-md-12
.alert.alert-danger
%strong
= pluralize(@announcement.errors.count, "error")
prohibited this announcement from being saved:
%ul
- @announcement.errors.full_messages.each do |err|
%li= err
.row
.col-md-12
= f.text_area :content, label: "Content"
.row
.col-md-6
= f.url_field :link_href, label: "Link URL"
.col-md-6
= f.datetime_field :link_text, label: "Link text"
.row
.col-md-6
= f.datetime_field :starts_at, label: "Start time"
.col-md-6
= f.datetime_field :ends_at, label: "End time"
.row
.col-md-12.text-right
= f.submit class: "btn btn-primary"
.container.container--main
.card
.card-body
= bootstrap_form_for(@announcement, url: {action: "create"}) do |f|
- if @announcement.errors.any?
.row
.col-md-12
.alert.alert-danger
%strong
= pluralize(@announcement.errors.count, "error")
prohibited this announcement from being saved:
%ul
- @announcement.errors.full_messages.each do |err|
%li= err
.row
.col-md-12
= f.text_area :content, label: "Content"
.row
.col-md-6
= f.url_field :link_href, label: "Link URL"
.col-md-6
= f.text_field :link_text, label: "Link text"
.row
.col-md-6
= f.datetime_field :starts_at, label: "Start time", class: "datetimepicker-input", data: { toggle: "datetimepicker", target: "#announcement_starts_at", "date-format": "YYYY-MM-DD hh:mm A" }
.col-md-6
= f.datetime_field :ends_at, label: "End time", class: "datetimepicker-input", data: { toggle: "datetimepicker", target: "#announcement_ends_at", "date-format": "YYYY-MM-DD hh:mm A" }
.row
.col-md-12.text-right
= f.submit class: "btn btn-primary"

View File

@ -0,0 +1,3 @@
- provide(:title, answer_title(@answer))
.container.container--main
= render 'answerbox', a: @answer

View File

@ -1,3 +0,0 @@
- provide(:title, answer_title(@answer))
.container.j2-page
= render 'shared/answerbox', a: @answer

View File

@ -0,0 +1,41 @@
%span.d-none.d-sm-inline.text-muted
- unless user_signed_in?
- if a.smile_count > 0
%button.btn.btn-info.btn-sm{name: 'ab-smile', disabled: true}
%i.fa.fa-smile-o
%span{id: "ab-smile-count-#{a.id}"}= a.smile_count
- if user_signed_in?
- if current_user.smiled? a
%button.btn.btn-link.answerbox__action{type: :button, name: 'ab-smile', data: { a_id: a.id, action: :unsmile }}
%i.fa.fa-fw.fa-frown-o
%span{id: "ab-smile-count-#{a.id}"}= a.smile_count
- else
%button.btn.btn-link.answerbox__action{type: :button, name: 'ab-smile', data: { a_id: a.id, action: :smile }}
%i.fa.fa-fw.fa-smile-o
%span{id: "ab-smile-count-#{a.id}"}= a.smile_count
- unless @display_all
%button.btn.btn-link.answerbox__action{type: :button, name: 'ab-comments', data: { a_id: a.id, state: :hidden }}
%i.fa.fa-fw.fa-comments
%span{id: "ab-comment-count-#{a.id}"}= a.comment_count
- if user_signed_in?
.btn-group
%button.btn.btn-default.btn-sm.dropdown-toggle{data: { toggle: :dropdown }, aria: { expanded: :false }}
%span.caret
.dropdown-menu.dropdown-menu-right{role: :menu}
- if Subscription.is_subscribed(current_user, a)
-# fun joke should subscribe?
%a.dropdown-item{href: '#', data: { a_id: a.id, action: 'ab-submarine', torpedo: "no" }}
%i.fa.fa-anchor
= t 'views.actions.unsubscribe'
- else
%a.dropdown-item{href: '#', data: { a_id: a.id, action: 'ab-submarine', torpedo: "yes" }}
%i.fa.fa-anchor
= t 'views.actions.subscribe'
- if privileged? a.user
%a.dropdown-item.text-danger{href: '#', data: { a_id: a.id, action: 'ab-destroy' }}
%i.fa.fa-trash-o
= t 'views.actions.return'
- unless a.user == current_user
%a.dropdown-item{href: '#', data: { a_id: a.id, action: 'ab-report' }}
%i.fa.fa-exclamation-triangle
= t 'views.actions.report'

View File

@ -0,0 +1,52 @@
- if a.comments.all.count == 0
= t 'views.answerbox.no_comment'
- else
%ul.comment__container
- a.comments.order(:created_at).each do |comment|
%li.comment{data: { comment_id: comment.id }}
%div{class: "ab-comment-smile-list", style: "height: 0; width: 0"}= render "modal/comment_smiles", comment: comment
.media
.pull-left
%img.comment__user-avatar.avatar-sm{src: comment.user.profile_picture.url(:medium)}
.media-body
%h6.media-heading.comment__user
= user_screen_name comment.user
%span.text-muted{title: comment.created_at, data: { toggle: :tooltip, placement: :right }}
= "#{time_ago_in_words(comment.created_at)} ago"
.comment__content
= markdown comment.content
.pull-right
%span.d-none.d-sm-inline.text-muted
- unless user_signed_in?
- if comment.smile_count > 0
%button.btn.btn-link.answerbox__action{name: 'ab-smile-comment', disabled: true}
%i.fa.fa-smile-o
%span{id: "ab-comment-smile-count-#{comment.id}"}= comment.smile_count
- if user_signed_in?
- if current_user.smiled_comment? comment
%button.btn.btn-link.answerbox__action{type: :button, name: 'ab-smile-comment', data: { c_id: comment.id, action: :unsmile }}
%i.fa.fa-fw.fa-frown-o
%span{id: "ab-comment-smile-count-#{comment.id}"}= comment.smile_count
- else
%button.btn.btn-link.answerbox__action{type: :button, name: 'ab-smile-comment', data: { c_id: comment.id, action: :smile }}
%i.fa.fa-fw.fa-smile-o
%span{id: "ab-comment-smile-count-#{comment.id}"}= comment.smile_count
.btn-group
%button.btn.btn-link.btn-sm.dropdown-toggle{data: { toggle: :dropdown }, aria: { expanded: :false }}
%span.caret
.dropdown-menu.dropdown-menu-right{role: :menu}
%a.dropdown-item{href: '#', type: :button, data: { target: "#modal-view-comment#{comment.id}-smiles", toggle: :modal}}
%i.fa.fa-smile-o
= t 'views.actions.view'
- if privileged?(comment.user) or privileged?(a.user)
%a.dropdown-item.text-danger{href: '#', data: { action: 'ab-comment-destroy', c_id: comment.id }}
%i.fa.fa-trash-o
= t 'views.actions.delete'
- unless comment.user == current_user
%a.dropdown-item{href: '#', data: { action: 'ab-comment-report', c_id: comment.id }}
%i.fa.fa-exclamation-triangle
= t 'views.acions.report'
- if user_signed_in?
.form-group.has-feedback.comment__input-group{name: 'ab-comment-new-group', data: { a_id: a.id }}
%input.form-control.comment__input{type: :text, placeholder: t('views.placeholder.comment'), name: 'ab-comment-new', data: {a_id: a.id }}
%span.text-muted.form-control-feedback.comment__character-count{id: "ab-comment-charcount-#{a.id}"} 160

View File

@ -0,0 +1,29 @@
.card-header
.media
- unless a.question.author_is_anonymous
%a.pull-left{href: show_user_profile_path(a.question.user.screen_name)}
%img.answerbox__question-user-avatar.avatar-md{src: a.question.user.profile_picture.url(:medium)}
.media-body
- if user_signed_in?
.pull-right
.btn-group
%button.btn.btn-link.btn-sm.dropdown-toggle{data: { toggle: :dropdown }, aria: { expanded: :false }}
%span.caret
.dropdown-menu.dropdown-menu-right{role: :menu}
- if current_user.mod? or a.question.user == current_user
%a.dropdown-item.text-danger{href: '#', tabindex: -1, data: { action: 'ab-question-destroy', q_id: a.question.id }}
%i.fa.fa-trash-o
= t 'views.actions.delete'
- unless a.question.user == current_user
%a.dropdown-item{href: '#', tabindex: -1, data: { action: 'ab-question-report', q_id: a.question.id }}
%i.fa.fa-exclamation-triangle
= t 'views.actions.report'
%h6.text-muted.media-heading.answerbox__question-user
= raw t('views.answerbox.asked', user: user_screen_name(a.question.user, anonymous: a.question.author_is_anonymous), time: time_tooltip(a.question))
- unless a.question.author_is_anonymous
- if a.question.answer_count > 1
·
%a{href: show_user_question_path(a.question.user.screen_name, a.question.id)}
= pluralize(a.question.answer_count, t('views.general.answer'))
.answerbox__question-text
= a.question.content

View File

@ -7,4 +7,4 @@
- else
- a.smiles.all.each do |smile|
%a{href: show_user_profile_path(smile.user.screen_name), title: smile.user.screen_name, data: { toggle: :tooltip, placement: :top, smile_id: smile.id }}
%img.img-rounded.answerbox--img-small{src: smile.user.profile_picture.url(:medium)}
%img.avatar-xs{src: smile.user.profile_picture.url(:medium)}

View File

@ -0,0 +1,39 @@
.card.answerbox{data: { id: a.id, q_id: a.question.id }}
- if @question.nil?
= render "answerbox/header", a: a
.card-body
- if @display_all.nil?
.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)}
= t 'views.answerbox.read'
- else
.answerbox__answer-text
= markdown a.content
- if @user.nil?
.row
.col.col-sm-4.col-md-6.text-left.text-muted
.media
.pull-left
%a{href: show_user_profile_path(a.user.screen_name)}
%img.answerbox__answer-user-avatar.avatar-sm{src: a.user.profile_picture.url(:medium)}
.media-body
%h6.media-heading.answerbox__answer-user
= raw t('views.answerbox.answered', hide: hidespan(t('views.answerbox.hide'), "d-none d-sm-inline"), user: user_screen_name(a.user))
.answerbox__answer-date
= link_to(raw(t('views.answerbox.time', time: time_tooltip(a))), show_user_answer_path(a.user.screen_name, a.id))
.col.col-sm-8.col-md-6.text-right
= render 'answerbox/actions', a: a
- else
.row
.col-4.col-sm-4.col-md-6.text-left.text-muted
%i.fa.fa-clock-o
= link_to(raw(t('views.answerbox.time', time: time_tooltip(a))), show_user_answer_path(a.user.screen_name, a.id))
.col-8.col-sm-8.col-md-6.text-right
= render 'answerbox/actions', a: a
.card-footer{id: "ab-comments-section-#{a.id}", style: @display_all.nil? ? 'display: none' : nil }
%div{id: "ab-smiles-#{a.id}"}= render 'answerbox/smiles', a: a
%div{id: "ab-comments-#{a.id}"}= render 'answerbox/comments', a: a

View File

@ -1,23 +1,19 @@
.panel.panel-default
.panel-heading
%h3.panel-title
- if @user.motivation_header.blank?
= t 'views.questionbox.title'
- else
= @user.motivation_header
.panel-body
.card
.card-header
- if @user.motivation_header.blank?
= t 'views.questionbox.title'
- else
= @user.motivation_header
.card-body
- if @user.banned?
.row
.col-xs-12.text-center
%strong= t 'views.questionbox.banned'
.text-center
%strong= t 'views.questionbox.banned'
- else
- if user_signed_in? or @user.privacy_allow_anonymous_questions?
#question-box
.row
.col-xs-12
%textarea.form-control{:name => "qb-question", :placeholder => t('views.placeholder.question')}
%textarea.form-control{:name => "qb-question", :placeholder => t('views.placeholder.question')}
.row{:style => "padding-top: 5px; padding-left: 5px; padding-right: 5px;"}
.col-xs-6
.col-6
- if user_signed_in?
- if @user.privacy_allow_anonymous_questions?
%input{:name => "qb-anonymous", :type => "checkbox"}/
@ -25,27 +21,23 @@
%br/
- else
%input{:name => "qb-anonymous", :type => "hidden", :value => "false"}/
.col-xs-6
.col-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: t('views.questionbox.load'), promote: user_signed_in? ? "false" : "true" }} Ask
- unless user_signed_in?
- if @user.privacy_allow_anonymous_questions?
#question-box-promote.row{:style => "display: none;"}
#question-box-promote{:style => "display: none;"}
.row
.col-xs-12.text-center
.col-12.text-center
%strong= t 'views.questionbox.promote.message'
.row
.col-sm-1
.col-sm-5
.col-sm-5.offset-sm-1
%button#create-account.btn.btn-block.btn-primary= t 'views.questionbox.promote.create'
.col-sm-5
%button#new-question.btn.btn-block.btn-default= t 'views.questionbox.promote.another'
.col-sm-1
.row
.col-sm-1
.col-xs-12.col-sm-10.text-center
.col-xs-12.col-sm-10.offset-sm-1.text-center
%small= t('views.questionbox.promote.join', app_title: APP_CONFIG['site_name'])
.col-sm-1
- else
%p= raw t 'views.questionbox.required', signup: link_to(t('views.sessions.new'),new_user_registration_path)

View File

@ -1,11 +1,15 @@
- provide(:title, generate_title("Resend confirmation instructions"))
.container
%h1 Resend confirmation instructions
= bootstrap_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f|
= devise_error_messages!
.row
.col-sm-8.offset-sm-2
.card.mt-3
.card-body
%h1 Resend confirmation instructions
= bootstrap_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f|
= devise_error_messages!
= f.text_field :screen_name, autofocus: true, label: "User name"
= f.submit "Resend confirmation instructions"
= f.text_field :screen_name, autofocus: true, label: "User name"
= f.submit "Resend confirmation instructions", class: "btn btn-primary mb-3"
= render "devise/shared/links"
= render "devise/shared/links"
= render "shared/links"

View File

@ -1,15 +1,19 @@
- provide(:title, generate_title("Reset Password"))
.container
%h1 Change your password
= bootstrap_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f|
= devise_error_messages!
.row
.col-sm-4.offset-sm-4
.card.mt-3
.card-body
%h1 Change your password
= bootstrap_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f|
= devise_error_messages!
= f.hidden_field :reset_password_token
= f.hidden_field :reset_password_token
= f.password_field :password, autofocus: true, autocomplete: "off", label: "New password"
= f.password_field :password_confirmation, autocomplete: "off", label: "Confirm new password"
= f.password_field :password, autofocus: true, autocomplete: "off", label: "New password"
= f.password_field :password_confirmation, autocomplete: "off", label: "Confirm new password"
= f.submit "Change my password"
= f.submit "Change my password"
= render "devise/shared/links"
= render "devise/shared/links"
= render "shared/links"

View File

@ -1,11 +1,15 @@
- provide(:title, generate_title("Forgot your Password?"))
.container
%h1 Forgot your password?
= bootstrap_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f|
= devise_error_messages!
.row
.col-sm-8.offset-sm-2
.card.mt-3
.card-body
%h1 Forgot your password?
= bootstrap_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f|
= devise_error_messages!
= f.email_field :email, autofocus: true, label: "Email address"
= f.submit "Send me password reset instructions"
= f.email_field :email, autofocus: true, label: "Email address"
= f.submit "Send me password reset instructions", class: "btn btn-primary mb-3"
= render "devise/shared/links"
= render "devise/shared/links"
= render "shared/links"

View File

@ -1,27 +1,4 @@
- case resource_name
- when :user
= render 'user/account'
- else
.container
%h1 Edit #{resource_name.to_s.humanize}
= bootstrap_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
= devise_error_messages!
= render "settings/account"
= f.text_field :screen_name, autofocus: true, label: "User name"
= f.email_field :email, label: "Email address"
- if devise_mapping.confirmable? && resource.pending_reconfirmation?
%div
Currently waiting confirmation for: #{resource.unconfirmed_email}
= f.password_field :password, autocomplete: "off", label: "Password", help: "Leave this blank if you don't want to change it"
= f.password_field :password_confirmation, autocomplete: "off", label: "Confirm password"
= f.password_field :current_password, autocomplete: "off", label: "Current password", help: "We need your current password to confirm your changes"
= f.submit "Update"
%p
=button_to "Delete my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete, class: "btn btn-danger btn-sm"
= link_to "Back", :back
= render 'shared/links'
- provide(:title, generate_title("Account Settings"))
- parent_layout "user/settings"

View File

@ -1,18 +1,21 @@
- provide(:title, generate_title("Sign Up"))
.container
%h1= t('views.sessions.new')
.row
.col-sm-8.offset-sm-2
.card.mt-3
.card-body
%h1= t('views.sessions.new')
= bootstrap_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
= devise_error_messages!
= bootstrap_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
= devise_error_messages!
= f.text_field :screen_name, autofocus: true, label: t('views.settings.account.username')
= f.email_field :email, autofocus: false, label: t('views.settings.account.email')
= f.text_field :screen_name, autofocus: true, label: t('views.settings.account.username')
= f.email_field :email, autofocus: false, label: t('views.settings.account.email')
= f.password_field :password, autocomplete: "off", label: t('views.settings.account.password')
= f.password_field :password_confirmation, autocomplete: "off", label: t('views.settings.account.password_confirm')
= f.password_field :password, autocomplete: "off", label: t('views.settings.account.password')
= f.password_field :password_confirmation, autocomplete: "off", label: t('views.settings.account.password_confirm')
%p= raw t('views.sessions.info', terms: link_to(t('views.general.terms'), terms_path))
= f.submit "Sign up", class: "btn btn-primary mb-3"
%p= raw t('views.sessions.info', terms: link_to(t('views.general.terms'), terms_path))
= f.submit "Sign up"
= render "devise/shared/links"
= render "devise/shared/links"
= render 'shared/links'

View File

@ -1,17 +1,20 @@
- provide(:title, generate_title("Sign In"))
.container
%h1= t('views.sessions.create')
= render 'layouts/messages'
.row
.col-sm-4.offset-sm-4
= render 'layouts/messages'
.card.mt-3
.card-body
%h1.mb-3.mt-0= t('views.sessions.create')
= bootstrap_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
= bootstrap_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
= f.text_field :login, autofocus: true, label: t('views.settings.account.username')
= f.password_field :password, autocomplete: "off", label: t('views.settings.account.password')
= f.text_field :login, autofocus: true, label: t('views.settings.account.username')
= f.password_field :password, autocomplete: "off", label: t('views.settings.account.password')
- if devise_mapping.rememberable?
= f.check_box :remember_me
- if devise_mapping.rememberable?
= f.check_box :remember_me
= f.submit t('views.sessions.create'), class: "btn btn-primary mt-3 mb-3"
= f.submit t('views.sessions.create')
= render "devise/shared/links"
= render "devise/shared/links"
= render "shared/links"

View File

@ -1,3 +1,3 @@
.tab-pane.active.fade.in{role: "tabpanel", id: "answers"}
.tab-pane.active.fade.show{role: "tabpanel", id: "answers"}
- answers.each do |a|
= render 'shared/answerbox', a: a
= render 'answerbox', a: a

View File

@ -1,3 +1,3 @@
.tab-pane.fade{role: "tabpanel", id: "comments"}
- comments.each do |a|
= render 'shared/answerbox', a: a
= render 'answerbox', a: a

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