`, and ``.
-$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;
-}
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
new file mode 100644
index 00000000..768706ef
--- /dev/null
+++ b/app/assets/stylesheets/application.scss
@@ -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";
diff --git a/app/assets/stylesheets/base.css.scss b/app/assets/stylesheets/base.css.scss
deleted file mode 100644
index 54ea3ee1..00000000
--- a/app/assets/stylesheets/base.css.scss
+++ /dev/null
@@ -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;
-}
diff --git a/app/assets/stylesheets/components/_announcements.scss b/app/assets/stylesheets/components/_announcements.scss
new file mode 100644
index 00000000..f69e2c5b
--- /dev/null
+++ b/app/assets/stylesheets/components/_announcements.scss
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/components/_answerbox.scss b/app/assets/stylesheets/components/_answerbox.scss
new file mode 100644
index 00000000..d13f672f
--- /dev/null
+++ b/app/assets/stylesheets/components/_answerbox.scss
@@ -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);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/components/_avatars.scss b/app/assets/stylesheets/components/_avatars.scss
new file mode 100644
index 00000000..6d2bf1cf
--- /dev/null
+++ b/app/assets/stylesheets/components/_avatars.scss
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/components/_buttons.scss b/app/assets/stylesheets/components/_buttons.scss
new file mode 100644
index 00000000..142b73fb
--- /dev/null
+++ b/app/assets/stylesheets/components/_buttons.scss
@@ -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;
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/components/_comments.scss b/app/assets/stylesheets/components/_comments.scss
new file mode 100644
index 00000000..70d35759
--- /dev/null
+++ b/app/assets/stylesheets/components/_comments.scss
@@ -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;
+ }
+}
+
diff --git a/app/assets/stylesheets/components/_container.scss b/app/assets/stylesheets/components/_container.scss
new file mode 100644
index 00000000..08d9bf08
--- /dev/null
+++ b/app/assets/stylesheets/components/_container.scss
@@ -0,0 +1,4 @@
+.container--main {
+ padding-top: map-get($spacers, 3);
+ padding-bottom: map-get($spacers, 3);
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/components/_entry.scss b/app/assets/stylesheets/components/_entry.scss
new file mode 100644
index 00000000..50f36a47
--- /dev/null
+++ b/app/assets/stylesheets/components/_entry.scss
@@ -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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/components/_icons.scss b/app/assets/stylesheets/components/_icons.scss
new file mode 100644
index 00000000..ef1db1ef
--- /dev/null
+++ b/app/assets/stylesheets/components/_icons.scss
@@ -0,0 +1,4 @@
+.icon--showcase {
+ text-align: center;
+ font-size: 5rem;
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/components/_inbox-entry.scss b/app/assets/stylesheets/components/_inbox-entry.scss
new file mode 100644
index 00000000..3f549443
--- /dev/null
+++ b/app/assets/stylesheets/components/_inbox-entry.scss
@@ -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;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/components/_jumbotron.scss b/app/assets/stylesheets/components/_jumbotron.scss
new file mode 100644
index 00000000..a0f388f1
--- /dev/null
+++ b/app/assets/stylesheets/components/_jumbotron.scss
@@ -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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/scss/flags.scss b/app/assets/stylesheets/components/_locales.scss
similarity index 79%
rename from app/assets/stylesheets/scss/flags.scss
rename to app/assets/stylesheets/components/_locales.scss
index cee8e6e2..48a6ff5c 100644
--- a/app/assets/stylesheets/scss/flags.scss
+++ b/app/assets/stylesheets/components/_locales.scss
@@ -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;
* {
diff --git a/app/assets/stylesheets/components/_notifications.scss b/app/assets/stylesheets/components/_notifications.scss
new file mode 100644
index 00000000..d470978a
--- /dev/null
+++ b/app/assets/stylesheets/components/_notifications.scss
@@ -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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/components/_profile.scss b/app/assets/stylesheets/components/_profile.scss
new file mode 100644
index 00000000..726bef72
--- /dev/null
+++ b/app/assets/stylesheets/components/_profile.scss
@@ -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;
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/components/_question.scss b/app/assets/stylesheets/components/_question.scss
new file mode 100644
index 00000000..3b2af72b
--- /dev/null
+++ b/app/assets/stylesheets/components/_question.scss
@@ -0,0 +1,14 @@
+.question {
+ &--fixed {
+ position: fixed;
+ width: 100%;
+ z-index: 999;
+ }
+
+ &--hidden {
+ visibility: hidden;
+ position: relative;
+ box-shadow: none;
+ z-index: -1;
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/components/_smiles.scss b/app/assets/stylesheets/components/_smiles.scss
new file mode 100644
index 00000000..fa1aceae
--- /dev/null
+++ b/app/assets/stylesheets/components/_smiles.scss
@@ -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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/components/_userbox.scss b/app/assets/stylesheets/components/_userbox.scss
new file mode 100644
index 00000000..42d7463a
--- /dev/null
+++ b/app/assets/stylesheets/components/_userbox.scss
@@ -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;
+ }
+}
diff --git a/app/assets/stylesheets/elements/_body.scss b/app/assets/stylesheets/elements/_body.scss
new file mode 100644
index 00000000..92aa0578
--- /dev/null
+++ b/app/assets/stylesheets/elements/_body.scss
@@ -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;
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/inbox.css.scss b/app/assets/stylesheets/inbox.css.scss
deleted file mode 100644
index 07a9c997..00000000
--- a/app/assets/stylesheets/inbox.css.scss
+++ /dev/null
@@ -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/
diff --git a/app/assets/stylesheets/overrides/_alerts.scss b/app/assets/stylesheets/overrides/_alerts.scss
new file mode 100644
index 00000000..8e9c2073
--- /dev/null
+++ b/app/assets/stylesheets/overrides/_alerts.scss
@@ -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));
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/overrides/_bootstrap-datetimepicker.scss b/app/assets/stylesheets/overrides/_bootstrap-datetimepicker.scss
new file mode 100644
index 00000000..c7a66d09
--- /dev/null
+++ b/app/assets/stylesheets/overrides/_bootstrap-datetimepicker.scss
@@ -0,0 +1,3 @@
+.remove-native-picker::-webkit-calendar-picker-indicator{
+ display: none
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/overrides/_buttons.scss b/app/assets/stylesheets/overrides/_buttons.scss
new file mode 100644
index 00000000..4bfe6cb4
--- /dev/null
+++ b/app/assets/stylesheets/overrides/_buttons.scss
@@ -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});
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/overrides/_card.scss b/app/assets/stylesheets/overrides/_card.scss
new file mode 100644
index 00000000..2b31a72a
--- /dev/null
+++ b/app/assets/stylesheets/overrides/_card.scss
@@ -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);
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/overrides/_colors.scss b/app/assets/stylesheets/overrides/_colors.scss
new file mode 100644
index 00000000..400c8d0d
--- /dev/null
+++ b/app/assets/stylesheets/overrides/_colors.scss
@@ -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;
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/overrides/_dropdown.scss b/app/assets/stylesheets/overrides/_dropdown.scss
new file mode 100644
index 00000000..6e38de4f
--- /dev/null
+++ b/app/assets/stylesheets/overrides/_dropdown.scss
@@ -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;
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/overrides/_growls.scss b/app/assets/stylesheets/overrides/_growls.scss
new file mode 100644
index 00000000..0e906324
--- /dev/null
+++ b/app/assets/stylesheets/overrides/_growls.scss
@@ -0,0 +1,4 @@
+#growls.default{
+ top:64px;
+ right:10px
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/overrides/_inputs.scss b/app/assets/stylesheets/overrides/_inputs.scss
new file mode 100644
index 00000000..bb2c75ce
--- /dev/null
+++ b/app/assets/stylesheets/overrides/_inputs.scss
@@ -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;
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/overrides/_links.scss b/app/assets/stylesheets/overrides/_links.scss
new file mode 100644
index 00000000..34bbae92
--- /dev/null
+++ b/app/assets/stylesheets/overrides/_links.scss
@@ -0,0 +1,7 @@
+a {
+ color: var(--primary);
+
+ &:hover {
+ color: var(--primary);
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/overrides/_list-group.scss b/app/assets/stylesheets/overrides/_list-group.scss
new file mode 100644
index 00000000..88aee252
--- /dev/null
+++ b/app/assets/stylesheets/overrides/_list-group.scss
@@ -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);
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/overrides/_minicolors.scss b/app/assets/stylesheets/overrides/_minicolors.scss
new file mode 100644
index 00000000..bcfe2265
--- /dev/null
+++ b/app/assets/stylesheets/overrides/_minicolors.scss
@@ -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);
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/overrides/_modal.scss b/app/assets/stylesheets/overrides/_modal.scss
new file mode 100644
index 00000000..04773c30
--- /dev/null
+++ b/app/assets/stylesheets/overrides/_modal.scss
@@ -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;
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/overrides/_navbar.scss b/app/assets/stylesheets/overrides/_navbar.scss
new file mode 100644
index 00000000..f5959ff0
--- /dev/null
+++ b/app/assets/stylesheets/overrides/_navbar.scss
@@ -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));
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/overrides/_sweet-alert.scss b/app/assets/stylesheets/overrides/_sweet-alert.scss
new file mode 100644
index 00000000..cd16be18
--- /dev/null
+++ b/app/assets/stylesheets/overrides/_sweet-alert.scss
@@ -0,0 +1,3 @@
+.sweet-overlay {
+ z-index: 1031;
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/scss/answerbox.scss b/app/assets/stylesheets/scss/answerbox.scss
deleted file mode 100644
index 362efe92..00000000
--- a/app/assets/stylesheets/scss/answerbox.scss
+++ /dev/null
@@ -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;
- }
-}
diff --git a/app/assets/stylesheets/scss/comments.scss b/app/assets/stylesheets/scss/comments.scss
deleted file mode 100644
index 08b73e2d..00000000
--- a/app/assets/stylesheets/scss/comments.scss
+++ /dev/null
@@ -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;
-}
\ No newline at end of file
diff --git a/app/assets/stylesheets/scss/data.scss b/app/assets/stylesheets/scss/data.scss
deleted file mode 100644
index c4aa26c0..00000000
--- a/app/assets/stylesheets/scss/data.scss
+++ /dev/null
@@ -1,10 +0,0 @@
-.data-heading {
- margin-bottom: 0;
- font-weight: bold;
- font-size: 1.1em;
-}
-
-.data-header-preview {
- height: auto;
- width: 100%;
-}
diff --git a/app/assets/stylesheets/scss/entry.scss b/app/assets/stylesheets/scss/entry.scss
deleted file mode 100644
index 6dda7023..00000000
--- a/app/assets/stylesheets/scss/entry.scss
+++ /dev/null
@@ -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;
- }
-}
\ No newline at end of file
diff --git a/app/assets/stylesheets/scss/generic.scss b/app/assets/stylesheets/scss/generic.scss
deleted file mode 100644
index f4ecb99c..00000000
--- a/app/assets/stylesheets/scss/generic.scss
+++ /dev/null
@@ -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;
- }
- }
-}
diff --git a/app/assets/stylesheets/scss/groups.scss b/app/assets/stylesheets/scss/groups.scss
deleted file mode 100644
index f8910279..00000000
--- a/app/assets/stylesheets/scss/groups.scss
+++ /dev/null
@@ -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;
-}
\ No newline at end of file
diff --git a/app/assets/stylesheets/scss/mobile.scss b/app/assets/stylesheets/scss/mobile.scss
deleted file mode 100644
index 8279eb21..00000000
--- a/app/assets/stylesheets/scss/mobile.scss
+++ /dev/null
@@ -1,4 +0,0 @@
-@media (max-width: 768px) {
- @import "mobile/settings";
- @import "mobile/profile";
-}
diff --git a/app/assets/stylesheets/scss/mobile/profile.scss b/app/assets/stylesheets/scss/mobile/profile.scss
deleted file mode 100644
index 3799ba3b..00000000
--- a/app/assets/stylesheets/scss/mobile/profile.scss
+++ /dev/null
@@ -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;
- }
- }
- }
- }
-}
diff --git a/app/assets/stylesheets/scss/mobile/settings.scss b/app/assets/stylesheets/scss/mobile/settings.scss
deleted file mode 100644
index a9b4f2cf..00000000
--- a/app/assets/stylesheets/scss/mobile/settings.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-#profile-header-media {
- clear: both;
- display: block;
- .pull-left {
- float: none !important;
- clear: both;
- img {
- width: 100%
- }
- }
-}
diff --git a/app/assets/stylesheets/scss/navbar.scss b/app/assets/stylesheets/scss/navbar.scss
deleted file mode 100644
index d6ee5188..00000000
--- a/app/assets/stylesheets/scss/navbar.scss
+++ /dev/null
@@ -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;
- }
-}
diff --git a/app/assets/stylesheets/scss/notifications.scss b/app/assets/stylesheets/scss/notifications.scss
deleted file mode 100644
index e8be9bcf..00000000
--- a/app/assets/stylesheets/scss/notifications.scss
+++ /dev/null
@@ -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;
-}
\ No newline at end of file
diff --git a/app/assets/stylesheets/scss/panel.scss b/app/assets/stylesheets/scss/panel.scss
deleted file mode 100644
index 91c39e4f..00000000
--- a/app/assets/stylesheets/scss/panel.scss
+++ /dev/null
@@ -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;
-}
diff --git a/app/assets/stylesheets/scss/user.scss b/app/assets/stylesheets/scss/user.scss
deleted file mode 100644
index 0f0adbfb..00000000
--- a/app/assets/stylesheets/scss/user.scss
+++ /dev/null
@@ -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;
-}
diff --git a/app/assets/stylesheets/scss/variable.scss b/app/assets/stylesheets/scss/variable.scss
deleted file mode 100644
index 56c04a46..00000000
--- a/app/assets/stylesheets/scss/variable.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-$main-color: #5e35b1;
-$black: #000;
diff --git a/app/assets/stylesheets/user.css.scss b/app/assets/stylesheets/user.css.scss
deleted file mode 100644
index 7c5eca9c..00000000
--- a/app/assets/stylesheets/user.css.scss
+++ /dev/null
@@ -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/
diff --git a/app/controllers/ajax/answer_controller.rb b/app/controllers/ajax/answer_controller.rb
index 05a7ba7e..37bc1ec0 100644
--- a/app/controllers/ajax/answer_controller.rb
+++ b/app/controllers/ajax/answer_controller.rb
@@ -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
diff --git a/app/controllers/ajax/comment_controller.rb b/app/controllers/ajax/comment_controller.rb
index 283da8d7..9ba83fcc 100644
--- a/app/controllers/ajax/comment_controller.rb
+++ b/app/controllers/ajax/comment_controller.rb
@@ -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
diff --git a/app/controllers/ajax/group_controller.rb b/app/controllers/ajax/group_controller.rb
index 919340aa..352147ef 100644
--- a/app/controllers/ajax/group_controller.rb
+++ b/app/controllers/ajax/group_controller.rb
@@ -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
diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb
index 931d113c..9804a61e 100644
--- a/app/controllers/user_controller.rb
+++ b/app/controllers/user_controller.rb
@@ -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?
diff --git a/app/helpers/announcement_helper.rb b/app/helpers/announcement_helper.rb
deleted file mode 100644
index b71ddc14..00000000
--- a/app/helpers/announcement_helper.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-module AnnouncementHelper
-end
diff --git a/app/helpers/answer_helper.rb b/app/helpers/answer_helper.rb
deleted file mode 100644
index 3b07ef9a..00000000
--- a/app/helpers/answer_helper.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-module AnswerHelper
-end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 3f9e1977..d87d9704 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -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
##
diff --git a/app/helpers/discover_helper.rb b/app/helpers/discover_helper.rb
deleted file mode 100644
index 6d7d2ed7..00000000
--- a/app/helpers/discover_helper.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-module DiscoverHelper
-end
diff --git a/app/helpers/inbox_helper.rb b/app/helpers/inbox_helper.rb
deleted file mode 100644
index 4c6ced5c..00000000
--- a/app/helpers/inbox_helper.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-module InboxHelper
-end
diff --git a/app/helpers/layouts_helper.rb b/app/helpers/layouts_helper.rb
new file mode 100644
index 00000000..20784840
--- /dev/null
+++ b/app/helpers/layouts_helper.rb
@@ -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
\ No newline at end of file
diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb
deleted file mode 100644
index 7342393a..00000000
--- a/app/helpers/notifications_helper.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-module NotificationsHelper
-end
diff --git a/app/helpers/public_helper.rb b/app/helpers/public_helper.rb
deleted file mode 100644
index 0d8e188e..00000000
--- a/app/helpers/public_helper.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-module PublicHelper
-end
diff --git a/app/helpers/services_helper.rb b/app/helpers/services_helper.rb
deleted file mode 100644
index de584353..00000000
--- a/app/helpers/services_helper.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-module ServicesHelper
-end
diff --git a/app/helpers/static_helper.rb b/app/helpers/static_helper.rb
deleted file mode 100644
index 8cfc9af4..00000000
--- a/app/helpers/static_helper.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-module StaticHelper
-end
diff --git a/app/helpers/subscribe_helper.rb b/app/helpers/subscribe_helper.rb
deleted file mode 100644
index e30187f5..00000000
--- a/app/helpers/subscribe_helper.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-module SubscribeHelper
-end
diff --git a/app/helpers/theme_helper.rb b/app/helpers/theme_helper.rb
index 1202588c..13f74a0a 100644
--- a/app/helpers/theme_helper.rb
+++ b/app/helpers/theme_helper.rb
@@ -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
diff --git a/app/models/theme.rb b/app/models/theme.rb
index 74700a54..bcdc5d05 100644
--- a/app/models/theme.rb
+++ b/app/models/theme.rb
@@ -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
diff --git a/app/views/announcement/edit.html.haml b/app/views/announcement/edit.html.haml
index ee7eb3ba..45f54008 100644
--- a/app/views/announcement/edit.html.haml
+++ b/app/views/announcement/edit.html.haml
@@ -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"
diff --git a/app/views/announcement/index.html.haml b/app/views/announcement/index.html.haml
index 0d117c83..bb8c3616 100644
--- a/app/views/announcement/index.html.haml
+++ b/app/views/announcement/index.html.haml
@@ -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?'
\ No newline at end of file
+ = link_to "Add new", :announcement_new, class: "btn btn-primary"
\ No newline at end of file
diff --git a/app/views/announcement/new.html.haml b/app/views/announcement/new.html.haml
index 25942f28..69e61d2c 100644
--- a/app/views/announcement/new.html.haml
+++ b/app/views/announcement/new.html.haml
@@ -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"
diff --git a/app/views/answer/show.haml b/app/views/answer/show.haml
new file mode 100644
index 00000000..f1096f09
--- /dev/null
+++ b/app/views/answer/show.haml
@@ -0,0 +1,3 @@
+- provide(:title, answer_title(@answer))
+.container.container--main
+ = render 'answerbox', a: @answer
\ No newline at end of file
diff --git a/app/views/answer/show.html.haml b/app/views/answer/show.html.haml
deleted file mode 100644
index 9c1b3f1d..00000000
--- a/app/views/answer/show.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-- provide(:title, answer_title(@answer))
-.container.j2-page
- = render 'shared/answerbox', a: @answer
diff --git a/app/views/answerbox/_actions.haml b/app/views/answerbox/_actions.haml
new file mode 100644
index 00000000..6f04c009
--- /dev/null
+++ b/app/views/answerbox/_actions.haml
@@ -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'
\ No newline at end of file
diff --git a/app/views/answerbox/_comments.haml b/app/views/answerbox/_comments.haml
new file mode 100644
index 00000000..4e635a3d
--- /dev/null
+++ b/app/views/answerbox/_comments.haml
@@ -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
diff --git a/app/views/answerbox/_header.haml b/app/views/answerbox/_header.haml
new file mode 100644
index 00000000..d4d7c8ab
--- /dev/null
+++ b/app/views/answerbox/_header.haml
@@ -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
\ No newline at end of file
diff --git a/app/views/shared/_smiles.html.haml b/app/views/answerbox/_smiles.haml
similarity index 78%
rename from app/views/shared/_smiles.html.haml
rename to app/views/answerbox/_smiles.haml
index 119086a6..ef9a8a4f 100644
--- a/app/views/shared/_smiles.html.haml
+++ b/app/views/answerbox/_smiles.haml
@@ -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)}
\ No newline at end of file
+ %img.avatar-xs{src: smile.user.profile_picture.url(:medium)}
\ No newline at end of file
diff --git a/app/views/application/_answerbox.haml b/app/views/application/_answerbox.haml
new file mode 100644
index 00000000..ed8a260d
--- /dev/null
+++ b/app/views/application/_answerbox.haml
@@ -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
\ No newline at end of file
diff --git a/app/views/shared/_questionbox.html.haml b/app/views/application/_questionbox.haml
similarity index 66%
rename from app/views/shared/_questionbox.html.haml
rename to app/views/application/_questionbox.haml
index 30ecb92f..78f0cd2d 100644
--- a/app/views/shared/_questionbox.html.haml
+++ b/app/views/application/_questionbox.haml
@@ -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)
diff --git a/app/views/devise/confirmations/new.html.haml b/app/views/devise/confirmations/new.html.haml
index c6a533a1..da395950 100644
--- a/app/views/devise/confirmations/new.html.haml
+++ b/app/views/devise/confirmations/new.html.haml
@@ -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"
diff --git a/app/views/devise/passwords/edit.html.haml b/app/views/devise/passwords/edit.html.haml
index d773a8c1..7c052384 100644
--- a/app/views/devise/passwords/edit.html.haml
+++ b/app/views/devise/passwords/edit.html.haml
@@ -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"
diff --git a/app/views/devise/passwords/new.html.haml b/app/views/devise/passwords/new.html.haml
index ce106ef3..b3578cfe 100644
--- a/app/views/devise/passwords/new.html.haml
+++ b/app/views/devise/passwords/new.html.haml
@@ -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"
diff --git a/app/views/devise/registrations/edit.html.haml b/app/views/devise/registrations/edit.html.haml
index e6ab70f8..77d692f8 100644
--- a/app/views/devise/registrations/edit.html.haml
+++ b/app/views/devise/registrations/edit.html.haml
@@ -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"
diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml
index 67b09af8..7ed1f434 100644
--- a/app/views/devise/registrations/new.html.haml
+++ b/app/views/devise/registrations/new.html.haml
@@ -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'
diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml
index 3ef2cdf2..c6d12ce8 100644
--- a/app/views/devise/sessions/new.html.haml
+++ b/app/views/devise/sessions/new.html.haml
@@ -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"
diff --git a/app/views/discover/_tab_answers.html.haml b/app/views/discover/_tab_answers.html.haml
index ed290d50..0738798d 100644
--- a/app/views/discover/_tab_answers.html.haml
+++ b/app/views/discover/_tab_answers.html.haml
@@ -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
diff --git a/app/views/discover/_tab_discussed.html.haml b/app/views/discover/_tab_discussed.html.haml
index a6b73b4f..1dafe7ce 100644
--- a/app/views/discover/_tab_discussed.html.haml
+++ b/app/views/discover/_tab_discussed.html.haml
@@ -1,3 +1,3 @@
.tab-pane.fade{role: "tabpanel", id: "comments"}
- comments.each do |a|
- = render 'shared/answerbox', a: a
+ = render 'answerbox', a: a
diff --git a/app/views/discover/_tab_new.html.haml b/app/views/discover/_tab_new.html.haml
index 261f904c..016a9612 100644
--- a/app/views/discover/_tab_new.html.haml
+++ b/app/views/discover/_tab_new.html.haml
@@ -1,3 +1,3 @@
-.tab-pane.active.fade.in{role: "tabpanel", id: "new"}
+.tab-pane.active.fade.show{role: "tabpanel", id: "new"}
- new.each do |user|
= render 'discover/userbox', u: user, type: "new"
diff --git a/app/views/discover/_userbox.html.haml b/app/views/discover/_userbox.html.haml
index 6da53dca..c1d5cf9b 100644
--- a/app/views/discover/_userbox.html.haml
+++ b/app/views/discover/_userbox.html.haml
@@ -1,11 +1,11 @@
-.panel.panel-default.questionbox{data: { id: u.id }}
- .panel-body
+.card{data: { id: u.id }}
+ .card-body
.media
.pull-left
%a{href: show_user_profile_path(u.screen_name)}
- %img.answerbox--img{src: u.profile_picture.url(:medium)}
+ %img.avatar-md.mr-2{src: u.profile_picture.url(:medium)}
.media-body
- %h6.media-heading
+ %h6.media-heading.answerbox__question-user
- if u.display_name.blank?
%a{href: show_user_profile_path(u.screen_name)}
%span= "@#{u.screen_name}"
@@ -13,7 +13,7 @@
%a{href: show_user_profile_path(u.screen_name)}
%span= u.display_name
%span.text-muted= "@#{u.screen_name}"
- %p.answerbox--question-text
+ %p.answerbox__question-text
- if type == "new"
= t('views.discover.userbox.new', time: time_ago_in_words(u.created_at))
- elsif type == "most"
diff --git a/app/views/discover/index.html.haml b/app/views/discover/index.html.haml
index 810b577a..b20a58b3 100644
--- a/app/views/discover/index.html.haml
+++ b/app/views/discover/index.html.haml
@@ -1,7 +1,7 @@
- provide(:title, generate_title("Discover"))
-.jumbotron.j2-jumbo.text-center.particle-jumbotron
- #particles
- .particle-content
+.jumbotron.jumbotron--particles
+ #particles.jumbotron__particles
+ .jumbotron__content
%h1= t 'views.discover.title'
%p= t('views.discover.subtitle', app_title: APP_CONFIG['site_name'])
.container
@@ -11,13 +11,13 @@
%p= t 'views.discover.content.desc'
%div{role: "tabpanel"}
%ul.nav.nav-tabs{role: "tablist"}
- %li.active{role: "presentation"}
- %a{href: "#answers", role: "tab", aria: {controls: "answers"}, data: {toggle: "tab"}}= t 'views.discover.content.tab.answers'
- %li{role: "presentation"}
- %a{href: "#questions", role: "tab", aria: {controls: "questions"}, data: {toggle: "tab"}}= t 'views.discover.content.tab.questions'
- %li{role: "presentation"}
- %a{href: "#comments", role: "tab", aria: {controls: "comments"}, data: {toggle: "tab"}}= t 'views.discover.content.tab.comments'
- .tab-content.discover
+ %li.nav-item{role: "presentation"}
+ %a.nav-link.active{href: "#answers", role: "tab", aria: {controls: "answers"}, data: {toggle: "tab"}}= t 'views.discover.content.tab.answers'
+ %li.nav-item{role: "presentation"}
+ %a.nav-link{href: "#questions", role: "tab", aria: {controls: "questions"}, data: {toggle: "tab"}}= t 'views.discover.content.tab.questions'
+ %li.nav-item{role: "presentation"}
+ %a.nav-link{href: "#comments", role: "tab", aria: {controls: "comments"}, data: {toggle: "tab"}}= t 'views.discover.content.tab.comments'
+ .tab-content.mt-3
= render 'discover/tab_answers', answers: @popular_answers
= render 'discover/tab_questions', questions: @popular_questions
= render 'discover/tab_discussed', comments: @most_discussed
@@ -26,13 +26,13 @@
%p= t 'views.discover.people.desc'
%div{role: "tabpanel"}
%ul.nav.nav-tabs{role: "tablist"}
- %li.active{role: "presentation"}
- %a{href: "#new", role: "tab", aria: {controls: "new"}, data: {toggle: "tab"}}= t 'views.discover.people.tab.new'
- %li{role: "presentation"}
- %a{href: "#asked", role: "tab", aria: {controls: "asked"}, data: {toggle: "tab"}}= t 'views.discover.people.tab.questions'
- %li{role: "presentation"}
- %a{href: "#answered", role: "tab", aria: {controls: "answered"}, data: {toggle: "tab"}}= t 'views.discover.people.tab.answers'
- .tab-content.discover
+ %li.nav-item{role: "presentation"}
+ %a.nav-link.active{href: "#new", role: "tab", aria: {controls: "new"}, data: {toggle: "tab"}}= t 'views.discover.people.tab.new'
+ %li.nav-item{role: "presentation"}
+ %a.nav-link{href: "#asked", role: "tab", aria: {controls: "asked"}, data: {toggle: "tab"}}= t 'views.discover.people.tab.questions'
+ %li.nav-item{role: "presentation"}
+ %a.nav-link{href: "#answered", role: "tab", aria: {controls: "answered"}, data: {toggle: "tab"}}= t 'views.discover.people.tab.answers'
+ .tab-content.mt-3
= render 'discover/tab_new', new: @new_users
= render 'discover/tab_asked', asked: @users_with_most_questions
= render 'discover/tab_most', answered: @users_with_most_answers
diff --git a/app/views/group/index.haml b/app/views/group/index.haml
new file mode 100644
index 00000000..61e139a3
--- /dev/null
+++ b/app/views/group/index.haml
@@ -0,0 +1,12 @@
+#timeline
+ - @timeline.each do |answer|
+ = render 'answerbox', a: answer
+
+ = render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @timeline_last_id
+
+ - if @more_data_available
+ %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @timeline_last_id }}
+ = t 'views.actions.load'
+
+- provide(:title, group_title(@group))
+- parent_layout "feed"
diff --git a/app/views/group/index.html.haml b/app/views/group/index.html.haml
deleted file mode 100644
index 26e38046..00000000
--- a/app/views/group/index.html.haml
+++ /dev/null
@@ -1,18 +0,0 @@
-- provide(:title, group_title(@group))
-= render 'static/mobile_nav'
-.container.j2-page
- .col-md-3.col-sm-4
- = render 'shared/sidebar'
- .col-md-9.col-xs-12.col-sm-8.j2-col-reset
- = render 'layouts/messages'
-
- #timeline
- - @timeline.each do |answer|
- = render 'shared/answerbox', a: answer
-
- = render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @timeline_last_id
-
- - if @more_data_available
- %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @timeline_last_id }}
- = t 'views.actions.load'
-.visible-xs= render 'shared/links'
diff --git a/app/views/group/index.js.erb b/app/views/group/index.js.erb
index fd1ddb36..59591f8d 100644
--- a/app/views/group/index.js.erb
+++ b/app/views/group/index.js.erb
@@ -1,5 +1,5 @@
$('#timeline').append('<% @timeline.each do |answer|
- %><%= j render 'shared/answerbox', a: answer
+ %><%= j render 'answerbox', a: answer
%><% end %>');
<% if @more_data_available %>
$('#pagination').html('<%= j render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @timeline_last_id %>');
diff --git a/app/views/inbox/_entry.html.haml b/app/views/inbox/_entry.html.haml
index 3bed6c9b..04982e3e 100644
--- a/app/views/inbox/_entry.html.haml
+++ b/app/views/inbox/_entry.html.haml
@@ -1,19 +1,19 @@
-.panel.inbox-box{class: "panel-#{i.new? ? 'primary' : 'default'}", data: { id: i.id }}
- .panel-heading
+.card.inbox-box{class: i.new? ? 'inbox-entry--new' : '', data: { id: i.id }}
+ .card-header
.media
- unless i.question.author_is_anonymous
%a.pull-left{href: show_user_profile_path(i.question.user.screen_name)}
- %img.img-rounded.answerbox--img{src: i.question.user.profile_picture.url(:medium)}
+ %img.answerbox__question-user-avatar.avatar-md{src: i.question.user.profile_picture.url(:medium)}
.media-body
- %h6.text-muted.media-heading.answerbox--question-user
+ %h6.text-muted.media-heading.answerbox__question-user
= raw t('views.inbox.entry.asked', user: user_screen_name(i.question.user, anonymous: i.question.author_is_anonymous), time: time_tooltip(i.question))
- unless i.question.author_is_anonymous
- if i.question.answer_count > 0
·
%a{href: show_user_question_path(i.question.user.screen_name, i.question.id)}
= pluralize(i.question.answer_count, t('views.inbox.entry.response'))
- %p.answerbox--question-text= i.question.content
- .panel-body
+ %p.answerbox__question-text= i.question.content
+ .card-body
%textarea.form-control{name: 'ib-answer', placeholder: t('views.placeholder.inbox'), data: { id: i.id }}
%br/
%button.btn.btn-success{name: 'ib-answer', data: { ib_id: i.id }}
@@ -23,7 +23,7 @@
%button.btn.btn-default{name: 'ib-options', data: { ib_id: i.id, state: :hidden }}
%i.fa.fa-cog
%span.sr-only= t 'views.actions.options'
- .panel-footer{id: "ib-options-#{i.id}", style: 'display: none'}
+ .card-footer{id: "ib-options-#{i.id}", style: 'display: none'}
%h4= t 'views.inbox.entry.sharing.title'
- if current_user.services.count > 0
.row
diff --git a/app/views/inbox/_sidebar.html.haml b/app/views/inbox/_sidebar.html.haml
index aa18a49a..4cda09a0 100644
--- a/app/views/inbox/_sidebar.html.haml
+++ b/app/views/inbox/_sidebar.html.haml
@@ -1,29 +1,25 @@
-.panel.panel-default.inbox--panel
- .panel-heading
- %h3.panel-title= t 'views.inbox.sidebar.questions.title'
- .panel-body
+.card.inbox--panel
+ .card-header= t 'views.inbox.sidebar.questions.title'
+ .card-body
%button.btn.btn-block.btn-info{type: :button, id: 'ib-generate-question'}= t 'views.inbox.sidebar.questions.button'
-.panel.panel-default.inbox--panel
- .panel-heading
- %h3.panel-title= t 'views.inbox.sidebar.share.title'
- .panel-body
+.card.inbox--panel
+ .card-header= t 'views.inbox.sidebar.share.title'
+ .card-body
%a.btn.btn-block.btn-primary{target: '_blank', href: "https://twitter.com/intent/tweet?text=Ask%20me%20anything%21&url=#{show_user_profile_url(current_user.screen_name)}"}
%i.fa.fa-fw.fa-twitter
= raw t('views.inbox.sidebar.share.button', service: "Twitter")
%a.btn.btn-block.btn-primary{target: '_blank', href: "https://www.tumblr.com/share/link?url=#{show_user_profile_url(current_user.screen_name)}&name=Ask%20me%20anything%21"}
%i.fa.fa-fw.fa-tumblr
= raw t('views.inbox.sidebar.share.button', service: "Tumblr")
-.panel.panel-default.inbox--panel
- .panel-heading
- %h3.panel-title Show author
- .panel-body
+.card.inbox--panel
+ .card-header Show author
+ .card-body
%form#author_form
= bootstrap_form_tag url: inbox_path, method: :get do |f|
= f.text_field :author, value: params[:author], placeholder: "username", prepend: "@" , hide_label: true
- = f.button "Show", name: nil, class: "btn btn-default btn-block btn-sm", id: "ib-author"
-.panel.panel-default.warning--panel
- .panel-heading
- %h3.panel-title= t 'views.inbox.sidebar.actions.title'
- .panel-body
+ = f.button "Show", name: nil, class: "btn btn-light btn-block btn-sm", id: "ib-author"
+.card.warning--panel
+ .card-header= t 'views.inbox.sidebar.actions.title'
+ .card-body
%button.btn.btn-block.btn-danger{type: :button, id: @delete_id , disabled: (@disabled ? 'disabled' : nil), data: { ib_count: @inbox_count }}= t 'views.inbox.sidebar.actions.button'
diff --git a/app/views/inbox/show.html.haml b/app/views/inbox/show.html.haml
index cb9b1f1e..be2abe85 100644
--- a/app/views/inbox/show.html.haml
+++ b/app/views/inbox/show.html.haml
@@ -1,25 +1,12 @@
-- provide(:title, generate_title("Inbox"))
-.container.j2-page
- .row
- .col-md-3.col-xs-12.col-sm-4.hidden-xs
- = render 'inbox/sidebar'
- .col-md-9.col-xs-12.col-sm-8
- = render 'layouts/messages'
- #entries
- - @inbox.each do |i|
- = render 'inbox/entry', i: i
+#entries
+ - @inbox.each do |i|
+ = render 'inbox/entry', i: i
- - if @inbox.empty?
- = t 'views.inbox.empty'
+ - if @inbox.empty?
+ = t 'views.inbox.empty'
- = render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @inbox_last_id
+ = render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @inbox_last_id
- - if @more_data_available
- %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @inbox_last_id }}
- = t 'views.actions.load'
-
- .col-md-9.col-xs-12.col-sm-8.visible-xs
- = render 'inbox/sidebar'
-
-= render "shared/links"
-- Inbox.where(id: @inbox.ids).update_all(new: false)
+ - if @more_data_available
+ %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @inbox_last_id }}
+ = t 'views.actions.load'
diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml
deleted file mode 100644
index fc88d814..00000000
--- a/app/views/layouts/_header.html.haml
+++ /dev/null
@@ -1,47 +0,0 @@
-%nav.navbar.navbar-inverse.navbar-fixed-top{role: "navigation"}
- .container{class: ios_web_app? ? "ios-web-app" : ''}
- .navbar-header
- %button.navbar-toggle{"data-target" => "#j2-main-navbar-collapse", "data-toggle" => "collapse", type: "button"}
- %span.sr-only Toggle navigation
- - if user_signed_in?
- - unless inbox_count.nil? or notification_count.nil?
- %span.icon-bar.navbar--inbox-animation
- %span.icon-bar.navbar--inbox-animation
- %span.icon-bar.navbar--inbox-animation
- - else
- %span.icon-bar
- %span.icon-bar
- %span.icon-bar
- - else
- %span.icon-bar
- %span.icon-bar
- %span.icon-bar
- %a.navbar-brand{href: "/"}= APP_CONFIG['site_name']
- #j2-main-navbar-collapse.collapse.navbar-collapse
- - if user_signed_in?
- %ul.nav.navbar-nav
- = nav_entry t('views.navigation.timeline'), root_path
- = nav_entry t('views.navigation.inbox'), "/inbox", badge: inbox_count
- - if APP_CONFIG.dig(:features, :discover, :enabled) || current_user.mod?
- = nav_entry t('views.navigation.discover'), discover_path
- %ul.nav.navbar-nav.navbar-right
- - unless @user.nil?
- - unless @user == current_user
- %li.hidden-xs{"data-toggle" => "tooltip", "data-placement" => "bottom", title: t('views.actions.group')}
- %a{href: '#', data: { target: "#modal-group-memberships", toggle: :modal }}
- %i.fa.fa-users.hidden-xs
- %span.visible-xs= t('views.actions.group')
- = render "layouts/notifications"
- %li.hidden-xs{"data-toggle" => "tooltip", "data-placement" => "bottom", title: t('views.actions.ask_question')}
- .btn.btn-link.navbar-btn{name: "toggle-all-ask", "data-target" => "#modal-ask-followers", "data-toggle" => "modal", :type => "button"}
- %i.fa.fa-pencil-square-o
- = render "layouts/profile"
- - else
- %ul.nav.navbar-nav.navbar-right
- = nav_entry t('views.sessions.create'), new_user_session_path
- = nav_entry t('views.sessions.new'), new_user_registration_path
-
-- if user_signed_in?
- = render 'shared/modal_ask_followers'
- %button.btn.btn-primary.btn-fab.visible-xs{"data-target" => "#modal-ask-followers", "data-toggle" => "modal", :type => "button"}
- %i.fa.fa-pencil-square-o
diff --git a/app/views/layouts/_notifications.html.haml b/app/views/layouts/_notifications.html.haml
deleted file mode 100644
index 34f27641..00000000
--- a/app/views/layouts/_notifications.html.haml
+++ /dev/null
@@ -1,126 +0,0 @@
-= nav_entry t('views.navigation.notifications'), notifications_path, badge: notification_count, class: 'visible-xs'
-- notifications = Notification.for(current_user).where(new: true).limit(4)
-%li.dropdown.hidden-xs
- %a.dropdown-toggle{href: "#", "data-toggle" => "dropdown"}
- - if notification_count.nil?
- %i.fa.fa-bell-o
- - else
- %i.fa.fa-bell
- %span.sr-only Notifications
- %span.badge= notification_count
- %ul.dropdown-menu.notification-center
- - if notifications.count == 0
- %li.text-center
- .notifications--none
- %i.fa.fa-bell-o.no-notifications
- %p No new notifications.
- %li.text-center
- %a{href: notifications_path('all')}
- %i.fa.fa-fw.fa-chevron-right
- Show all notifications
- - else
- - notifications.each do |notification|
- %li
- .media.notification--dropdown-media
- - case notification.target_type
- - when "Answer"
- .pull-left
- %i.fa.fa-2x.fa-fw.fa-exclamation
- .media-body
- .notification--heading
- %img.notification--img-sm{src: notification.target.user.profile_picture.url(:small)}
- = user_screen_name notification.target.user
- answered
- = link_to "your question", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.id)
- = time_tooltip(notification.target)
- ago
- .list-group.notification--list
- .list-group-item
- .media.question-media
- .media-body
- %h6.notification--list-heading question
- .notification--list-content
- = markdown notification.target.question.content[0..60] + "#{notification.target.question.content.length > 60 ? '[...]' : ''}"
- .list-group-item
- .media.question-media
- .media-body
- %h6.notification--list-heading answer
- .notification--list-content
- = markdown notification.target.content[0..60] + "#{notification.target.content.length > 60 ? '[...]' : ''}"
- - when "Relationship"
- .pull-left
- %img.img-rounded.notification--dropdown-img{src: notification.target.source.profile_picture.url(:small)}
- .media-body
- %h6.media-heading.notification--dropdown-user
- = user_screen_name notification.target.source
- .notification--dropdown-text
- = raw t('views.notifications.relationship.body', time: time_ago_in_words(notification.target.created_at))
- - when "Smile"
- .pull-left
- %i.fa.fa-2x.fa-fw.fa-smile-o
- .media-body
- .notification--heading
- %img.notification--img-sm{src: notification.target.user.profile_picture.url(:small)}
- = user_screen_name notification.target.user
- smiled
- = link_to "your answer", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id)
- = time_tooltip(notification.target)
- ago
- .list-group.notification--list
- .list-group-item
- .media.question-media
- .media-body
- %h6.notification--list-heading answer
- .notification--list-content
- = markdown notification.target.answer.content[0..60] + "#{notification.target.answer.content.length > 60 ? '[...]' : ''}"
- - when "CommentSmile"
- .pull-left
- %i.fa.fa-2x.fa-fw.fa-smile-o
- .media-body
- .notification--heading
- %img.notification--img-sm{src: notification.target.user.profile_picture.url(:small)}
- = user_screen_name notification.target.user
- smiled
- = link_to "your comment", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.comment.answer.id)
- = time_tooltip(notification.target)
- ago
- .list-group.notification--list
- .list-group-item
- .media.question-media
- .media-body
- %h6.notification--list-heading comment
- .notification--list-content
- = markdown notification.target.comment.content[0..60] + "#{notification.target.comment.content.length > 60 ? '[...]' : ''}"
- - when "Comment"
- .pull-left
- %i.fa.fa-2x.fa-fw.fa-comments
- .media-body
- .notification--heading
- %img.notification--img-sm{src: notification.target.user.profile_picture.url(:small)}
- = user_screen_name notification.target.user
- commented on
- - if notification.target.answer.user == current_user
- = link_to "your answer", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id)
- - elsif notification.target.user == notification.target.answer.user
- = link_to "their answer", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id)
- - else
- = link_to "#{notification.target.answer.user.screen_name}'s answer", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id)
- = time_tooltip(notification.target)
- ago
- .list-group.notification--list
- .list-group-item
- .media.question-media
- .media-body
- %h6.notification--list-heading answer
- .notification--list-content
- = markdown notification.target.answer.content[0..60] + "#{notification.target.answer.content.length > 60 ? '[...]' : ''}"
- .list-group-item
- .media.question-media
- .media-body
- %h6.notification--list-heading comment
- .notification--list-content
- = markdown notification.target.content[0..60] + "#{notification.target.content.length > 60 ? '[...]' : ''}"
- %li.text-center
- %a{href: notifications_path}
- %i.fa.fa-fw.fa-chevron-right
- Show all new notifications
diff --git a/app/views/layouts/_profile.html.haml b/app/views/layouts/_profile.html.haml
deleted file mode 100644
index 519195db..00000000
--- a/app/views/layouts/_profile.html.haml
+++ /dev/null
@@ -1,45 +0,0 @@
-%li.dropdown.profile--image-dropdown
- %a.dropdown-toggle{href: "#", "data-toggle" => "dropdown"}
- %img.profile--image-avatar.hidden-xs{src: current_user.profile_picture.url(:small)}
- %span.visible-xs
- = current_user.screen_name
- %b.caret
- %ul.dropdown-menu
- %li.dropdown-header.hidden-xs= current_user.screen_name
- %li
- %a{href: show_user_profile_path(current_user.screen_name)}
- %i.fa.fa-fw.fa-user
- = t('views.navigation.show')
- %li
- %a{href: edit_user_registration_path}
- %i.fa.fa-fw.fa-cog
- = t('views.navigation.settings')
- %li.divider
- - if current_user.has_role?(:administrator)
- %li
- %a{href: rails_admin_path}
- %i.fa.fa-fw.fa-cogs
- = t('views.navigation.admin')
- %li
- %a{href: sidekiq_web_path}
- %i.fa.fa-fw.fa-bar-chart
- = t('views.navigation.sidekiq')
- %li
- %a{href: pghero_path}
- %i.fa.fa-fw.fa-database
- Database Monitor
- %li
- %a{href: announcement_index_path}
- %i.fa.fa-fw.fa-info
- Announcements
- %li.divider
- - if current_user.mod?
- %li
- %a{href: moderation_path}
- %i.fa.fa-fw.fa-gavel
- = t('views.navigation.moderation')
- %li.divider
- %li
- %a{href: destroy_user_session_path, data: {method: :delete} }
- %i.fa.fa-fw.fa-sign-out
- = t 'views.sessions.destroy'
diff --git a/app/views/layouts/application.haml b/app/views/layouts/application.haml
new file mode 100644
index 00000000..001462ad
--- /dev/null
+++ b/app/views/layouts/application.haml
@@ -0,0 +1,3 @@
+= yield
+
+- parent_layout "base"
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/base.haml
similarity index 63%
rename from app/views/layouts/application.html.haml
rename to app/views/layouts/base.haml
index d40a87d8..7e466fe6 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/base.haml
@@ -12,19 +12,16 @@
%title= yield(:title)
= javascript_include_tag 'i18n', 'data-turbolinks-track' => true
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
- - if user_signed_in? and not current_user.theme.nil? and (@user.nil? || @user.theme.nil?)
- %link{rel: 'stylesheet', href: current_user.theme.css.url, media: :all, 'data-turbolinks-track' => "false"}
- %meta{name: 'theme-color', content: current_user.theme.theme_color}
- - if (not @user.nil?) and (not @user.theme.nil?) and (if user_signed_in? then current_user.show_foreign_themes? else true end)
- %link{rel: 'stylesheet', href: @user.theme.css.url, media: :all, 'data-turbolinks-track' => "false"}
- %meta{name: 'theme-color', content: @user.theme.theme_color}
= javascript_include_tag 'application', 'data-turbolinks-track' => true
- if user_signed_in?
- if current_user.mod?
= javascript_include_tag 'moderation', 'data-turbolinks-track' => true
= csrf_meta_tags
- %body#version1
- = render 'layouts/header'
+ %body
+ - if user_signed_in?
+ = render 'navigation/main'
+ - else
+ = render 'navigation/guest'
= render 'shared/announcements'
= yield
= render 'shared/locales'
@@ -40,7 +37,4 @@
= `git rev-parse --short HEAD`.strip
%p.text-danger Debug params:
= debug params
- - if Rails.env.production?
- %noscript
- %p
- %img{:alt => "", :src => "//stat.rrerr.net/piwik.php?idsite=9", :style => "border:0;"}/
+ = render_theme
diff --git a/app/views/layouts/feed.haml b/app/views/layouts/feed.haml
new file mode 100644
index 00000000..dff4d4f9
--- /dev/null
+++ b/app/views/layouts/feed.haml
@@ -0,0 +1,9 @@
+.container.container--main
+ .row
+ .col-md-3.col-sm-4.d-none.d-sm-block
+ = render 'shared/sidebar'
+ .col-md-9.col-xs-12.col-sm-8
+ = render 'layouts/messages'
+ = render 'tabs/feed'
+ = yield
+ .d-block.d-sm-none= render 'shared/links'
\ No newline at end of file
diff --git a/app/views/layouts/inbox.haml b/app/views/layouts/inbox.haml
new file mode 100644
index 00000000..625bdfcd
--- /dev/null
+++ b/app/views/layouts/inbox.haml
@@ -0,0 +1,13 @@
+.container.container--main
+ .row
+ .col-md-3.col-xs-12.col-sm-4.order-2.order-sm-1
+ = render 'inbox/sidebar'
+ .col-md-9.col-xs-12.col-sm-8.order-1.order-sm-2
+ = render 'layouts/messages'
+ = yield
+
+= render "shared/links"
+
+- Inbox.where(id: @inbox.ids).update_all(new: false)
+- provide(:title, generate_title("Inbox"))
+- parent_layout "base"
\ No newline at end of file
diff --git a/app/views/layouts/moderation.haml b/app/views/layouts/moderation.haml
new file mode 100644
index 00000000..18fb60a6
--- /dev/null
+++ b/app/views/layouts/moderation.haml
@@ -0,0 +1,10 @@
+= render 'navigation/moderation'
+.container.container--main
+ .row
+ .col-md-3.col-sm-4.col-xs-12
+ = render 'tabs/moderation'
+ .col-md-9.col-sm-8.col-xs-12
+ = yield
+
+- provide(:title, generate_title("Moderation"))
+- parent_layout "base"
\ No newline at end of file
diff --git a/app/views/layouts/notifications.haml b/app/views/layouts/notifications.haml
new file mode 100644
index 00000000..83d74825
--- /dev/null
+++ b/app/views/layouts/notifications.haml
@@ -0,0 +1,11 @@
+= render 'navigation/notification'
+.container.container--main
+ .row
+ .col-md-3.col-xs-12.col-sm-4
+ = render 'tabs/notifications'
+ .col-md-9.col-xs-12.col-sm-8
+ = yield
+
+- Notification.for(current_user).update_all(new: false)
+- provide(:title, generate_title("Notifications"))
+- parent_layout "base"
\ No newline at end of file
diff --git a/app/views/layouts/user/profile.haml b/app/views/layouts/user/profile.haml
new file mode 100644
index 00000000..c551a4c3
--- /dev/null
+++ b/app/views/layouts/user/profile.haml
@@ -0,0 +1,16 @@
+.profile__header-container
+ %img.profile__header-image{src: @user.profile_header.url(:web)}
+.container
+ .row
+ .col-md-3.col-xs-12.col-sm-4
+ = render 'user/profile'
+ .d-none.d-sm-block= render 'shared/links'
+ .col-md-9.col-xs-12.col-sm-8
+ = render "questionbox"
+ = render "tabs/profile"
+ = yield
+- if user_signed_in?
+ = render 'modal/group'
+ - if current_user.mod? and @user != current_user
+ = render 'modal/privileges'
+ = render 'modal/ban'
\ No newline at end of file
diff --git a/app/views/layouts/user/settings.haml b/app/views/layouts/user/settings.haml
new file mode 100644
index 00000000..e63f29ba
--- /dev/null
+++ b/app/views/layouts/user/settings.haml
@@ -0,0 +1,7 @@
+.container.container--main
+ .row
+ .col-md-3.col-xs-12.col-sm-4
+ = render 'tabs/settings'
+ .col-md-9.col-xs-12.col-sm-8
+ = render 'layouts/messages'
+ = yield
\ No newline at end of file
diff --git a/app/views/shared/_modal_ask_followers.html.haml b/app/views/modal/_ask.haml
similarity index 95%
rename from app/views/shared/_modal_ask_followers.html.haml
rename to app/views/modal/_ask.haml
index c7d14b21..43d295d5 100644
--- a/app/views/shared/_modal_ask_followers.html.haml
+++ b/app/views/modal/_ask.haml
@@ -2,10 +2,10 @@
.modal-dialog
.modal-content
.modal-header
+ %h5#modal-ask-followers-label.modal-title= t 'views.modal.ask.title'
%button.close{"data-dismiss" => "modal", :type => "button"}
%span{"aria-hidden" => "true"} ×
%span.sr-only= t 'views.actions.close'
- %h4#modal-ask-followers-label.modal-title= t 'views.modal.ask.title'
.modal-body
%textarea.form-control{:name => "qb-all-question", :placeholder => t('views.placeholder.question')}
.modal-footer
diff --git a/app/views/user/_modal_ban.html.haml b/app/views/modal/_ban.haml
similarity index 97%
rename from app/views/user/_modal_ban.html.haml
rename to app/views/modal/_ban.haml
index 63b374bd..0e1d5752 100644
--- a/app/views/user/_modal_ban.html.haml
+++ b/app/views/modal/_ban.haml
@@ -2,11 +2,11 @@
.modal-dialog
.modal-content
.modal-header
+ %h5#modal-ban-label.modal-title
+ = t 'views.modal.bancontrol.title'
%button.close{"data-dismiss" => "modal", :type => "button"}
%span{"aria-hidden" => "true"} ×
%span.sr-only Close
- %h4#modal-ban-label.modal-title
- = t 'views.modal.bancontrol.title'
= bootstrap_form_tag(url: '/mod/ban', html: { method: :post, novalidate: "novalidate" }) do |f|
= f.hidden_field :user, value: @user.screen_name
#ban-control-super.modal-body
diff --git a/app/views/shared/_comment_smiles.html.haml b/app/views/modal/_comment_smiles.haml
similarity index 71%
rename from app/views/shared/_comment_smiles.html.haml
rename to app/views/modal/_comment_smiles.haml
index 9d0b314d..0e15e327 100644
--- a/app/views/shared/_comment_smiles.html.haml
+++ b/app/views/modal/_comment_smiles.haml
@@ -2,17 +2,17 @@
.modal-dialog
.modal-content
.modal-header
+ %h5#modal-ask-followers-label.modal-title= t 'views.answerbox.commentsmile'
%button.close{"data-dismiss" => "modal", :type => "button"}
%span{"aria-hidden" => "true"} ×
%span.sr-only Close
- %h4#modal-ask-followers-label.modal-title= t 'views.answerbox.commentsmile'
.modal-body
- if comment.smiles.all.count == 0
= t 'views.answerbox.no_smile'
- else
- %ul.user-list.user-list-smiles
+ %ul.smiles__user-list
- comment.smiles.all.each do |smile|
- %li.user-list-entry.user-list-entry-smiles
+ %li.smiles__user-list-entry
%a{href: show_user_profile_path(smile.user.screen_name)}
- %img.img-rounded{src: smile.user.profile_picture.url(:medium), alt: user_screen_name(smile.user, url: false)}
+ %img{src: smile.user.profile_picture.url(:medium), alt: user_screen_name(smile.user, url: false)}
%span= user_screen_name(smile.user, url: false)
diff --git a/app/views/user/_modal_group_memberships.html.haml b/app/views/modal/_group.haml
similarity index 67%
rename from app/views/user/_modal_group_memberships.html.haml
rename to app/views/modal/_group.haml
index b8b1265a..4b7b45c4 100644
--- a/app/views/user/_modal_group_memberships.html.haml
+++ b/app/views/modal/_group.haml
@@ -2,24 +2,24 @@
.modal-dialog
.modal-content
.modal-header
+ %h5#modal-group-memberships-label.modal-title= t 'views.modal.group.title'
%button.close{"data-dismiss" => "modal", :type => "button"}
%span{"aria-hidden" => "true"} ×
%span.sr-only= t 'views.actions.close'
- %h4#modal-group-memberships-label.modal-title= t 'views.modal.group.title'
%div{role: "tabpanel"}
- %ul.nav.nav-tabs{role: "tablist"}
- %li.active{role: "presentation"}
- %a{href: "#grouplist", aria: {controls: "grouplist"}, data: {toggle: "tab"}, role: "tab"}
+ %ul.nav.nav-tabs.mt-1{role: "tablist"}
+ %li.nav-item{role: "presentation"}
+ %a.nav-link.active{href: "#grouplist", aria: {controls: "grouplist"}, data: {toggle: "tab"}, role: "tab"}
= t 'views.modal.group.tabs.main'
- %li{role: "presentation"}
- %a{href: "#create", aria: {controls: "create"}, data: {toggle: "tab"}, role: "tab"}
+ %li.nav-item{role: "presentation"}
+ %a.nav-link{href: "#create", aria: {controls: "create"}, data: {toggle: "tab"}, role: "tab"}
= t 'views.modal.group.tabs.create'
.tab-content
.tab-pane.active{role:"tabpanel", id: "grouplist"}
- %ul.list-group.groups--list
+ %ul.list-group
- current_user.groups.each do |group|
- = render 'user/modal_group_item', group: group, user: @user
+ = render 'modal/group/item', group: group, user: @user
.tab-pane{role:"tabpanel", id: "create"}
.modal-body
%input#new-group-name.form-control{type: :text, placeholder: t('views.modal.group.name')}
diff --git a/app/views/modal/_password.haml b/app/views/modal/_password.haml
new file mode 100644
index 00000000..7d411fb8
--- /dev/null
+++ b/app/views/modal/_password.haml
@@ -0,0 +1,13 @@
+#modal-passwd.modal.fade{"aria-hidden" => "true", "aria-labelledby" => "modal-passwd-label", :role => "dialog", :tabindex => "-1"}
+ .modal-dialog
+ .modal-content
+ .modal-header
+ %h5#modal-passwd-label.modal-title= t 'views.settings.account.modal.title'
+ %button.close{"data-dismiss" => "modal", :type => "button"}
+ %span{"aria-hidden" => "true"} ×
+ %span.sr-only= t 'views.actions.close'
+ .modal-body
+ = f.password_field :current_password, autocomplete: "off", label: t('views.settings.account.password_current'), help: t('views.settings.account.password_current_help')
+ .modal-footer
+ %button.btn.btn-default{"data-dismiss" => "modal", :type => "button"}= t 'views.actions.cancel'
+ %button.btn.btn-primary{:type => "submit"}= t 'views.actions.save'
\ No newline at end of file
diff --git a/app/views/user/_modal_privileges.html.haml b/app/views/modal/_privileges.haml
similarity index 67%
rename from app/views/user/_modal_privileges.html.haml
rename to app/views/modal/_privileges.haml
index cdbae22d..3fda929e 100644
--- a/app/views/user/_modal_privileges.html.haml
+++ b/app/views/modal/_privileges.haml
@@ -2,14 +2,14 @@
.modal-dialog
.modal-content
.modal-header
+ %h5#modal-privileges-label.modal-title
+ = raw t('views.actions.privilege', user: @user.screen_name)
%button.close{"data-dismiss" => "modal", :type => "button"}
%span{"aria-hidden" => "true"} ×
%span.sr-only= t 'views.actions.close'
- %h4#modal-privileges-label.modal-title
- = raw t('views.actions.privilege', user: @user.screen_name)
%ul.list-group.groups--list
- if current_user.has_role?(:administrator)
- = render 'user/modal_privileges_item', privilege: 'moderator', description: t('views.modal.privilege.moderator'),user: @user
- = render 'user/modal_privileges_item', privilege: 'admin', description: t('views.modal.privilege.admin'), user: @user
+ = render 'modal/privileges/item', privilege: 'moderator', description: t('views.modal.privilege.moderator'),user: @user
+ = render 'modal/privileges/item', privilege: 'admin', description: t('views.modal.privilege.admin'), user: @user
.modal-footer
%button.btn.btn-primary{name: 'checked-privileges', type: :button, data: { dismiss: :modal }}= t 'views.actions.done'
diff --git a/app/views/modal/group/_item.haml b/app/views/modal/group/_item.haml
new file mode 100644
index 00000000..c060abc8
--- /dev/null
+++ b/app/views/modal/group/_item.haml
@@ -0,0 +1,15 @@
+%li.list-group-item{id: "group-#{group.name}"}
+ .media
+ .pull-left
+ .custom-control.custom-checkbox
+ %input.custom-control-input{type: :checkbox, id: "groupCheck#{group.id}", name: 'gm-group-check', data: { group: group.name, user: user.screen_name }, checked: user.member_of?(group), autocomplete: 'off'}
+ %label.custom-control-label{for: "groupCheck#{group.id}"}
+ .media-body
+ .list-group-item-heading= group.display_name
+ .list-group-item-text.text-muted
+ %span{id: "#{group.name}-members"}= group.members.count
+ = t 'views.modal.group.members'
+ ·
+ %a.text-danger#delete-group{href: "#", data: { group: group.name }}
+ %i.fa.fa-close
+ = t 'views.actions.delete'
diff --git a/app/views/user/_modal_privileges_item.html.haml b/app/views/modal/privileges/_item.haml
similarity index 71%
rename from app/views/user/_modal_privileges_item.html.haml
rename to app/views/modal/privileges/_item.haml
index 5164a049..47c6380e 100644
--- a/app/views/user/_modal_privileges_item.html.haml
+++ b/app/views/modal/privileges/_item.haml
@@ -4,8 +4,8 @@
- checked = requires_role ? user.has_role?(role_mapping.fetch(privilege, privilege).to_sym) : user.public_send("#{privilege}?")
%li.list-group-item{id: "privilege-#{privilege}"}
.media
- .pull-left.j2-table
- %input.input--center{type: :checkbox, name: 'check-your-privileges', data: { type: privilege, user: user.screen_name }, checked: checked, autocomplete: 'off'}
+ .pull-left
+ %input{type: :checkbox, name: 'check-your-privileges', data: { type: privilege, user: user.screen_name }, checked: checked, autocomplete: 'off'}
.media-body
.list-group-item-heading= privilege.capitalize
- unless description.blank?
diff --git a/app/views/moderation/_discussion.html.haml b/app/views/moderation/_discussion.html.haml
index dddb7866..4be392f0 100644
--- a/app/views/moderation/_discussion.html.haml
+++ b/app/views/moderation/_discussion.html.haml
@@ -1,14 +1,14 @@
- if report.moderation_comments.all.count == 0
= t 'views.answerbox.no_comment'
- else
- %ul.comments
+ %ul.comment__container
- report.moderation_comments.order(:created_at).each do |comment|
- %li{data: { comment_id: comment.id }}
- .media.comments--media
+ %li.comment{data: { comment_id: comment.id }}
+ .media
.pull-left
- %img.img-rounded.answerbox--img{src: comment.user.profile_picture.url(:medium)}
- .media-body.comments--body
- %h6.media-heading.answerbox--question-user
+ %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"
@@ -17,12 +17,12 @@
.btn-group
%button.btn.btn-link.btn-sm.dropdown-toggle{data: { toggle: :dropdown }, aria: { expanded: :false }}
%span.caret
- %ul.dropdown-menu.dropdown-menu-right{role: :menu}
- %li.text-danger
- %a{href: '#', tabindex: -1, data: { action: 'mod-comment-destroy', id: comment.id }}
- %i.fa.fa-trash-o
- = t 'views.actions.delete'
- %p.comments--content= comment.content
+ .dropdown-menu.dropdown-menu-right{role: :menu}
+ %a.dropdown-item.text-danger{href: '#', tabindex: -1, data: { action: 'mod-comment-destroy', id: comment.id }}
+ %i.fa.fa-trash-o
+ = t 'views.actions.delete'
+ .comment__content
+ = comment.content
.form-group.has-feedback{name: 'mod-comment-new-group', data: { id: report.id }}
%input.form-control.comments--box{type: :text, placeholder: t('views.placeholder.comment'), name: 'mod-comment-new', data: { id: report.id }}
%span.text-muted.form-control-feedback.comments--count{id: "mod-comment-charcount-#{report.id}"} 160
diff --git a/app/views/moderation/_moderation_nav.html.haml b/app/views/moderation/_moderation_nav.html.haml
deleted file mode 100644
index 434c725a..00000000
--- a/app/views/moderation/_moderation_nav.html.haml
+++ /dev/null
@@ -1,17 +0,0 @@
-%nav.navbar.navbar-default.navbar-static-top.j2-navbar.visible-xs{role: "navigation"}
- .container
- .navbar-header
- %button.navbar-toggle{"data-target" => "#j2-tl-navbar-collapse", "data-toggle" => "collapse", type: "button"}
- %span.sr-only Toggle navigation
- %span.icon-bar
- %span.icon-bar
- %span.icon-bar
- %a.navbar-brand{href: moderation_path} Moderation
- #j2-tl-navbar-collapse.collapse.navbar-collapse
- %ul.nav.navbar-nav
- = nav_entry t('views.moderation.tabs.all'), moderation_path
- = nav_entry t('views.general.answer').pluralize(2) , moderation_path('answer')
- = nav_entry t('views.general.comment').pluralize(2), moderation_path('comment')
- = nav_entry t('views.general.user').pluralize(2) , moderation_path('user')
- = nav_entry t('views.general.question').pluralize(2), moderation_path('question')
- = nav_entry 'Priority', moderation_priority_path
diff --git a/app/views/moderation/_moderation_tabs.html.haml b/app/views/moderation/_moderation_tabs.html.haml
deleted file mode 100644
index 7cf4a3cc..00000000
--- a/app/views/moderation/_moderation_tabs.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-.col-md-3.col-sm-4.col-xs-12
- .panel.panel-default.hidden-xs
- .list-group
- = list_group_item t('views.moderation.tabs.all'), moderation_path
- = list_group_item t('views.general.answer').pluralize(2), moderation_path('answer')
- = list_group_item t('views.general.comment').pluralize(2), moderation_path('comment')
- = list_group_item t('views.general.user').pluralize(2), moderation_path('user')
- = list_group_item t('views.general.question').pluralize(2), moderation_path('question')
- = list_group_item 'Priority', moderation_priority_path
diff --git a/app/views/moderation/_moderationbox.html.haml b/app/views/moderation/_moderationbox.html.haml
index c341db8d..122582cb 100644
--- a/app/views/moderation/_moderationbox.html.haml
+++ b/app/views/moderation/_moderationbox.html.haml
@@ -1,9 +1,9 @@
- unless report.nil? or report.target.nil? or report.user.nil? or report.type.nil?
- .panel.panel-default.moderationbox{data: { id: report.id }}
- .panel-heading
- %img.img-rounded.answerbox--img{src: report.user.profile_picture.url(:medium)}
+ .card.moderationbox{data: { id: report.id }}
+ .card-header
+ %img.avatar-sm{src: report.user.profile_picture.url(:medium)}
= raw t('views.moderation.moderationbox.reported', user: user_screen_name(report.user), content: report.type.sub('Reports::', ''), time: time_tooltip(report))
- .panel-body
+ .card-body
%p
- if report.type == 'Reports::User'
= user_screen_name report.target
@@ -42,5 +42,5 @@
%span{id: "mod-comment-count-#{report.id}"}= report.moderation_comments.all.count
%button.btn.btn-default.btn-sm{type: :button, name: "mod-delete-report", data: { id: report.id }}
%i.fa.fa-trash-o
- .panel-footer{id: "mod-comments-section-#{report.id}", style: 'display: none'}
+ .card-footer{id: "mod-comments-section-#{report.id}", style: 'display: none'}
%div{id: "mod-comments-#{report.id}"}= render 'moderation/discussion', report: report
diff --git a/app/views/moderation/_userbox.html.haml b/app/views/moderation/_userbox.html.haml
index b9cc793d..ad59b82e 100644
--- a/app/views/moderation/_userbox.html.haml
+++ b/app/views/moderation/_userbox.html.haml
@@ -1,12 +1,11 @@
-- header_class = if user.profile_header.exists? then "userbox--header-container" else "userbox--no-header" end
-.panel.panel-default
- %div{class: header_class}
- %img.userbox--header{src: user.profile_header.url(:mobile)}
- .panel-body
- %img.userbox--avatar{src: user.profile_picture.url(:small)}
- %p.userbox--username
- %a.profile--displayname{href: show_user_profile_path(user.screen_name)}
- = user.screen_name
+.card.h-100.userbox
+ %img.userbox__header{src: user.profile_header.url(:mobile)}
+ .card-body
+ %img.userbox__avatar{src: user.profile_picture.url(:small)}
+ %a.profile__name{href: show_user_profile_path(user.screen_name)}
+ - unless user.display_name.blank?
+ .profile__display-name
+ = user.display_name
.row
.col-md-12.col-sm-12.col-xs-12
- unless count.nil?
diff --git a/app/views/moderation/index.html.haml b/app/views/moderation/index.html.haml
index 6d381d42..0e7b0a7a 100644
--- a/app/views/moderation/index.html.haml
+++ b/app/views/moderation/index.html.haml
@@ -1,8 +1,2 @@
-- provide(:title, generate_title("Moderation"))
-= render 'moderation/moderation_nav'
-.container.j2-page
- .row
- = render 'moderation/moderation_tabs'
- .col-md-9.col-sm-8.col-xs-12
- - @reports.each do |r|
- = render 'moderation/moderationbox', report: r
+- @reports.each do |r|
+ = render 'moderation/moderationbox', report: r
diff --git a/app/views/moderation/priority.html.haml b/app/views/moderation/priority.html.haml
index 0291c89d..436fb9ea 100644
--- a/app/views/moderation/priority.html.haml
+++ b/app/views/moderation/priority.html.haml
@@ -1,16 +1,10 @@
-- provide(:title, generate_title("Moderation"))
-= render 'moderation/moderation_nav'
-.container.j2-page
- .row
- = render 'moderation/moderation_tabs'
- .col-md-9.col-sm-9.col-xs-12
- %h2
- - if @host.nil?
- Users sorted by reports
- - else
- Users with the same IP
- #users
- .row
- - @users.each do |u, c|
- .col-md-4.col-sm-12col-xs-12
- = render 'moderation/userbox', user: u, count: c
+%h2
+ - if @host.nil?
+ Users sorted by reports
+ - else
+ Users with the same IP
+#users
+ .row.row-cols-1.row-cols-sm-2.row-cols-md-3
+ - @users.each do |u, c|
+ .col
+ = render 'moderation/userbox', user: u, count: c
diff --git a/app/views/navigation/_feed.haml b/app/views/navigation/_feed.haml
new file mode 100644
index 00000000..acbfaeec
--- /dev/null
+++ b/app/views/navigation/_feed.haml
@@ -0,0 +1,10 @@
+%nav.navbar.navbar-light.navbar-static-top.j2-navbar.d-flex.d-sm-none.bg-white{role: "navigation"}
+ %a.navbar-brand{href: "/"} Timelines
+ %button.navbar-toggler{"data-target" => "#j2-tl-navbar-collapse", "data-toggle" => "collapse", type: "button"}
+ %span.sr-only Toggle navigation
+ %span.navbar-toggler-icon
+ #j2-tl-navbar-collapse.collapse.navbar-collapse
+ %ul.nav.navbar-nav
+ = nav_entry "Public", public_timeline_path
+ - current_user.groups.each do |group|
+ = nav_entry group.display_name, group_timeline_path(group.name)
\ No newline at end of file
diff --git a/app/views/navigation/_guest.haml b/app/views/navigation/_guest.haml
new file mode 100644
index 00000000..d06d91c8
--- /dev/null
+++ b/app/views/navigation/_guest.haml
@@ -0,0 +1,10 @@
+%nav.navbar.navbar-dark.navbar-expand-lg.bg-primary.fixed-top{role: "navigation"}
+ .container{class: ios_web_app? ? "ios-web-app" : ''}
+ %a.navbar-brand{href: "/"}= APP_CONFIG['site_name']
+ %button.navbar-toggler{"data-target" => "#j2-main-navbar-collapse", "data-toggle" => "collapse", type: "button"}
+ %span.sr-only Toggle navigation
+ %span.navbar-toggler-icon
+ #j2-main-navbar-collapse.collapse.navbar-collapse
+ %ul.nav.navbar-nav.ml-auto
+ = nav_entry t('views.sessions.create'), new_user_session_path
+ = nav_entry t('views.sessions.new'), new_user_registration_path
\ No newline at end of file
diff --git a/app/views/navigation/_main.haml b/app/views/navigation/_main.haml
new file mode 100644
index 00000000..8e0aea46
--- /dev/null
+++ b/app/views/navigation/_main.haml
@@ -0,0 +1,28 @@
+%nav.navbar.navbar-themed.navbar-expand-lg.bg-primary.fixed-top{role: "navigation"}
+ .container{class: ios_web_app? ? "ios-web-app" : ''}
+ %a.navbar-brand{href: "/"}= APP_CONFIG['site_name']
+ %button.navbar-toggler{"data-target" => "#j2-main-navbar-collapse", "data-toggle" => "collapse", type: "button"}
+ %span.sr-only Toggle navigation
+ %span.navbar-toggler-icon
+ #j2-main-navbar-collapse.collapse.navbar-collapse
+ %ul.nav.navbar-nav.mr-auto
+ = nav_entry t('views.navigation.timeline'), root_path
+ = nav_entry t('views.navigation.inbox'), "/inbox", badge: inbox_count
+ - if APP_CONFIG.dig(:features, :discover, :enabled) || current_user.mod?
+ = nav_entry t('views.navigation.discover'), discover_path
+ %ul.nav.navbar-nav
+ - unless @user.nil?
+ - unless @user == current_user
+ %li.nav-item.d-none.d-sm-block{"data-toggle" => "tooltip", "data-placement" => "bottom", title: t('views.actions.group')}
+ %a.nav-link{href: '#', data: { target: "#modal-group-memberships", toggle: :modal }}
+ %i.fa.fa-users.hidden-xs
+ %span.d-none.d-sm-inline.d-md-none= t('views.actions.group')
+ = render "navigation/main/notifications"
+ %li.nav-item.d-none.d-sm-block{"data-toggle" => "tooltip", "data-placement" => "bottom", title: t('views.actions.ask_question')}
+ %a.nav-link{href: "#", name: "toggle-all-ask", "data-target" => "#modal-ask-followers", "data-toggle" => "modal"}
+ %i.fa.fa-pencil-square-o
+ = render "navigation/main/profile"
+
+= render 'modal/ask'
+%button.btn.btn-primary.btn-fab.d-block.d-sm-none{"data-target" => "#modal-ask-followers", "data-toggle" => "modal", :type => "button"}
+ %i.fa.fa-pencil-square-o
\ No newline at end of file
diff --git a/app/views/navigation/_moderation.haml b/app/views/navigation/_moderation.haml
new file mode 100644
index 00000000..e97f466d
--- /dev/null
+++ b/app/views/navigation/_moderation.haml
@@ -0,0 +1,13 @@
+%nav.navbar.navbar-light.bg-light.navbar-static-top.j2-navbar.d-flex.d-sm-none{role: "navigation"}
+ %a.navbar-brand{href: moderation_path} Moderation
+ %button.navbar-toggler{"data-target" => "#j2-tl-navbar-collapse", "data-toggle" => "collapse", type: "button"}
+ %span.sr-only Toggle navigation
+ %span.navbar-toggler-icon
+ #j2-tl-navbar-collapse.collapse.navbar-collapse
+ %ul.nav.navbar-nav
+ = nav_entry t('views.moderation.tabs.all'), moderation_path
+ = nav_entry t('views.general.answer').pluralize(2) , moderation_path('answer')
+ = nav_entry t('views.general.comment').pluralize(2), moderation_path('comment')
+ = nav_entry t('views.general.user').pluralize(2) , moderation_path('user')
+ = nav_entry t('views.general.question').pluralize(2), moderation_path('question')
+ = nav_entry 'Priority', moderation_priority_path
diff --git a/app/views/navigation/_notification.haml b/app/views/navigation/_notification.haml
new file mode 100644
index 00000000..c2be678a
--- /dev/null
+++ b/app/views/navigation/_notification.haml
@@ -0,0 +1,14 @@
+%nav.navbar.navbar-light.bg-white.navbar-static-top.j2-navbar.d-flex.d-sm-none{role: "navigation"}
+ %a.navbar-brand{href: notifications_path} Notifications
+ %button.navbar-toggler{"data-target" => "#j2-tl-navbar-collapse", "data-toggle" => "collapse", type: "button"}
+ %span.sr-only Toggle navigation
+ %span.navbar-toggler-icon
+ #j2-tl-navbar-collapse.collapse.navbar-collapse
+ %ul.nav.navbar-nav
+ = nav_entry "New Notifications", notifications_path
+ = nav_entry "All Notifications", notifications_path('all')
+ = nav_entry t('views.notifications.tabs.answer'), notifications_path('answer')
+ = nav_entry t('views.notifications.tabs.smile'), notifications_path('smile')
+ = nav_entry t('views.notifications.tabs.comment'), notifications_path('comment')
+ = nav_entry t('views.notifications.tabs.commentsmile'), notifications_path('commentsmile')
+ = nav_entry t('views.notifications.tabs.relationship'), notifications_path('relationship')
diff --git a/app/views/navigation/main/_notifications.haml b/app/views/navigation/main/_notifications.haml
new file mode 100644
index 00000000..0d11877e
--- /dev/null
+++ b/app/views/navigation/main/_notifications.haml
@@ -0,0 +1,26 @@
+= nav_entry t('views.navigation.notifications'), notifications_path, badge: notification_count, class: 'd-block d-sm-none'
+- notifications = Notification.for(current_user).where(new: true).limit(4)
+%li.nav-item.dropdown.d-none.d-sm-block
+ %a.nav-link.dropdown-toggle{href: "#", "data-toggle" => "dropdown"}
+ - if notification_count.nil?
+ %i.fa.fa-bell-o
+ - else
+ %i.fa.fa-bell
+ %span.sr-only Notifications
+ %span.badge= notification_count
+ .dropdown-menu.notification-dropdown
+ - if notifications.count == 0
+ .dropdown-item.text-center.p-2
+ %i.fa.fa-bell-o.notification__bell-icon
+ %p No new notifications.
+ %a.dropdown-item.text-center{href: notifications_path('all')}
+ %i.fa.fa-fw.fa-chevron-right
+ Show all notifications
+ - else
+ - notifications.each do |notification|
+ .dropdown-item
+ = render "notifications/type/#{notification.target_type.downcase}", notification: notification
+
+ %a.dropdown-item.text-center{href: notifications_path}
+ %i.fa.fa-fw.fa-chevron-right
+ Show all new notifications
diff --git a/app/views/navigation/main/_profile.haml b/app/views/navigation/main/_profile.haml
new file mode 100644
index 00000000..2aef7ad5
--- /dev/null
+++ b/app/views/navigation/main/_profile.haml
@@ -0,0 +1,37 @@
+%li.nav-item.dropdown.profile--image-dropdown
+ %a.nav-link.dropdown-toggle.p-sm-0{href: "#", "data-toggle" => "dropdown"}
+ %img.avatar-md.d-none.d-sm-inline{src: current_user.profile_picture.url(:small)}
+ %span.d-inline.d-sm-none
+ = current_user.screen_name
+ %b.caret
+ .dropdown-menu
+ %h6.dropdown-header.d-none.d-sm-block= current_user.screen_name
+ %a.dropdown-item{href: show_user_profile_path(current_user.screen_name)}
+ %i.fa.fa-fw.fa-user
+ = t('views.navigation.show')
+ %a.dropdown-item{href: edit_user_registration_path}
+ %i.fa.fa-fw.fa-cog
+ = t('views.navigation.settings')
+ .dropdown-divider
+ - if current_user.has_role?(:administrator)
+ %a.dropdown-item{href: rails_admin_path}
+ %i.fa.fa-fw.fa-cogs
+ = t('views.navigation.admin')
+ %a.dropdown-item{href: sidekiq_web_path}
+ %i.fa.fa-fw.fa-bar-chart
+ = t('views.navigation.sidekiq')
+ %a.dropdown-item{href: pghero_path}
+ %i.fa.fa-fw.fa-database
+ Database Monitor
+ %a.dropdown-item{href: announcement_index_path}
+ %i.fa.fa-fw.fa-info
+ Announcements
+ .dropdown-divider
+ - if current_user.mod?
+ %a.dropdown-item{href: moderation_path}
+ %i.fa.fa-fw.fa-gavel
+ = t('views.navigation.moderation')
+ .dropdown-divider
+ %a.dropdown-item{href: destroy_user_session_path, data: {method: :delete} }
+ %i.fa.fa-fw.fa-sign-out
+ = t 'views.sessions.destroy'
diff --git a/app/views/notifications/_notification.html.haml b/app/views/notifications/_notification.html.haml
deleted file mode 100644
index 594ec85c..00000000
--- a/app/views/notifications/_notification.html.haml
+++ /dev/null
@@ -1,100 +0,0 @@
-%li.list-group-item
- .media
- - case notification.target_type
- - when "Answer"
- .pull-left
- %i.fa.fa-2x.fa-fw.fa-exclamation
- .media-body
- .notification--heading
- %img.notification--img-sm{src: notification.target.user.profile_picture.url(:small)}
- = user_screen_name notification.target.user
- answered
- = link_to "your question", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.id)
- = time_tooltip(notification.target)
- ago
- .list-group.notification--list
- .list-group-item
- .media.question-media
- .media-body
- %h6.notification--list-heading question
- .notification--list-content
- = markdown notification.target.question.content
- .list-group-item
- .media.question-media
- .media-body
- %h6.notification--list-heading answer
- .notification--list-content
- = markdown notification.target.content[0..255] + "#{notification.target.content.length > 255 ? '[...]' : ''}"
- - when "Relationship"
- .pull-left
- %img.img-rounded.notification--dropdown-img{src: notification.target.source.profile_picture.url(:small)}
- .media-body
- %h6.media-heading.notification--dropdown-user
- = user_screen_name notification.target.source
- .notification--dropdown-text
- = raw t('views.notifications.relationship.body', time: time_ago_in_words(notification.target.created_at))
- - when "Smile"
- .pull-left
- %i.fa.fa-2x.fa-fw.fa-smile-o
- .media-body
- .notification--heading
- %img.notification--img-sm{src: notification.target.user.profile_picture.url(:small)}
- = user_screen_name notification.target.user
- smiled
- = link_to "your answer", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id)
- = time_tooltip(notification.target)
- ago
- .list-group.notification--list
- .list-group-item
- .media.question-media
- .media-body
- %h6.notification--list-heading answer
- .notification--list-content
- = markdown notification.target.answer.content[0..255] + "#{notification.target.answer.content.length > 255 ? '[...]' : ''}"
- - when "CommentSmile"
- .pull-left
- %i.fa.fa-2x.fa-fw.fa-smile-o
- .media-body
- .notification--heading
- %img.notification--img-sm{src: notification.target.user.profile_picture.url(:small)}
- = user_screen_name notification.target.user
- smiled
- = link_to "your comment", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.comment.answer.id)
- = time_tooltip(notification.target)
- ago
- .list-group.notification--list
- .list-group-item
- .media.question-media
- .media-body
- %h6.notification--list-heading comment
- .notification--list-content
- = markdown notification.target.comment.content
- - when "Comment"
- .pull-left
- %i.fa.fa-2x.fa-fw.fa-comments
- .media-body
- .notification--heading
- %img.notification--img-sm{src: notification.target.user.profile_picture.url(:small)}
- = user_screen_name notification.target.user
- commented on
- - if notification.target.answer.user == current_user
- = link_to "your answer", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id)
- - elsif notification.target.user == notification.target.answer.user
- = link_to "their answer", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id)
- - else
- = link_to "#{notification.target.answer.user.screen_name}'s answer", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id)
- = time_tooltip(notification.target)
- ago
- .list-group.notification--list
- .list-group-item
- .media.question-media
- .media-body
- %h6.notification--list-heading answer
- .notification--list-content
- = markdown notification.target.answer.content[0..255] + "#{notification.target.answer.content.length > 255 ? '[...]' : ''}"
- .list-group-item
- .media.question-media
- .media-body
- %h6.notification--list-heading comment
- .notification--list-content
- = markdown notification.target.content
diff --git a/app/views/notifications/_notification_nav.html.haml b/app/views/notifications/_notification_nav.html.haml
deleted file mode 100644
index 59a54d56..00000000
--- a/app/views/notifications/_notification_nav.html.haml
+++ /dev/null
@@ -1,18 +0,0 @@
-%nav.navbar.navbar-default.navbar-static-top.j2-navbar.visible-xs{role: "navigation"}
- .container
- .navbar-header
- %button.navbar-toggle{"data-target" => "#j2-tl-navbar-collapse", "data-toggle" => "collapse", type: "button"}
- %span.sr-only Toggle navigation
- %span.icon-bar
- %span.icon-bar
- %span.icon-bar
- %a.navbar-brand{href: notifications_path} Notifications
- #j2-tl-navbar-collapse.collapse.navbar-collapse
- %ul.nav.navbar-nav
- = nav_entry "New Notifications", notifications_path
- = nav_entry "All Notifications", notifications_path('all')
- = nav_entry t('views.notifications.tabs.answer'), notifications_path('answer')
- = nav_entry t('views.notifications.tabs.smile'), notifications_path('smile')
- = nav_entry t('views.notifications.tabs.comment'), notifications_path('comment')
- = nav_entry t('views.notifications.tabs.commentsmile'), notifications_path('commentsmile')
- = nav_entry t('views.notifications.tabs.relationship'), notifications_path('relationship')
diff --git a/app/views/notifications/_notification_tabs.html.haml b/app/views/notifications/_notification_tabs.html.haml
deleted file mode 100644
index 7970a5a2..00000000
--- a/app/views/notifications/_notification_tabs.html.haml
+++ /dev/null
@@ -1,15 +0,0 @@
-.col-md-3.col-xs-12.col-sm-4
- .panel.panel-default.hidden-xs
- .list-group
- = list_group_item "New Notifications", notifications_path, badge: Notification.for(current_user).where(new: true).count
- = list_group_item "All Notifications", notifications_path('all')
-
- .panel.panel-default.hidden-xs
- .panel-heading
- Filter by Type
- .list-group
- = list_group_item t('views.notifications.tabs.answer'), notifications_path('answer'), badge: Notification.for(current_user).where(target_type: "Answer", new: true).count
- = list_group_item t('views.notifications.tabs.smile'), notifications_path('smile'), badge: Notification.for(current_user).where(target_type: "Smile", new: true).count
- = list_group_item t('views.notifications.tabs.comment'), notifications_path('comment'), badge: Notification.for(current_user).where(target_type: "Comment", new: true).count
- = list_group_item t('views.notifications.tabs.commentsmile'), notifications_path('commentsmile'), badge: Notification.for(current_user).where(target_type: "CommentSmile", new: true).count
- = list_group_item t('views.notifications.tabs.relationship'), notifications_path('relationship'), badge: Notification.for(current_user).where(target_type: "Relationship", new: true).count
diff --git a/app/views/notifications/index.haml b/app/views/notifications/index.haml
new file mode 100644
index 00000000..919cfb59
--- /dev/null
+++ b/app/views/notifications/index.haml
@@ -0,0 +1,22 @@
+.card
+ %ul#notifications.list-group
+ - if @notifications.count == 0
+ %li.list-group-item.text-center
+ .notifications--none
+ %i.fa.fa-bell-o.notification__bell-icon
+ %p
+ - if params[:type] != "all"
+ No new notifications.
+ - else
+ No notifications.
+ - else
+ - @notifications.each do |notification|
+ %li.list-group-item
+ .media
+ = render "notifications/type/#{notification.target_type.downcase}", notification: notification
+
+ = render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @notifications_last_id, permitted_params: %i[type]
+
+ - if @more_data_available
+ %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @notifications_last_id }}
+ Load more
\ No newline at end of file
diff --git a/app/views/notifications/index.html.haml b/app/views/notifications/index.html.haml
deleted file mode 100644
index 2993cffd..00000000
--- a/app/views/notifications/index.html.haml
+++ /dev/null
@@ -1,26 +0,0 @@
-- provide(:title, generate_title("Notifications"))
-= render 'notifications/notification_nav'
-.container.j2-page
- = render 'notification_tabs'
- .col-md-9.col-xs-12.col-sm-8
- .panel.panel-default
- %ul#notifications.list-group
- - if @notifications.count == 0
- %li.list-group-item.text-center
- .notifications--none
- %i.fa.fa-bell-o.no-notifications
- %p
- - if params[:type] != "all"
- No new notifications.
- - else
- No notifications.
- - else
- - @notifications.each do |notification|
- = render 'notifications/notification', notification: notification
-
- = render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @notifications_last_id, permitted_params: %i[type]
-
- - if @more_data_available
- %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @notifications_last_id }}
- Load more
-- Notification.for(current_user).update_all(new: false)
diff --git a/app/views/notifications/type/_answer.haml b/app/views/notifications/type/_answer.haml
new file mode 100644
index 00000000..f8d8539e
--- /dev/null
+++ b/app/views/notifications/type/_answer.haml
@@ -0,0 +1,22 @@
+.media.notification
+ .notification__icon
+ %i.fa.fa-2x.fa-fw.fa-exclamation
+ .media-body
+ .notification__heading
+ %img.avatar-xs{src: notification.target.user.profile_picture.url(:small)}
+ = user_screen_name notification.target.user
+ answered
+ = link_to "your question", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.id)
+ = time_tooltip(notification.target)
+ ago
+ .list-group
+ .list-group-item
+ .media.question-media
+ .media-body
+ %h6.notification__list-heading question
+ = markdown notification.target.question.content[0..60] + "#{notification.target.question.content.length > 60 ? '[...]' : ''}"
+ .list-group-item
+ .media.question-media
+ .media-body
+ %h6.notification__list-heading answer
+ = markdown notification.target.content[0..60] + "#{notification.target.content.length > 60 ? '[...]' : ''}"
\ No newline at end of file
diff --git a/app/views/notifications/type/_comment.haml b/app/views/notifications/type/_comment.haml
new file mode 100644
index 00000000..91f58666
--- /dev/null
+++ b/app/views/notifications/type/_comment.haml
@@ -0,0 +1,27 @@
+.media.notification
+ .notification__icon
+ %i.fa.fa-2x.fa-fw.fa-comments
+ .media-body
+ .notification__heading
+ %img.avatar-xs{src: notification.target.user.profile_picture.url(:small)}
+ = user_screen_name notification.target.user
+ commented on
+ - if notification.target.answer.user == current_user
+ = link_to "your answer", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id)
+ - elsif notification.target.user == notification.target.answer.user
+ = link_to "their answer", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id)
+ - else
+ = link_to "#{notification.target.answer.user.screen_name}'s answer", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id)
+ = time_tooltip(notification.target)
+ ago
+ .list-group
+ .list-group-item
+ .media.question-media
+ .media-body
+ %h6.notification__list-heading answer
+ = markdown notification.target.answer.content[0..60] + "#{notification.target.answer.content.length > 60 ? '[...]' : ''}"
+ .list-group-item
+ .media.question-media
+ .media-body
+ %h6.notification__list-heading comment
+ = markdown notification.target.content[0..60] + "#{notification.target.content.length > 60 ? '[...]' : ''}"
\ No newline at end of file
diff --git a/app/views/notifications/type/_commentsmile.haml b/app/views/notifications/type/_commentsmile.haml
new file mode 100644
index 00000000..09833486
--- /dev/null
+++ b/app/views/notifications/type/_commentsmile.haml
@@ -0,0 +1,17 @@
+.media.notification
+ .notification__icon
+ %i.fa.fa-2x.fa-fw.fa-smile-o
+ .media-body
+ .notification__heading
+ %img.avatar-xs{src: notification.target.user.profile_picture.url(:small)}
+ = user_screen_name notification.target.user
+ smiled
+ = link_to "your comment", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.comment.answer.id)
+ = time_tooltip(notification.target)
+ ago
+ .list-group
+ .list-group-item
+ .media.question-media
+ .media-body
+ %h6.notification__list-heading comment
+ = markdown notification.target.comment.content[0..60] + "#{notification.target.comment.content.length > 60 ? '[...]' : ''}"
\ No newline at end of file
diff --git a/app/views/notifications/type/_relationship.haml b/app/views/notifications/type/_relationship.haml
new file mode 100644
index 00000000..c5654ae5
--- /dev/null
+++ b/app/views/notifications/type/_relationship.haml
@@ -0,0 +1,8 @@
+.media.notification
+ .notification__icon
+ %img.avatar-sm{src: notification.target.source.profile_picture.url(:small)}
+ .media-body
+ %h6.media-heading.notification__user
+ = user_screen_name notification.target.source
+ .notification__text
+ = raw t('views.notifications.relationship.body', time: time_ago_in_words(notification.target.created_at))
\ No newline at end of file
diff --git a/app/views/notifications/type/_smile.haml b/app/views/notifications/type/_smile.haml
new file mode 100644
index 00000000..eabe35c1
--- /dev/null
+++ b/app/views/notifications/type/_smile.haml
@@ -0,0 +1,17 @@
+.media.notification
+ .notification__icon
+ %i.fa.fa-2x.fa-fw.fa-smile-o
+ .media-body
+ .notification__heading
+ %img.avatar-xs{src: notification.target.user.profile_picture.url(:small)}
+ = user_screen_name notification.target.user
+ smiled
+ = link_to "your answer", show_user_answer_path(username: notification.target.user.screen_name, id: notification.target.answer.id)
+ = time_tooltip(notification.target)
+ ago
+ .list-group
+ .list-group-item
+ .media.question-media
+ .media-body
+ %h6.notification__list-heading answer
+ = markdown notification.target.answer.content[0..60] + "#{notification.target.answer.content.length > 60 ? '[...]' : ''}"
\ No newline at end of file
diff --git a/app/views/public/index.haml b/app/views/public/index.haml
new file mode 100644
index 00000000..18a8e660
--- /dev/null
+++ b/app/views/public/index.haml
@@ -0,0 +1,12 @@
+#timeline
+ - @timeline.each do |answer|
+ = render 'answerbox', a: answer
+
+ = render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @timeline_last_id
+
+ - if @more_data_available
+ %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @timeline_last_id }}
+ Load more
+
+- provide(:title, generate_title("Public Timeline"))
+- parent_layout "feed"
\ No newline at end of file
diff --git a/app/views/public/index.html.haml b/app/views/public/index.html.haml
deleted file mode 100644
index 09336b59..00000000
--- a/app/views/public/index.html.haml
+++ /dev/null
@@ -1,18 +0,0 @@
-- provide(:title, generate_title("Public Timeline"))
-= render 'static/mobile_nav'
-.container.j2-page
- .col-md-3.col-sm-4
- = render 'shared/sidebar'
- .col-md-9.col-xs-12.col-sm-8
- = render 'layouts/messages'
-
- #timeline
- - @timeline.each do |answer|
- = render 'shared/answerbox', a: answer
-
- = render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @timeline_last_id
-
- - if @more_data_available
- %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @timeline_last_id }}
- Load more
-.visible-xs= render 'shared/links'
diff --git a/app/views/public/index.js.erb b/app/views/public/index.js.erb
index fd1ddb36..59591f8d 100644
--- a/app/views/public/index.js.erb
+++ b/app/views/public/index.js.erb
@@ -1,5 +1,5 @@
$('#timeline').append('<% @timeline.each do |answer|
- %><%= j render 'shared/answerbox', a: answer
+ %><%= j render 'answerbox', a: answer
%><% end %>');
<% if @more_data_available %>
$('#pagination').html('<%= j render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @timeline_last_id %>');
diff --git a/app/views/shared/_question_header.haml b/app/views/question/_question.haml
similarity index 84%
rename from app/views/shared/_question_header.haml
rename to app/views/question/_question.haml
index bc5dc694..ef1e336d 100644
--- a/app/views/shared/_question_header.haml
+++ b/app/views/question/_question.haml
@@ -1,10 +1,10 @@
-.panel.panel-question{class: if hidden then 'question-hidden' end, tabindex: if hidden then '-1' end, aria: { hidden: if hidden then :true end }}
+.card.question--fixed{class: if hidden then 'question--hidden' end, tabindex: if hidden then '-1' end, aria: { hidden: if hidden then :true end }}
.container
- .panel-body
+ .card-body
.media.question-media
- unless question.author_is_anonymous
%a.pull-left{href: unless hidden then show_user_profile_path(question.user.screen_name) end}
- %img.img-rounded.answerbox--img{src: question.user.profile_picture.url(:medium)}
+ %img.avatar-sm{src: question.user.profile_picture.url(:medium)}
.media-body.question-body
- if user_signed_in?
.pull-right
@@ -28,4 +28,4 @@
= user_screen_name question.user, anonymous: question.author_is_anonymous, url: false
- else
= raw t('views.answerbox.asked', user: user_screen_name(question.user, anonymous: question.author_is_anonymous), time: time_tooltip(question))
- %p.answerbox--question-text= question.content
+ %p.answerbox__question-text= question.content
diff --git a/app/views/question/show.html.haml b/app/views/question/show.haml
similarity index 61%
rename from app/views/question/show.html.haml
rename to app/views/question/show.haml
index 5d407ab4..c05bf2a8 100644
--- a/app/views/question/show.html.haml
+++ b/app/views/question/show.haml
@@ -1,12 +1,10 @@
- provide(:title, question_title(@question))
-= render 'shared/question_header', question: @question, hidden: false
-= render 'shared/question_header', question: @question, hidden: true
+= render 'question', question: @question, hidden: false
+= render 'question', question: @question, hidden: true
.container.question-page
- / TODO: make this pretty (it's currently C-c'd straight from shared/_answerbox)
-
#answers
- @answers.each do |a|
- = render 'shared/answerbox', a: a, show_question: false
+ = render 'answerbox', a: a, show_question: false
= render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @answers_last_id
@@ -14,11 +12,11 @@
%button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @answers_last_id }}
Load more
- - if user_signed_in? and !current_user.answered? @question and current_user != @question.user and @question.user.privacy_allow_stranger_answers
- .panel.panel-default#q-answer-box
- .panel-heading
- %h3.panel-title= t('views.question.title')
- .panel-body
+ - if user_signed_in? && !current_user.answered?(@question) && current_user != @question.user && @question.user&.privacy_allow_stranger_answers
+ .card#q-answer-box
+ .card-header
+ %h3.card-title= t('views.question.title')
+ .card-body
%textarea#q-answer.form-control{placeholder: t('views.placeholder.inbox'), data: { id: @question.id }}
%br/
%button#q-answer.btn.btn-success{data: { q_id: @question.id }}
diff --git a/app/views/question/show.js.erb b/app/views/question/show.js.erb
index 10610656..fbbf582f 100644
--- a/app/views/question/show.js.erb
+++ b/app/views/question/show.js.erb
@@ -1,5 +1,5 @@
$('#answers').append('<% @answers.each do |answer|
- %><%= j render 'shared/answerbox', a: answer, show_question: false
+ %><%= j render 'answerbox', a: answer, show_question: false
%><% end %>');
<% if @more_data_available %>
$('#pagination').html('<%= j render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @answers_last_id %>');
diff --git a/app/views/services/index.haml b/app/views/services/index.haml
new file mode 100644
index 00000000..691d5076
--- /dev/null
+++ b/app/views/services/index.haml
@@ -0,0 +1,4 @@
+= render "settings/services"
+
+- provide(:title, generate_title("Service Settings"))
+- parent_layout "user/settings"
diff --git a/app/views/services/index.html.haml b/app/views/services/index.html.haml
deleted file mode 100644
index a6c54df9..00000000
--- a/app/views/services/index.html.haml
+++ /dev/null
@@ -1,24 +0,0 @@
-- provide(:title, generate_title("Service Settings"))
-.container.j2-page
- = render 'user/settings_tabs'
- .col-md-9.col-xs-12.col-sm-8
- = render 'layouts/messages'
- .panel.panel-default
- .panel-body
- - if @services.count > 0
- = t 'views.settings.service.enabled'
- - else
- = t 'views.settings.service.none'
-
- - APP_CONFIG['sharing'].each do |service, service_options|
- - if service_options['enabled'] and !@services.any? { |x| x.provider == service.to_s }
- %p=link_to t('views.settings.service.connect', service: service.capitalize), "/auth/#{service}"
-
- - if @services.count > 0
- %ul.list-group
- - @services.each do |service|
- %li.list-group-item
- %i{class: "fa fa-#{service.provider}"}
- %strong= service.provider.capitalize
- (#{service.nickname})
- = link_to t('views.settings.service.disconnect'), service_path(service), data: { confirm: t('views.settings.service.confirm', service: service.provider.capitalize) }, method: :delete
diff --git a/app/views/settings/_account.haml b/app/views/settings/_account.haml
new file mode 100644
index 00000000..bc34b0a9
--- /dev/null
+++ b/app/views/settings/_account.haml
@@ -0,0 +1,29 @@
+.card
+ .card-body
+ = bootstrap_form_for(resource, as: resource_name, url: '/settings/account', html: { method: :put }) do |f|
+ = render 'modal/password', f: f
+
+ = devise_error_messages!
+
+ = f.text_field :screen_name, autofocus: true, label: t('views.settings.account.username')
+
+ = f.email_field :email, label: t('views.settings.account.email')
+ - if devise_mapping.confirmable? && resource.pending_reconfirmation?
+ %div= raw t('views.settings.account.email_confirm', resource: resource.unconfirmed_email)
+
+ = f.password_field :password, autocomplete: "off", label: t('views.settings.account.password'), help: t('views.settings.account.password_help')
+ = f.password_field :password_confirmation, autocomplete: "off", label: t('views.settings.account.password_confirm')
+
+ %button.btn.btn-primary{"data-target" => "#modal-passwd", "data-toggle" => "modal", :type => "button"}
+ = t 'views.actions.save'
+
+ %hr/
+ %p
+ = t 'views.settings.account.unsatisfied'
+ =button_to t('views.settings.account.delete'), '/settings/account', data: { confirm: "Are you sure?" }, method: :delete, class: "btn btn-danger btn-xs"
+
+ = link_to t('views.settings.account.back'), :back
+
+.visible-xs= render "shared/links"
+
+
diff --git a/app/views/settings/_data.haml b/app/views/settings/_data.haml
new file mode 100644
index 00000000..fd6b4829
--- /dev/null
+++ b/app/views/settings/_data.haml
@@ -0,0 +1,159 @@
+.card
+ .card-body
+ %h2 Your Profile Data
+ %p Everything we have about you! Really, not that much as you might expect.
+
+ %h3 General
+ .row
+ .col-md-6.col-sm-6.col-xs-12
+ %h4 Profile
+
+ %p.font-weight-bold.mb-0 User name
+ %p.text-muted= current_user.screen_name
+
+ %p.font-weight-bold.mb-0 Display name
+ %p.text-muted
+ - if current_user.display_name.blank?
+ None set!
+ - else
+ = current_user.display_name
+
+ %p.font-weight-bold.mb-0 Bio
+ %p.text-muted
+ - if current_user.bio.blank?
+ None set!
+ - else
+ = current_user.bio
+
+ %p.font-weight-bold.mb-0 Location
+ %p.text-muted
+ - if current_user.location.blank?
+ None set!
+ - else
+ = current_user.location
+
+ %p.font-weight-bold.mb-0 Website
+ %p.text-muted
+ - if current_user.website.blank?
+ None set!
+ - else
+ = current_user.website
+ .col-md-6.col-sm-6.col-xs-12
+ %h4 Pictures
+ %p.font-weight-bold.mb-0 Profile picture
+ .media
+ .pull-left
+ %img.profile--img{src: current_user.profile_picture.url(:medium)}
+ .media-body
+ %ul
+ %li
+ %a{href: current_user.profile_picture.url(:small)} Small
+ %li
+ %a{href: current_user.profile_picture.url(:medium)} Medium
+ %li
+ %a{href: current_user.profile_picture.url(:large)} Large
+ %li
+ %a{href: current_user.profile_picture.url(:original)} Original image
+
+ %p.font-weight-bold.mb-0 Header picture
+ %img{src: current_user.profile_header.url(:mobile), style: 'width: 100%'}
+ %p
+ %a{href: current_user.profile_header.url(:mobile)} Mobile
+ |
+ %a{href: current_user.profile_header.url(:web)} Web
+ |
+ %a{href: current_user.profile_header.url(:retina)} Retina
+ |
+ %a{href: current_user.profile_header.url(:original)} Original image
+ .row
+ .col-md-6.col-sm-6.col-xs-12
+ %h4 Statistics
+
+ %p.font-weight-bold.mb-0 Answers
+ %p.text-muted= current_user.answered_count
+
+ %p.font-weight-bold.mb-0 Questions
+ %p.text-muted= current_user.asked_count
+
+ %p.font-weight-bold.mb-0 Following
+ %p.text-muted= current_user.friend_count
+
+ %p.font-weight-bold.mb-0 Followers
+ %p.text-muted= current_user.follower_count
+
+ %p.font-weight-bold.mb-0 Smiles
+ %p.text-muted= current_user.smiled_count + current_user.comment_smiled_count
+
+ %p.font-weight-bold.mb-0 Comments
+ %p.text-muted= current_user.commented_count
+ .col-md-6.col-sm-6.col-xs-12
+ %h4 Badges
+
+ %p.font-weight-bold.mb-0 Admin
+ %p
+ - if current_user.has_role? :administrator
+ %span.label.label-success
+ %i.fa.fa-fw.fa-check
+ - else
+ %span.label.label-danger
+ %i.fa.fa-fw.fa-close
+
+ %p.font-weight-bold.mb-0 Moderator
+ %p
+ - if current_user.mod?
+ %span.label.label-success
+ %i.fa.fa-fw.fa-check
+ - else
+ %span.label.label-danger
+ %i.fa.fa-fw.fa-close
+ .row
+ .col-md-6.col-sm-6.col-xs-12
+ %h3 IP
+ %p.font-weight-bold.mb-0 Current Sign In
+ %p.text-muted= current_user.current_sign_in_ip
+
+ %p.font-weight-bold.mb-0 Last Sign In
+ %p.text-muted= current_user.last_sign_in_ip
+ .col-md-6.col-sm-6.col-xs-12
+ %h3 Miscellaneous
+
+ %p.font-weight-bold.mb-0 Locale
+ %p.text-muted
+ - if current_user.locale.blank?
+ None set!
+ - else
+ = current_user.locale
+
+ %p.font-weight-bold.mb-0 Sign In count
+ %p.text-muted= current_user.sign_in_count
+ %h3 Dates
+ .row
+ .col-md-6.col-sm-6.col-xs-12
+ %h4 Sign In
+
+ %p.font-weight-bold.mb-0 Current Sign In
+ %p.text-muted= current_user.current_sign_in_at ? localize(current_user.current_sign_in_at) : "Not set"
+
+ %p.font-weight-bold.mb-0 Last Sign In
+ %p.text-muted= current_user.last_sign_in_at ? localize(current_user.last_sign_in_at) : "Not set"
+
+ %p.font-weight-bold.mb-0 Remember me set at
+ %p.text-muted= current_user.remember_created_at ? localize(current_user.remember_created_at) : "Not set"
+ .col-md-6.col-sm-6.col-xs-12
+ %h4 Create/Update
+
+ %p.font-weight-bold.mb-0 Account created
+ %p.text-muted
+ - if current_user.created_at
+ = localize(current_user.created_at)
+ = " (#{time_ago_in_words(current_user.created_at)} ago)"
+ - else
+ Not set
+
+ %p.font-weight-bold.mb-0 Account last updated
+ %p.text-muted
+ - if current_user.created_at
+ = localize(current_user.updated_at)
+ = " (#{time_ago_in_words(current_user.updated_at)} ago)"
+ - else
+ Not set
diff --git a/app/views/settings/_export.haml b/app/views/settings/_export.haml
new file mode 100644
index 00000000..91634d2c
--- /dev/null
+++ b/app/views/settings/_export.haml
@@ -0,0 +1,29 @@
+.card
+ .card-body
+ %h2 Export your data
+ %p
+ The data is inside a
+ %code= ".tar.gz"
+ archive and available in three formats: YAML, JSON, and XML. The archive also contains a copy of your
+ profile picture and header picture in all sizes.
+ %p
+ Please note that you can only export your data once a week. Exporting your data
+ will take a while, so please be patient. You will receive a question once exporting
+ is done.
+ - if current_user.can_export?
+ %form{action: begin_user_export_path, method: 'POST'}
+ %p.text-center
+ %button#export-btn.btn.btn-lg.btn-primary{type: :submit} Export
+ = hidden_field_tag :authenticity_token, form_authenticity_token
+ - else
+ %p.text-center
+ %button.btn.btn-lg.btn-primary.disabled{disabled: :disabled} Export
+ %p
+ - if current_user.export_url.nil?
+ Once exporting your account is done, a download link will appear here.
+ - else
+ Here is your export from
+ = succeed ':' do
+ = current_user.export_created_at
+ %a{href: current_user.export_url}
+ = File.basename current_user.export_url
\ No newline at end of file
diff --git a/app/views/settings/_privacy.haml b/app/views/settings/_privacy.haml
new file mode 100644
index 00000000..e3edd407
--- /dev/null
+++ b/app/views/settings/_privacy.haml
@@ -0,0 +1,9 @@
+.card
+ .card-body
+ = bootstrap_form_for(current_user, url: {action: "edit_privacy"}, method: "patch") do |f|
+
+ = f.check_box :privacy_allow_anonymous_questions, label: t('views.settings.privacy.anonymous')
+ = f.check_box :privacy_allow_public_timeline, label: t('views.settings.privacy.public')
+ = f.check_box :privacy_allow_stranger_answers, label: t('views.settings.privacy.stranger')
+
+ = f.submit t('views.actions.save'), class: 'btn btn-primary'
\ No newline at end of file
diff --git a/app/views/settings/_profile.haml b/app/views/settings/_profile.haml
new file mode 100644
index 00000000..1dcd3cda
--- /dev/null
+++ b/app/views/settings/_profile.haml
@@ -0,0 +1,57 @@
+.card
+ .card-body
+ = bootstrap_form_for(current_user, url: {action: "edit"}, :html => { :multipart => true }, method: "patch") do |f|
+
+ = f.text_field :display_name, label: t('views.settings.profile.displayname')
+
+ .media#profile-picture-media
+ .pull-left
+ %img.avatar-lg.mr-3{src: current_user.profile_picture.url(:medium)}
+ .media-body
+ = f.file_field :profile_picture, label: t('views.settings.profile.avatar')
+
+ .row#profile-picture-crop-controls{style: 'display: none;'}
+ .col-sm-10.col-md-8
+ %strong= t('views.settings.profile.avatar_adjust')
+ %img#profile-picture-cropper{src: current_user.profile_picture.url(:medium)}
+ .col-sm-2.col-md-4
+ .btn-group
+ %button#cropper-zoom-out.btn.btn-inverse{type: :button}
+ %i.fa.fa-search-minus
+ %button#cropper-zoom-in.btn.btn-inverse{type: :button}
+ %i.fa.fa-search-plus
+
+ .row.mb-2#profile-header-media
+ .col
+ %img.mw-100.mr-3{src: current_user.profile_header.url(:mobile)}
+ .col-xs-12.mt-3.mt-sm-0.pl-3.pr-3
+ = f.file_field :profile_header, label: t('views.settings.profile.header')
+
+ .row#profile-header-crop-controls{style: 'display: none;'}
+ .col-sm-10.col-md-8
+ %strong= t('views.settings.profile.header_adjust')
+ %img#profile-header-cropper{src: current_user.profile_header.url(:web)}
+ .col-sm-2.col-md-4
+ .btn-group
+ %button#cropper-header-zoom-out.btn.btn-inverse{type: :button}
+ %i.fa.fa-search-minus
+ %button#cropper-header-zoom-in.btn.btn-inverse{type: :button}
+ %i.fa.fa-search-plus
+
+ = f.text_field :motivation_header, label: t('views.settings.profile.motivation'), placeholder: t('views.settings.profile.placeholder.motivation')
+
+ = f.text_field :website, label: t('views.settings.profile.website'), placeholder: 'https://example.com'
+
+ = f.text_field :location, label: t('views.settings.profile.location'), placeholder: t('views.settings.profile.placeholder.location')
+
+ = f.text_area :bio, label: t('views.settings.profile.bio'), placeholder: t('views.settings.profile.placeholder.bio')
+
+ = f.check_box :show_foreign_themes, label: 'Render other user themes when visiting their profile'
+
+ - for attrib in %i(crop_x crop_y crop_w crop_h)
+ = f.hidden_field attrib, id: attrib
+
+ - for attrib in %i(crop_h_x crop_h_y crop_h_w crop_h_h)
+ = f.hidden_field attrib, id: attrib
+
+ = f.submit t('views.actions.save'), class: 'btn btn-primary'
\ No newline at end of file
diff --git a/app/views/settings/_services.haml b/app/views/settings/_services.haml
new file mode 100644
index 00000000..6967f0fc
--- /dev/null
+++ b/app/views/settings/_services.haml
@@ -0,0 +1,19 @@
+.card
+ .card-body
+ - if @services.count > 0
+ = t 'views.settings.service.enabled'
+ - else
+ = t 'views.settings.service.none'
+
+ - APP_CONFIG['sharing'].each do |service, service_options|
+ - if service_options['enabled'] and !@services.any? { |x| x.provider == service.to_s }
+ %p=link_to t('views.settings.service.connect', service: service.capitalize), "/auth/#{service}"
+
+ - if @services.count > 0
+ %ul.list-group
+ - @services.each do |service|
+ %li.list-group-item
+ %i{class: "fa fa-#{service.provider}"}
+ %strong= service.provider.capitalize
+ (#{service.nickname})
+ = link_to t('views.settings.service.disconnect'), service_path(service), data: { confirm: t('views.settings.service.confirm', service: service.provider.capitalize) }, method: :delete
\ No newline at end of file
diff --git a/app/views/settings/_theme.haml b/app/views/settings/_theme.haml
new file mode 100644
index 00000000..53f4ba6f
--- /dev/null
+++ b/app/views/settings/_theme.haml
@@ -0,0 +1,135 @@
+.card
+ .card-body
+ %h1 Theming
+ %p.lead Welcome to the Theme Editor!
+ %p
+ Here you'll be able to modify your Retrospring experience by adjusting all available colors.
+ To further help you with adjusting needs, there are a few example elements using the specified colors, and sections will include
+ descriptions on their general use on the site!
+
+ %p
+ And with that:
+ %b Happy Theming!
+
+ - if current_user.theme
+ .pull-right
+ = button_to 'Delete Theme', delete_user_theme_path, data: { confirm: "Are you sure?" }, tabindex: -1, method: :delete, class: "btn btn-danger"
+= bootstrap_form_for(current_user.theme || Theme.new, url: {action: "update_theme"}, html: {id: 'update_theme'}, method: "patch") do |f|
+ .card
+ .card-body
+ %h2 General
+ %p
+ Here you'll find general page values that are basically visible all across the page.
+ .row
+ .col-sm-6
+ = f.text_field :background_color, class: 'color', data: {default: 0xF0EDF4}
+ .col-sm-6
+ = f.text_field :body_text, class: 'color', data: {default: 0x000000}
+ .card
+ .card-body
+ %h2 Colors
+ %p
+ Colors you can find used on the site. The names of the colors usually describe the context.
+ The "text" colors for all styles represent the color that text on top of these colors has.
+
+ %ul
+ %li
+ %b Primary:
+ The primary/brand color of the site, used for navigation, links, etc.
+ %li
+ %b Danger:
+ Color used for errors or critical actions like deleting something.
+ %li
+ %b Warning:
+ Color used for warnings if something non-critical has happened.
+ %li
+ %b Info:
+ Color used for informational popups or messages.
+ %li
+ %b Success:
+ Color used for messages if something went through successfully.
+ .row
+ .col-sm-6
+ = f.text_field :primary_color, class: 'color', data: {default: 0x5E35B1}
+ .col-sm-6
+ = f.text_field :primary_text, class: 'color', data: {default: 0xFFFFFF}
+ .col-sm-12
+ .alert.alert-primary
+ A simple primary alert—check it out!
+ .row
+ .col-sm-6
+ = f.text_field :danger_color, class: 'color', data: {default: 0xDC3545}
+ .col-sm-6
+ = f.text_field :danger_text, class: 'color', data: {default: 0xFFFFFF}
+ .col-sm-12
+ .alert.alert-danger
+ A simple danger alert—check it out!
+ .row
+ .col-sm-6
+ = f.text_field :warning_color, class: 'color', data: {default: 0xFFC107}
+ .col-sm-6
+ = f.text_field :warning_text, class: 'color', data: {default: 0x292929}
+ .col-sm-12
+ .alert.alert-warning
+ A simple warning alert—check it out!
+ .row
+ .col-sm-6
+ = f.text_field :info_color, class: 'color', data: {default: 0x17A2B8}
+ .col-sm-6
+ = f.text_field :info_text, class: 'color', data: {default: 0xFFFFFF}
+ .col-sm-12
+ .alert.alert-info
+ A simple info alert—check it out!
+ .row
+ .col-sm-6
+ = f.text_field :success_color, class: 'color', data: {default: 0x28A745}
+ .col-sm-6
+ = f.text_field :success_text, class: 'color', data: {default: 0xFFFFFF}
+ .col-sm-12
+ .alert.alert-success
+ A simple success alert—check it out!
+ .row
+ .col-sm-6
+ = f.text_field :dark_color, class: 'color', data: {default: 0x343A40}
+ .col-sm-6
+ = f.text_field :dark_text, class: 'color', data: {default: 0xFFFFFF}
+ .col-sm-12
+ %a.btn.btn-dark.mb-3{ href: '#' } A dark button
+ .row
+ .col-sm-6
+ = f.text_field :light_color, class: 'color', data: {default: 0xF8F9FA}
+ .col-sm-6
+ = f.text_field :light_text, class: 'color', data: {default: 0xFFFFFF}
+ .col-sm-12
+ %a.btn.btn-light.mb-3{ href: '#' } A light button
+ .row
+ .col-sm-6
+ = f.text_field :muted_text, class: 'color', data: {default: 0x6C757D}
+ .col-sm-6
+ %p.pt-4.text-muted Some muted text
+ .card
+ .card-body
+ %h2 Forms and Inputs
+ %p
+ Styles for form inputs, like textfields.
+ .row
+ .col-sm-6
+ = f.text_field :input_color, class: 'color', data: {default: 0xFFFFFF}
+ .col-sm-6
+ = f.text_field :input_text, class: 'color', data: {default: 0x000000}
+ .card
+ .card-body
+ %h2 Raised Content
+ %p
+ Raised content basically describes all the different boxes and panels you can see across the site.
+ .row
+ .col-sm-6
+ = f.text_field :raised_background, class: 'color', data: {default: 0xFFFFFF}
+ .col-sm-6
+ = f.text_field :raised_accent, class: 'color', data: {default: 0xF7F7F7}
+ .card-footer
+ %p Some text on top of a accented area on a raised element!
+ .card
+ .card-body
+ .pull-left
+ = f.submit t('views.actions.save'), class: 'btn btn-primary'
diff --git a/app/views/shared/_announcements.haml b/app/views/shared/_announcements.haml
index 99fa74d6..3f4bab7b 100644
--- a/app/views/shared/_announcements.haml
+++ b/app/views/shared/_announcements.haml
@@ -1,8 +1,10 @@
-.container.announcements
+.announcement__container
- @active_announcements.each do |announcement|
- .alert.alert-announcement.alert-info.alert-dismissable.hidden{ data: { 'announcement-id': announcement.id } }
- %button.close{ type: "button", "data-dismiss" => "alert" }
- %span{ "aria-hidden" => "true" } ×
- %p= announcement.content
- - if announcement.link_present?
- %a.alert-link{ href: announcement.link_href }= announcement.link_text
+ .alert.announcement.alert-info.alert-dismissable.d-none{ data: { 'announcement-id': announcement.id } }
+ .container
+ %button.close{ type: "button", "data-dismiss" => "alert" }
+ %span{ "aria-hidden" => "true" } ×
+ %p
+ = announcement.content
+ - if announcement.link_present?
+ %a.alert-link{ href: announcement.link_href }= announcement.link_text
diff --git a/app/views/shared/_answerbox.html.haml b/app/views/shared/_answerbox.html.haml
deleted file mode 100644
index 350397d5..00000000
--- a/app/views/shared/_answerbox.html.haml
+++ /dev/null
@@ -1,69 +0,0 @@
-.panel.panel-default.answerbox{data: { id: a.id, q_id: a.question.id }}
- - if @question.nil?
- .panel-heading
- .media.question-media
- - unless a.question.author_is_anonymous
- %a.pull-left{href: show_user_profile_path(a.question.user.screen_name)}
- %img.img-rounded.answerbox--img{src: a.question.user.profile_picture.url(:medium)}
- .media-body.question-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
- %ul.dropdown-menu.dropdown-menu-right{role: :menu}
- - if current_user.mod? or a.question.user == current_user
- %li.text-danger
- %a{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
- %li
- %a{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
- .panel-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-md-6.col-sm-4.col-xs-6.text-left.text-muted
- .media
- .pull-left
- %a{href: show_user_profile_path(a.user.screen_name)}
- %img.img-rounded.answerbox--img{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'), "xs"), 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-md-6.col-sm-8.col-xs-6.text-right
- = render 'shared/answerbox_buttons', a: a
- - else
- .row
- .col-md-6.col-sm-4.col-xs-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-md-6.col-sm-8.col-xs-6.text-right
- = render 'shared/answerbox_buttons', a: a
- .panel-footer{id: "ab-comments-section-#{a.id}", style: @display_all.nil? ? 'display: none' : nil }
- %div{id: "ab-smiles-#{a.id}"}= render 'shared/smiles', a: a
- %div{id: "ab-comments-#{a.id}"}= render 'shared/comments', a: a
diff --git a/app/views/shared/_answerbox_buttons.html.haml b/app/views/shared/_answerbox_buttons.html.haml
deleted file mode 100644
index b8de32c4..00000000
--- a/app/views/shared/_answerbox_buttons.html.haml
+++ /dev/null
@@ -1,45 +0,0 @@
-%span.hidden-xs.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-info.btn-sm{type: :button, name: 'ab-smile', data: { a_id: a.id, action: :unsmile }}
- %i.fa.fa-frown-o
- %span{id: "ab-smile-count-#{a.id}"}= a.smile_count
- - else
- %button.btn.btn-info.btn-sm{type: :button, name: 'ab-smile', data: { a_id: a.id, action: :smile }}
- %i.fa.fa-smile-o
- %span{id: "ab-smile-count-#{a.id}"}= a.smile_count
-- unless @display_all
- %button.btn.btn-primary.btn-sm{type: :button, name: 'ab-comments', data: { a_id: a.id, state: :hidden }}
- %i.fa.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
- %ul.dropdown-menu.dropdown-menu-right{role: :menu}
- - if Subscription.is_subscribed(current_user, a)
- %li
- -# fun joke should subscribe?
- %a{href: '#', data: { a_id: a.id, action: 'ab-submarine', torpedo: "no" }}
- %i.fa.fa-anchor
- = t 'views.actions.unsubscribe'
- - else
- %li
- %a{href: '#', data: { a_id: a.id, action: 'ab-submarine', torpedo: "yes" }}
- %i.fa.fa-anchor
- = t 'views.actions.subscribe'
- - if privileged? a.user
- %li.text-danger
- %a{href: '#', data: { a_id: a.id, action: 'ab-destroy' }}
- %i.fa.fa-trash-o
- = t 'views.actions.return'
- - unless a.user == current_user
- %li
- %a{href: '#', data: { a_id: a.id, action: 'ab-report' }}
- %i.fa.fa-exclamation-triangle
- = t 'views.actions.report'
diff --git a/app/views/shared/_comments.html.haml b/app/views/shared/_comments.html.haml
deleted file mode 100644
index e4435611..00000000
--- a/app/views/shared/_comments.html.haml
+++ /dev/null
@@ -1,55 +0,0 @@
-- if a.comments.all.count == 0
- = t 'views.answerbox.no_comment'
-- else
- %ul.comments
- - a.comments.order(:created_at).each do |comment|
- %li{data: { comment_id: comment.id }}
- %div{class: "ab-comment-smile-list", style: "height: 0; width: 0"}= render "shared/comment_smiles", comment: comment
- .media.comments--media
- .pull-left
- %img.img-rounded.answerbox--img{src: comment.user.profile_picture.url(:medium)}
- .media-body.comments--body
- %h6.media-heading.answerbox--question-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"
- .pull-right
- %span.hidden-xs.text-muted
- - unless user_signed_in?
- - if comment.smile_count > 0
- %button.btn.btn-info.btn-sm{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-info.btn-sm{type: :button, name: 'ab-smile-comment', data: { c_id: comment.id, action: :unsmile }}
- %i.fa.fa-frown-o
- %span{id: "ab-comment-smile-count-#{comment.id}"}= comment.smile_count
- - else
- %button.btn.btn-info.btn-sm{type: :button, name: 'ab-smile-comment', data: { c_id: comment.id, action: :smile }}
- %i.fa.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
- %ul.dropdown-menu.dropdown-menu-right{role: :menu}
- %li
- %a{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)
- %li.text-danger
- %a{href: '#', data: { action: 'ab-comment-destroy', c_id: comment.id }}
- %i.fa.fa-trash-o
- = t 'views.actions.delete'
- - unless comment.user == current_user
- %li
- %a{href: '#', data: { action: 'ab-comment-report', c_id: comment.id }}
- %i.fa.fa-exclamation-triangle
- = t 'views.acions.report'
- .comments--content
- = markdown comment.content
-- if user_signed_in?
- .form-group.has-feedback{name: 'ab-comment-new-group', data: { a_id: a.id }}
- %input.form-control.comments--box{type: :text, placeholder: t('views.placeholder.comment'), name: 'ab-comment-new', data: {a_id: a.id }}
- %span.text-muted.form-control-feedback.comments--count{id: "ab-comment-charcount-#{a.id}"} 160
diff --git a/app/views/shared/_links.html.haml b/app/views/shared/_links.html.haml
index f943e838..2c85b582 100644
--- a/app/views/shared/_links.html.haml
+++ b/app/views/shared/_links.html.haml
@@ -1,4 +1,4 @@
-.centre.text-muted.links
+.text-center.text-muted.pb-3
©
= Date.today.year
= APP_CONFIG['site_name']
diff --git a/app/views/shared/_locales.haml b/app/views/shared/_locales.haml
index 70a187f5..36b3e4cc 100644
--- a/app/views/shared/_locales.haml
+++ b/app/views/shared/_locales.haml
@@ -4,7 +4,7 @@
%a{href: '#', id: 'locale-switch'}
%i.fa.fa-globe
= t('views.locale.languages')
- #locales-panel
+ #locales-panel.locales__panel
%ul
- APP_LOCALES.each do |key, value|
%li
diff --git a/app/views/shared/_question.html.haml b/app/views/shared/_question.html.haml
index d86502d0..677c73ac 100644
--- a/app/views/shared/_question.html.haml
+++ b/app/views/shared/_question.html.haml
@@ -1,11 +1,11 @@
- type ||= nil
-.panel.panel-default.questionbox{data: { id: q.id }}
- .panel-body
+.card{data: { id: q.id }}
+ .card-body
.media
- if type == "discover"
.pull-left
%a{href: user_screen_name(q.user, link_only: true)}
- %img.answerbox--img{src: q.user&.profile_picture&.url(:medium)}
+ %img.avatar-md.mr-2{src: q.user&.profile_picture&.url(:medium)}
.media-body
- if user_signed_in?
.pull-right
@@ -23,11 +23,11 @@
%a{href: '#', tabindex: -1, data: { action: 'ab-question-report', q_id: q.id }}
%i.fa.fa-exclamation-triangle
= t 'views.actions.report'
- %h6.media-heading.text-muted.answerbox--question-user
+ %h6.media-heading.text-muted.answerbox__question-user
= raw t('views.answerbox.asked', user: user_screen_name(q.user), time: time_tooltip(q))
- if q.answer_count > 1
·
%a{href: show_user_question_path(q.user.screen_name, q.id)}
= pluralize(q.answer_count, t('views.general.answer'))
- %p.answerbox--question-text
+ %p.answerbox__question-text
= q.content
diff --git a/app/views/shared/_sidebar.haml b/app/views/shared/_sidebar.haml
new file mode 100644
index 00000000..205d49ad
--- /dev/null
+++ b/app/views/shared/_sidebar.haml
@@ -0,0 +1,21 @@
+.card.userbox
+ %img.userbox__header{src: current_user.profile_header.url(:mobile)}
+ .card-body
+ %img.userbox__avatar{src: current_user.profile_picture.url(:small)}
+ .profile__name
+ - unless current_user.display_name.blank?
+ .profile__display-name
+ = current_user.display_name
+ .profile__screen-name
+ = current_user.screen_name
+- unless @group.nil?
+ .card
+ .card-header= t('views.group.members')
+ .card-body
+ - if @group.members.empty?
+ %p.text-muted No members yet!
+ - @group.members.each do |member|
+ %a{href: show_user_profile_path(member.user.screen_name), title: member.user.screen_name, data: { toggle: :tooltip, placement: :top }}
+ %img.avatar-xs{src: member.user.profile_picture.url(:medium)}
+
+= render 'shared/links'
diff --git a/app/views/shared/_sidebar.html.haml b/app/views/shared/_sidebar.html.haml
deleted file mode 100644
index 645f2e8d..00000000
--- a/app/views/shared/_sidebar.html.haml
+++ /dev/null
@@ -1,41 +0,0 @@
-- header_class = if current_user.profile_header.exists? then "userbox--header-container" else "userbox--no-header" end
-.panel.panel-default.hidden-xs
- %div{class: header_class}
- %img.userbox--header{src: current_user.profile_header.url(:mobile)}
- .panel-body
- %img.userbox--avatar{src: current_user.profile_picture.url(:small)}
- %p.userbox--username
- - if current_user.display_name.blank?
- %span.profile--displayname
- = current_user.screen_name
- - else
- %span.profile--displayname
- = current_user.display_name
- %span.profile--username
- = current_user.screen_name
- .row
- %a{href: show_user_followers_path(current_user.screen_name)}
- .col-md-6.col-sm-6.col-xs-6
- %h4.entry-text#follower-count= current_user.follower_count
- %h6.entry-subtext= t('views.general.follower').pluralize(current_user.follower_count)
- %a{href: show_user_friends_path(current_user.screen_name)}
- .col-md-6.col-sm-6.col-xs-6
- %h4.entry-text#friend-count= current_user.friend_count
- %h6.entry-subtext= t('views.general.following')
-.panel.panel-default.hidden-xs
- .list-group
- = list_group_item t('views.general.timeline'), root_path
- - if APP_CONFIG.dig(:features, :public, :enabled)
- = list_group_item t('views.general.public'), public_timeline_path
- - current_user.groups.each do |group|
- = list_group_item group.display_name, group_timeline_path(group.name)
-- unless @group.nil?
- .panel.panel-default.profile--panel.hidden-xs
- .panel-heading
- %h3.panel-title= t('views.group.members')
- .panel-body
- - @group.members.each do |member|
- %a{href: show_user_profile_path(member.user.screen_name), title: member.user.screen_name, data: { toggle: :tooltip, placement: :top }}
- %img.img-rounded.answerbox--img-small{src: member.user.profile_picture.url(:medium)}
-
-.hidden-xs= render 'shared/links'
diff --git a/app/views/shared/_userbox.haml b/app/views/shared/_userbox.haml
new file mode 100644
index 00000000..67a4472e
--- /dev/null
+++ b/app/views/shared/_userbox.haml
@@ -0,0 +1,12 @@
+- type ||= @type || :nil
+.card.h-100.userbox
+ %img.userbox__header{src: user.profile_header.url(:mobile)}
+ .card-body
+ %img.userbox__avatar{src: user.profile_picture.url(:small)}
+ %a.profile__name{href: show_user_profile_path(user.screen_name)}
+ - unless user.display_name.blank?
+ .profile__display-name
+ = user.display_name
+ .profile__screen-name
+ = user.screen_name
+ = render 'user/actions', user: user, type: type
diff --git a/app/views/shared/_userbox.html.haml b/app/views/shared/_userbox.html.haml
deleted file mode 100644
index c8826f90..00000000
--- a/app/views/shared/_userbox.html.haml
+++ /dev/null
@@ -1,24 +0,0 @@
-- type ||= @type || :nil
-- header_class = if user.profile_header.exists? then "userbox--header-container" else "userbox--no-header" end
-.panel.panel-default
- %div{class: header_class}
- %img.userbox--header{src: user.profile_header.url(:mobile)}
- .panel-body
- %img.userbox--avatar{src: user.profile_picture.url(:small)}
- %p.userbox--username
- - if user.display_name.blank?
- %a.profile--displayname{href: show_user_profile_path(user.screen_name)}
- = user.screen_name
- - else
- %a.profile--displayname{href: show_user_profile_path(user.screen_name)}
- = user.display_name
- %span.profile--username
- = user.screen_name
- .row
- .col-md-6.col-sm-6.col-xs-6
- %h4.entry-text#asked-count= user.asked_count
- %h6.entry-subtext= t('views.general.question').pluralize(user.asked_count)
- .col-md-6.col-sm-6.col-xs-6
- %h4.entry-text#answered-count= user.answered_count
- %h6.entry-subtext= t('views.general.answer').pluralize(user.answered_count)
- = render 'user/actions', user: user, type: type
diff --git a/app/views/static/_mobile_nav.html.haml b/app/views/static/_mobile_nav.html.haml
deleted file mode 100644
index 24304d95..00000000
--- a/app/views/static/_mobile_nav.html.haml
+++ /dev/null
@@ -1,14 +0,0 @@
-%nav.navbar.navbar-default.navbar-static-top.j2-navbar.visible-xs{role: "navigation"}
- .container
- .navbar-header
- %button.navbar-toggle{"data-target" => "#j2-tl-navbar-collapse", "data-toggle" => "collapse", type: "button"}
- %span.sr-only Toggle navigation
- %span.icon-bar
- %span.icon-bar
- %span.icon-bar
- %a.navbar-brand{href: "/"} Timelines
- #j2-tl-navbar-collapse.collapse.navbar-collapse
- %ul.nav.navbar-nav
- = nav_entry "Public", public_timeline_path
- - current_user.groups.each do |group|
- = nav_entry group.display_name, group_timeline_path(group.name)
diff --git a/app/views/static/about.html.haml b/app/views/static/about.haml
similarity index 54%
rename from app/views/static/about.html.haml
rename to app/views/static/about.haml
index e657ced4..dddc544c 100644
--- a/app/views/static/about.html.haml
+++ b/app/views/static/about.haml
@@ -1,30 +1,30 @@
- provide(:title, generate_title("About"))
-.jumbotron.j2-jumbo.text-center.particle-jumbotron
- #particles
- .particle-content
+.jumbotron.jumbotron--particles
+ #particles.jumbotron__particles
+ .jumbotron__content
%h1= APP_CONFIG['site_name']
%p= t 'views.about.subtitle'
.container
- .panel.panel-default
- .panel-body
+ .card
+ .card-body
.row
.col-md-4
%h3= t 'views.about.links.title'
%p= t('views.about.links.desc', app_title: APP_CONFIG['site_name'])
.col-md-4.col-sm-6
%a{href: "https://twitter.com/retrospring"}
- .icon-showcase
+ .icon--showcase
%i.fa.fa-twitter
%h4.heading-about.text-center
Twitter
.col-md-4.col-sm-6
%a{href: help_faq_path}
- .icon-showcase
+ .icon--showcase
%i.fa.fa-question
%h4.heading-about.text-center
FAQ
- .panel.panel-default
- .panel-body
+ .card
+ .card-body
.row
.col-md-4
%h3= t 'views.about.opensource.title'
@@ -32,29 +32,34 @@
%p= raw t('views.about.opensource.desc', app_title: APP_CONFIG['site_name'], github: link_to(t('views.about.opensource.github'), "https://github.com/Retrospring/retrospring"), bugtracker: link_to(t('views.about.opensource.bugtracker'), "https://github.com/Retrospring/retrospring/issues"))
.col-md-4
%a{href: "https://github.com/Retrospring/retrospring"}
- .icon-showcase
+ .icon--showcase
%i.fa.fa-github
%h4.heading-about.text-center= t 'views.about.repository.title'
%p.text-center
%em= t 'views.about.repository.desc'
- .panel.panel-default
- .panel-body
+ .card
+ .card-body
.row
.col-md-3.col-sm-12.col-xs-12
%h3= t 'views.about.statistics.title'
%p= t('views.about.statistics.desc', app_title: APP_CONFIG['site_name'])
- .col-md-3.col-sm-6.col-xs-6.statistics
- %h2.entry-text#asked-count= Question.count
- %h4.entry-subtext= t('views.general.question').pluralize(Question.count)
- %h2.entry-text#answered-count= Answer.count
- %h4.entry-subtext= t('views.general.answer').pluralize(Answer.count)
- .col-md-3.col-sm-6.col-xs-6.statistics
- %h2.entry-text#comment-count= Comment.count
- %h4.entry-subtext= t('views.general.comment').pluralize(Comment.count)
- %h2.entry-text#smile-count= Smile.count + CommentSmile.count
- %h4.entry-subtext= t('views.general.smile').pluralize(Smile.count)
- .col-md-3.col-sm-12.col-xs-12.users
- .entry-text#follower-count= User.count
- %h6.entry-subtext= t('views.general.user').pluralize(User.count)
+ .col-md-3.col-sm-6.col-xs-6
+ .entry.entry--statistics
+ %h2.entry__value#asked-count= Question.count
+ %h4.entry__description= t('views.general.question').pluralize(Question.count)
+ .entry.entry--statistics
+ %h2.entry__value#answered-count= Answer.count
+ %h4.entry__description= t('views.general.answer').pluralize(Answer.count)
+ .col-md-3.col-sm-6.col-xs-6
+ .entry.entry--statistics
+ %h2.entry__value#comment-count= Comment.count
+ %h4.entry__description= t('views.general.comment').pluralize(Comment.count)
+ .entry.entry--statistics
+ %h2.entry__value#smile-count= Smile.count + CommentSmile.count
+ %h4.entry__description= t('views.general.smile').pluralize(Smile.count)
+ .col-md-3.col-sm-12.col-xs-12
+ .entry.entry--users
+ .entry__value#follower-count= User.count
+ %h4.entry__description= t('views.general.user').pluralize(User.count)
= render "shared/links"
diff --git a/app/views/static/faq.html.haml b/app/views/static/faq.html.haml
index 774d998a..0b126b30 100644
--- a/app/views/static/faq.html.haml
+++ b/app/views/static/faq.html.haml
@@ -1,13 +1,13 @@
- provide(:title, generate_title("Frequently Asked Questions"))
-.jumbotron.j2-jumbo.text-center.particle-jumbotron
- #particles
- .particle-content
+.jumbotron.jumbotron--particles
+ #particles.jumbotron__particles
+ .jumbotron__content
%h1 Frequently Asked Questions
%p
Everything you want to know about
= succeed '!' do
= APP_CONFIG['site_name']
.container
- .panel.panel-default
- .panel-body
+ .card
+ .card-body
= raw_markdown_io "service-docs/en/help/faq.md"
diff --git a/app/views/static/front.html.haml b/app/views/static/front.html.haml
index b220c168..c3dcb866 100644
--- a/app/views/static/front.html.haml
+++ b/app/views/static/front.html.haml
@@ -1,114 +1,115 @@
- provide(:title, "#{APP_CONFIG['site_name']}")
-.jumbotron.j2-jumbo.text-center.particle-jumbotron.frontpage
- .frontpage-scroll
+.jumbotron.jumbotron--particles.jumbotron--frontpage
+ .jumbotron__scroller
%a.arctic_scroll{href: "#content", data: {offset: "-80"} }
%i.fa.fa-chevron-down
- #particles
- .particle-content.frontpage-content
+ #particles.jumbotron__particles
+ .jumbotron__content
.container
= render 'layouts/messages'
%h1= APP_CONFIG['site_name']
%p= t 'views.front.subtitle'
%p
- %a.btn.btn-register.btn-lg{href: url_for(new_user_registration_path)}
+ %a.btn.btn-outline-light.btn-lg{href: url_for(new_user_registration_path)}
Register now
%small
Already a member?
= link_to 'Sign in', new_user_session_path
-.container-fluid#content
- .container.text-center
- %h1.frontpage-heading= "What is #{APP_CONFIG['site_name']}?"
- %p.lead
- A
- %abbr{title: "Question and Answer"} Q/A
- based social network
- %p Most of the people already know how these sorts of networks already work. You have a profile and other users (or even anonymous people without accounts) can ask you any question to find out more about you, so can you do the same with others. Finding friends with the same interests, people that share your opinion (and people that probably don't), you can find everything here!
- %p.lead
- But what makes
- = APP_CONFIG['site_name']
- special?
- %p
- = APP_CONFIG['site_name']
- tries to take aspects from other popular or now gone platforms and combine them to get the best result possible. Also, we take in the ideas and feedback of our community so we can build a service that's even closer to being exactly the service people want to use!
-
- .container.frontpage-features
- %h2.features-heading.text-center Awesome Features
- .row
- .col-md-4.col-sm-4.col-xs-12
- %h3.heading-showcase
- %i.fa.fa-fw.fa-comments.colored-icon
- Discussion
- %p= "With #{APP_CONFIG['site_name']}, you can ask and answer questions from other users as well as receive anonymous questions. Want to know something? Keep the conversation alive with interactive comments."
- .col-md-4.col-sm-4.col-xs-12
- %h3.heading-showcase
- %i.fa.fa-fw.fa-user-plus.colored-icon
- Following
- %p
- Following users allows you to get a personalized feed of all people you want to know more about. You can also send a question to all your followers at once!
- .col-md-4.col-sm-4.col-xs-12
- %h3.heading-showcase
- %i.fa.fa-fw.fa-share-square-o.colored-icon
- Sharing
- %p
- Want to share your answer to a question so that more people read it? With a simple click on the answer button, your answer is shared wherever you want!
- .row
- .col-md-4.col-sm-4.col-xs-12
- %h3.heading-showcase
- %i.fa.fa-fw.fa-users.colored-icon
- Groups
- %p
- Want to ask a question to a specific set of people? No problem! Set up unique groups of users and send them questions apart from everyone else.
- .col-md-4.col-sm-4.col-xs-12
- %h3.heading-showcase
- %i.fa.fa-fw.fa-image.colored-icon
- Images
- %p
- Express yourself with images and upload an avatar and a header of your liking. And soon you'll be able to attach images to answers and questions as well!
- .col-md-4.col-sm-4.col-xs-12
- %h3.heading-showcase
- %i.fa.fa-fw.fa-paint-brush.colored-icon
- Themes
- %p
- Don't like the default purple or don't like light interfaces in general? On
- = APP_CONFIG['site_name']
- you can change every color aspect of the site with Themes!
- .row
- .col-md-4.col-sm-4.col-xs-12
- %h3.heading-showcase
- %i.fa.fa-fw.fa-globe.colored-icon
- Open Source
- %p
- You heard it right!
- = APP_CONFIG['site_name']
- and all of it's core components are open source! Everyone can help and improve the service!
- .col-md-4.col-sm-4.col-xs-12
- %h3.heading-showcase
- %i.fa.fa-fw.fa-eye-slash.colored-icon
- No Ads
- %p
- We don't like them ourselves, really.
- = APP_CONFIG['site_name']
- just runs with community funding over
- %a{href: "https://patreon.com/retrospring"} Patreon
- which is way better than displaying annoying stuff.
- .col-md-4.col-sm-4.col-xs-12
- %h3.heading-showcase
- %i.fa.fa-fw.fa-user-secret.colored-icon
- Your Data is yours
- %p
- Today the most precious things on the internet is your data.
- = APP_CONFIG['site_name']
- doesn't sell any data that is collected. It remains encrypted on our servers!
-.container-fluid.frontpage-fluid
+#content.container.text-center
+ %h1= "What is #{APP_CONFIG['site_name']}?"
+ %p.lead
+ A
+ %abbr{title: "Question and Answer"} Q/A
+ based social network
+ %p Most of the people already know how these sorts of networks already work. You have a profile and other users (or even anonymous people without accounts) can ask you any question to find out more about you, so can you do the same with others. Finding friends with the same interests, people that share your opinion (and people that probably don't), you can find everything here!
+ %p.lead
+ But what makes
+ = APP_CONFIG['site_name']
+ special?
%p
- Any questions? Ask us on
- %a{href: "https://twitter.com/retrospring"} Twitter
-.container.text-center#register
+ = APP_CONFIG['site_name']
+ tries to take aspects from other popular or now gone platforms and combine them to get the best result possible. Also, we take in the ideas and feedback of our community so we can build a service that's even closer to being exactly the service people want to use!
+
+
+ %h2 Awesome Features
+ .row
+ .col-md-4.col-sm-4.col-xs-12
+ %h3
+ %i.fa.fa-fw.fa-comments.text-primary
+ Discussion
+ %p= "With #{APP_CONFIG['site_name']}, you can ask and answer questions from other users as well as receive anonymous questions. Want to know something? Keep the conversation alive with interactive comments."
+ .col-md-4.col-sm-4.col-xs-12
+ %h3
+ %i.fa.fa-fw.fa-user-plus.text-primary
+ Following
+ %p
+ Following users allows you to get a personalized feed of all people you want to know more about. You can also send a question to all your followers at once!
+ .col-md-4.col-sm-4.col-xs-12
+ %h3
+ %i.fa.fa-fw.fa-share-square-o.text-primary
+ Sharing
+ %p
+ Want to share your answer to a question so that more people read it? With a simple click on the answer button, your answer is shared wherever you want!
+ .row
+ .col-md-4.col-sm-4.col-xs-12
+ %h3
+ %i.fa.fa-fw.fa-users.text-primary
+ Groups
+ %p
+ Want to ask a question to a specific set of people? No problem! Set up unique groups of users and send them questions apart from everyone else.
+ .col-md-4.col-sm-4.col-xs-12
+ %h3
+ %i.fa.fa-fw.fa-image.text-primary
+ Images
+ %p
+ Express yourself with images and upload an avatar and a header of your liking. And soon you'll be able to attach images to answers and questions as well!
+ .col-md-4.col-sm-4.col-xs-12
+ %h3
+ %i.fa.fa-fw.fa-paint-brush.text-primary
+ Themes
+ %p
+ Don't like the default purple or don't like light interfaces in general? On
+ = APP_CONFIG['site_name']
+ you can change every color aspect of the site with Themes!
+ .row
+ .col-md-4.col-sm-4.col-xs-12
+ %h3
+ %i.fa.fa-fw.fa-globe.text-primary
+ Open Source
+ %p
+ You heard it right!
+ = APP_CONFIG['site_name']
+ and all of it's core components are open source! Everyone can help and improve the service!
+ .col-md-4.col-sm-4.col-xs-12
+ %h3
+ %i.fa.fa-fw.fa-eye-slash.text-primary
+ No Ads
+ %p
+ We don't like them ourselves, really.
+ = APP_CONFIG['site_name']
+ just runs with community funding over
+ %a{href: "https://patreon.com/retrospring"} Patreon
+ which is way better than displaying annoying stuff.
+ .col-md-4.col-sm-4.col-xs-12
+ %h3
+ %i.fa.fa-fw.fa-user-secret.text-primary
+ Your Data is yours
+ %p
+ Today the most precious things on the internet is your data.
+ = APP_CONFIG['site_name']
+ doesn't sell any data that is collected. It remains encrypted on our servers!
+
+ .card
+ .card-body
+ %p
+ Any questions? Ask us on
+ %a{href: "https://twitter.com/retrospring"} Twitter
+
%h2 What are you waiting for?
%p
Registering takes less than 5 minutes!
%p
- %a.btn.btn-primary.btn-lg.register-now{href: url_for(new_user_registration_path)}
+ %a.btn.btn-primary.btn-lg{href: url_for(new_user_registration_path)}
Register now
= render "shared/links"
diff --git a/app/views/static/index.haml b/app/views/static/index.haml
new file mode 100644
index 00000000..5b4eda6d
--- /dev/null
+++ b/app/views/static/index.haml
@@ -0,0 +1,12 @@
+#timeline
+ - @timeline.each do |answer|
+ = render 'answerbox', a: answer
+
+ = render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @timeline_last_id
+
+ - if @more_data_available
+ %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @timeline_last_id }}
+ Load more
+
+- provide(:title, "#{APP_CONFIG['site_name']}")
+- parent_layout "feed"
\ No newline at end of file
diff --git a/app/views/static/index.html.haml b/app/views/static/index.html.haml
deleted file mode 100644
index 8318e9b7..00000000
--- a/app/views/static/index.html.haml
+++ /dev/null
@@ -1,17 +0,0 @@
-- provide(:title, "#{APP_CONFIG['site_name']}")
-= render 'static/mobile_nav'
-.container.j2-page
- .col-md-3.col-sm-4
- = render 'shared/sidebar'
- .col-md-9.col-xs-12.col-sm-8.j2-col-reset
- = render 'layouts/messages'
- #timeline
- - @timeline.each do |answer|
- = render 'shared/answerbox', a: answer
-
- = render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @timeline_last_id
-
- - if @more_data_available
- %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @timeline_last_id }}
- Load more
- .visible-xs= render 'shared/links'
diff --git a/app/views/static/index.js.erb b/app/views/static/index.js.erb
index fd1ddb36..59591f8d 100644
--- a/app/views/static/index.js.erb
+++ b/app/views/static/index.js.erb
@@ -1,5 +1,5 @@
$('#timeline').append('<% @timeline.each do |answer|
- %><%= j render 'shared/answerbox', a: answer
+ %><%= j render 'answerbox', a: answer
%><% end %>');
<% if @more_data_available %>
$('#pagination').html('<%= j render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @timeline_last_id %>');
diff --git a/app/views/static/privacy_policy.html.haml b/app/views/static/privacy_policy.html.haml
index ef1c8daf..15c9f8aa 100644
--- a/app/views/static/privacy_policy.html.haml
+++ b/app/views/static/privacy_policy.html.haml
@@ -1,5 +1,5 @@
- provide(:title, generate_title("Privacy Policy"))
-.container.j2-page
- .panel.panel-default
- .panel-body
+.container.container--main
+ .card
+ .card-body
= raw_markdown_io "service-docs/en/policy/privacy.md"
diff --git a/app/views/static/terms.html.haml b/app/views/static/terms.html.haml
index 0d44d6da..792ede73 100644
--- a/app/views/static/terms.html.haml
+++ b/app/views/static/terms.html.haml
@@ -1,5 +1,5 @@
- provide(:title, generate_title("Terms of Service"))
-.container.j2-page
- .panel.panel-default
- .panel-body
+.container.container--main
+ .card
+ .card-body
= raw_markdown_io "service-docs/en/policy/terms.md"
diff --git a/app/views/tabs/_feed.haml b/app/views/tabs/_feed.haml
new file mode 100644
index 00000000..8ee4fc1c
--- /dev/null
+++ b/app/views/tabs/_feed.haml
@@ -0,0 +1,25 @@
+.card
+ .list-group.list-group-horizontal-sm.text-center
+ = list_group_item t('views.general.timeline'), root_path
+ - if APP_CONFIG.dig(:features, :public, :enabled)
+ = list_group_item t('views.general.public'), public_timeline_path
+ .list-group-item.list-group-item-action.dropdown{class: "#{'active' if @group}"}
+ %a.dropdown-toggle{ type: 'button', data: { toggle: 'dropdown' }, aria: { haspopup: true, expanded: false }}
+ - if @group
+ = @group.display_name
+ - else
+ Groups
+ .dropdown-menu
+ - if current_user.groups.empty?
+ .p-3
+ %p Looks like you don't have any groups yet.
+ %p
+ You can create groups and add users to them using the
+ %i.fa.fa-fw.fa-users
+ icon in the navigation on user profiles that are not yours.
+ %p.mb-0
+ Once you have done that, the groups will be listed here and
+ when selected, you'll get a timeline view of all users from
+ that group.
+ - current_user.groups.each do |group|
+ %a.dropdown-item{ href: group_timeline_path(group.name) }= group.display_name
\ No newline at end of file
diff --git a/app/views/tabs/_moderation.haml b/app/views/tabs/_moderation.haml
new file mode 100644
index 00000000..180922c7
--- /dev/null
+++ b/app/views/tabs/_moderation.haml
@@ -0,0 +1,10 @@
+.card.d-none.d-sm-block
+ .list-group
+ = list_group_item t('views.moderation.tabs.all'), moderation_path
+ = list_group_item t('views.general.answer').pluralize(2), moderation_path('answer')
+ = list_group_item t('views.general.comment').pluralize(2), moderation_path('comment')
+ = list_group_item t('views.general.user').pluralize(2), moderation_path('user')
+ = list_group_item t('views.general.question').pluralize(2), moderation_path('question')
+ = list_group_item 'Priority', moderation_priority_path
+
+.d-none.d-sm-block= render "shared/links"
\ No newline at end of file
diff --git a/app/views/tabs/_notifications.haml b/app/views/tabs/_notifications.haml
new file mode 100644
index 00000000..d282b911
--- /dev/null
+++ b/app/views/tabs/_notifications.haml
@@ -0,0 +1,16 @@
+.card.d-none.d-sm-block
+ .list-group
+ = list_group_item "New Notifications", notifications_path, badge: Notification.for(current_user).where(new: true).count
+ = list_group_item "All Notifications", notifications_path('all')
+
+.card.d-none.d-sm-block
+ .card-header
+ Filter by Type
+ .list-group
+ = list_group_item t('views.notifications.tabs.answer'), notifications_path('answer'), badge: Notification.for(current_user).where(target_type: "Answer", new: true).count
+ = list_group_item t('views.notifications.tabs.smile'), notifications_path('smile'), badge: Notification.for(current_user).where(target_type: "Smile", new: true).count
+ = list_group_item t('views.notifications.tabs.comment'), notifications_path('comment'), badge: Notification.for(current_user).where(target_type: "Comment", new: true).count
+ = list_group_item t('views.notifications.tabs.commentsmile'), notifications_path('commentsmile'), badge: Notification.for(current_user).where(target_type: "CommentSmile", new: true).count
+ = list_group_item t('views.notifications.tabs.relationship'), notifications_path('relationship'), badge: Notification.for(current_user).where(target_type: "Relationship", new: true).count
+
+.d-none.d-sm-block= render "shared/links"
\ No newline at end of file
diff --git a/app/views/tabs/_profile.haml b/app/views/tabs/_profile.haml
new file mode 100644
index 00000000..f49f17dd
--- /dev/null
+++ b/app/views/tabs/_profile.haml
@@ -0,0 +1,6 @@
+.card
+ .list-group.list-group-horizontal-sm.text-center
+ = list_group_item "Answers", show_user_profile_path(@user.screen_name), badge: @user.answered_count
+ = list_group_item "Questions", show_user_questions_path(@user.screen_name), badge: @user.asked_count
+ = list_group_item "Followers", show_user_followers_path(@user.screen_name), badge: @user.follower_count
+ = list_group_item "Following", show_user_friends_path(@user.screen_name), badge: @user.friend_count
\ No newline at end of file
diff --git a/app/views/tabs/_settings.haml b/app/views/tabs/_settings.haml
new file mode 100644
index 00000000..a3b91589
--- /dev/null
+++ b/app/views/tabs/_settings.haml
@@ -0,0 +1,11 @@
+.card
+ .list-group
+ = list_group_item t('views.settings.tabs.account'), edit_user_registration_path
+ = list_group_item t('views.settings.tabs.profile'), edit_user_profile_path
+ = list_group_item t('views.settings.tabs.privacy'), edit_user_privacy_path
+ = list_group_item t('views.settings.tabs.sharing'), services_path
+ = list_group_item 'Theme', edit_user_theme_path
+ = list_group_item "Your Data", user_data_path
+ = list_group_item 'Export', user_export_path
+
+.d-none.d-sm-block= render "shared/links"
\ No newline at end of file
diff --git a/app/views/user/_account.html.haml b/app/views/user/_account.html.haml
deleted file mode 100644
index 82f933e1..00000000
--- a/app/views/user/_account.html.haml
+++ /dev/null
@@ -1,45 +0,0 @@
-- provide(:title, generate_title("Account Settings"))
-.container.j2-page
- = render 'user/settings_tabs'
- .col-md-9.col-xs-12.col-sm-8
- = render 'layouts/messages'
- .panel.panel-default
- .panel-body
- = bootstrap_form_for(resource, as: resource_name, url: '/settings/account', html: { method: :put }) do |f|
- / Password field modal
- #modal-passwd.modal.fade{"aria-hidden" => "true", "aria-labelledby" => "modal-passwd-label", :role => "dialog", :tabindex => "-1"}
- .modal-dialog
- .modal-content
- .modal-header
- %button.close{"data-dismiss" => "modal", :type => "button"}
- %span{"aria-hidden" => "true"} ×
- %span.sr-only= t 'views.actions.close'
- %h4#modal-passwd-label.modal-title= t 'views.settings.account.modal.title'
- .modal-body
- = f.password_field :current_password, autocomplete: "off", label: t('views.settings.account.password_current'), help: t('views.settings.account.password_current_help')
- .modal-footer
- %button.btn.btn-default{"data-dismiss" => "modal", :type => "button"}= t 'views.actions.cancel'
- %button.btn.btn-primary{:type => "submit"}= t 'views.actions.save'
-
- = devise_error_messages!
-
- = f.text_field :screen_name, autofocus: true, label: t('views.settings.account.username')
-
- = f.email_field :email, label: t('views.settings.account.email')
- - if devise_mapping.confirmable? && resource.pending_reconfirmation?
- %div= raw t('views.settings.account.email_confirm', resource: resource.unconfirmed_email)
-
- = f.password_field :password, autocomplete: "off", label: t('views.settings.account.password'), help: t('views.settings.account.password_help')
- = f.password_field :password_confirmation, autocomplete: "off", label: t('views.settings.account.password_confirm')
-
- %button.btn.btn-primary{"data-target" => "#modal-passwd", "data-toggle" => "modal", :type => "button"}
- = t 'views.actions.save'
-
- %hr/
- %p
- = t 'views.settings.account.unsatisfied'
- =button_to t('views.settings.account.delete'), '/settings/account', data: { confirm: "Are you sure?" }, method: :delete, class: "btn btn-danger btn-xs"
-
- = link_to t('views.settings.account.back'), :back
-
-.visible-xs= render "shared/links"
diff --git a/app/views/user/_actions.haml b/app/views/user/_actions.haml
new file mode 100644
index 00000000..f257fb09
--- /dev/null
+++ b/app/views/user/_actions.haml
@@ -0,0 +1,32 @@
+.profile__actions
+ - if user_signed_in?
+ - type ||= :nil
+ - if user == current_user
+ %a.btn.btn-dark.btn-block{href: edit_user_profile_path} Edit profile
+ - else
+ - if current_user.following? user
+ %button#editprofile.btn.btn-primary.btn-block{type: :button, name: 'user-action', data: { action: :unfollow, type: type, target: user.screen_name }}
+ = t 'views.actions.unfollow'
+ - else
+ %button#editprofile.btn.btn-primary.btn-block{type: :button, name: 'user-action', data: { action: :follow, type: type, target: user.screen_name }}
+ = t 'views.actions.follow'
+ - unless user == current_user
+ .btn-group.btn-block
+ %button.btn.btn-light.btn-block.btn-sm.dropdown-toggle{data: { toggle: :dropdown }, aria: { expanded: :false }}
+ = t 'views.actions.title'
+ %span.caret
+ .dropdown-menu
+ %a.dropdown-item.d-block.d-sm-none{href: '#', data: { target: "#modal-group-memberships", toggle: :modal }}
+ %i.fa.fa-users
+ = t 'views.actions.group'
+ %a.dropdown-item{href: '#', data: { action: 'report-user', target: user.screen_name }}
+ %i.fa.fa-exclamation-triangle
+ = t 'views.actions.report'
+ - if current_user.mod?
+ %a.dropdown-item{href: '#', data: { target: "#modal-privileges", toggle: :modal }}
+ %i.fa.fa-wrench
+ = raw t('views.actions.privilege', user: user.screen_name)
+ - unless user.has_role?(:administrator)
+ %a.dropdown-item{href: '#', data: { target: "#modal-ban", toggle: :modal }}
+ %i.fa.fa-ban
+ = t 'views.actions.ban'
diff --git a/app/views/user/_actions.html.haml b/app/views/user/_actions.html.haml
deleted file mode 100644
index 7f3ae676..00000000
--- a/app/views/user/_actions.html.haml
+++ /dev/null
@@ -1,40 +0,0 @@
-- if user_signed_in?
- - type ||= :nil
- - if user == current_user
- %a.btn.btn-default.btn-block.profile--follow-btn{href: edit_user_profile_path} Edit profile
- - else
- - if current_user.following? user
- %button#editprofile.btn.btn-default.btn-block.profile--follow-btn{type: :button, name: 'user-action', data: { action: :unfollow, type: type, target: user.screen_name }}
- = t 'views.actions.unfollow'
- - else
- %button#editprofile.btn.btn-primary.btn-block.profile--follow-btn{type: :button, name: 'user-action', data: { action: :follow, type: type, target: user.screen_name }}
- = t 'views.actions.follow'
- - unless user == current_user
- .btn-group.btn-block
- %button.btn.btn-default.btn-block.btn-sm.dropdown-toggle{data: { toggle: :dropdown }, aria: { expanded: :false }}
- = t 'views.actions.title'
- %span.caret
- %ul.dropdown-menu
- /
- %li
- %a{href: '#', name: 'user-action', data: { action: :block, type: type, target: user.screen_name }}
- %i.fa.fa-minus-circle
- Block
- %li.visible-xs
- %a{href: '#', data: { target: "#modal-group-memberships", toggle: :modal }}
- %i.fa.fa-users
- = t 'views.actions.group'
- %li
- %a{href: '#', data: { action: 'report-user', target: user.screen_name }}
- %i.fa.fa-exclamation-triangle
- = t 'views.actions.report'
- - if current_user.mod?
- %li
- %a{href: '#', data: { target: "#modal-privileges", toggle: :modal }}
- %i.fa.fa-wrench
- = raw t('views.actions.privilege', user: user.screen_name)
- - unless user.has_role?(:administrator)
- %li
- %a{href: '#', data: { target: "#modal-ban", toggle: :modal }}
- %i.fa.fa-ban
- = t 'views.actions.ban'
diff --git a/app/views/user/_modal_group_item.html.haml b/app/views/user/_modal_group_item.html.haml
deleted file mode 100644
index 820d88d8..00000000
--- a/app/views/user/_modal_group_item.html.haml
+++ /dev/null
@@ -1,13 +0,0 @@
-%li.list-group-item{id: "group-#{group.name}"}
- .media
- .pull-left.j2-table
- %input.input--center{type: :checkbox, name: 'gm-group-check', data: { group: group.name, user: user.screen_name }, checked: user.member_of?(group), autocomplete: 'off'}
- .media-body
- .list-group-item-heading= group.display_name
- .list-group-item-text.text-muted.j2-up
- %span{id: "#{group.name}-members"}= group.members.count
- = t 'views.modal.group.members'
- ·
- %a.j2-delete#delete-group{href: "#", data: { group: group.name }}
- %i.fa.fa-close
- = t 'views.actions.delete'
diff --git a/app/views/user/_profile.haml b/app/views/user/_profile.haml
new file mode 100644
index 00000000..55783cd2
--- /dev/null
+++ b/app/views/user/_profile.haml
@@ -0,0 +1,38 @@
+.card#profile
+ %img.profile__avatar{src: @user.profile_picture.url(:large)}
+ .card-body
+ .profile__name
+ - unless @user.display_name.blank?
+ .profile__display-name
+ = @user.display_name
+ .profile__screen-name
+ = @user.screen_name
+ .profile__badge-container
+ - if @user.banned?
+ %span.badge.badge-dark
+ %i.fa.fa-fw.fa-ban
+ = t 'views.user.title.banned'
+ - if @user.following? current_user
+ .badge.badge-light
+ = t 'views.user.follows_you'
+ - if user_signed_in? && current_user.has_role?(:administrator)
+ - if @user.has_role?(:administrator)
+ %span.badge.badge-danger
+ %i.fa.fa-fw.fa-flask
+ = t 'views.user.title.admin'
+ - if @user.has_role?(:moderator)
+ %span.badge.badge-success
+ %i.fa.fa-fw.fa-users
+ = t 'views.user.title.moderator'
+ - unless @user.bio.blank?
+ .profile__biography
+ = markdown @user.bio
+ - unless @user.website.blank?
+ .profile__website
+ %i.fa.fa-fw.fa-globe
+ %a{href: @user.website}= @user.display_website
+ - unless @user.location.blank?
+ .profile__location
+ %i.fa.fa-fw.fa-location-arrow
+ = @user.location
+ = render 'user/actions', user: @user, type: :follower
diff --git a/app/views/user/_profile_info.html.haml b/app/views/user/_profile_info.html.haml
deleted file mode 100644
index 0403a7e0..00000000
--- a/app/views/user/_profile_info.html.haml
+++ /dev/null
@@ -1,40 +0,0 @@
-.panel.panel-default#profile
- %img.profile--avatar{src: @user.profile_picture.url(:large)}
- - if user_signed_in? && current_user.has_role?(:administrator)
- - if @user.has_role?(:administrator)
- .profile--panel-badge.panel-badge-danger
- %i.fa.fa-flask
- = t 'views.user.title.admin'
- - if @user.has_role?(:moderator)
- .profile--panel-badge.panel-badge-success
- %i.fa.fa-users
- = t 'views.user.title.moderator'
- - if @user.banned?
- .profile--panel-badge.panel-badge-default
- %i.fa.fa-ban
- = t 'views.user.title.banned'
- - if @user.following? current_user
- .profile--panel-badge.panel-badge-default
- = t 'views.user.follows_you'
- .panel-body
- .profile--panel-name
- - if @user.display_name.blank?
- .profile--displayname
- = @user.screen_name
- - else
- .profile--displayname
- = @user.display_name
- .profile--username
- = @user.screen_name
- - unless @user.bio.blank?
- %p.profile--text= markdown @user.bio
- - unless @user.website.blank?
- %p.profile--text
- %i.fa.fa-globe
- %a{href: @user.website}= @user.display_website
- - unless @user.location.blank?
- %p.profile--text
- %i.fa.fa-location-arrow
- = @user.location
- = render 'user/actions', user: @user, type: :follower
-= render 'user/stats', user: @user
diff --git a/app/views/user/_settings_tabs.html.haml b/app/views/user/_settings_tabs.html.haml
deleted file mode 100644
index 52ff1b2e..00000000
--- a/app/views/user/_settings_tabs.html.haml
+++ /dev/null
@@ -1,12 +0,0 @@
-.col-md-3.col-xs-12.col-sm-4
- .panel.panel-default
- .list-group
- = list_group_item t('views.settings.tabs.account'), edit_user_registration_path
- = list_group_item t('views.settings.tabs.profile'), edit_user_profile_path
- = list_group_item t('views.settings.tabs.privacy'), edit_user_privacy_path
- = list_group_item t('views.settings.tabs.sharing'), services_path
- = list_group_item 'Theme', edit_user_theme_path
- = list_group_item "Your Data", user_data_path
- = list_group_item 'Export', user_export_path
-
- .hidden-xs= render "shared/links"
diff --git a/app/views/user/_stats.html.haml b/app/views/user/_stats.html.haml
deleted file mode 100644
index 41446e44..00000000
--- a/app/views/user/_stats.html.haml
+++ /dev/null
@@ -1,22 +0,0 @@
-.panel.panel-default.profile--panel#profile-stats
- .panel-heading
- %h3.panel-title Stats
- .panel-body
- .row
- %a{href: show_user_followers_path(@user.screen_name)}
- .col-md-6.col-sm-6.col-xs-6
- %h4.entry-text#follower-count= @user.follower_count
- %h6.entry-subtext= t('views.general.follower').pluralize(@user.follower_count)
- %a{href: show_user_friends_path(@user.screen_name)}
- .col-md-6.col-sm-6.col-xs-6
- %h4.entry-text#friend-count= @user.friend_count
- %h6.entry-subtext= t('views.general.following')
- .row
- %a{href: show_user_questions_path(@user.screen_name)}
- .col-md-6.col-sm-6.col-xs-6
- %h4.entry-text#asked-count= @user.asked_count
- %h6.entry-subtext= t('views.general.question').pluralize(@user.asked_count)
- %a{href: show_user_profile_path(@user.screen_name)}
- .col-md-6.col-sm-6.col-xs-6
- %h4.entry-text#answered-count= @user.answered_count
- %h6.entry-subtext= t('views.general.answer').pluralize(@user.answered_count)
diff --git a/app/views/user/data.haml b/app/views/user/data.haml
new file mode 100644
index 00000000..f2093748
--- /dev/null
+++ b/app/views/user/data.haml
@@ -0,0 +1,4 @@
+= render "settings/data"
+
+- provide(:title, generate_title("Your Data"))
+- parent_layout "user/settings"
diff --git a/app/views/user/data.html.haml b/app/views/user/data.html.haml
deleted file mode 100644
index e7296259..00000000
--- a/app/views/user/data.html.haml
+++ /dev/null
@@ -1,158 +0,0 @@
-- provide(:title, generate_title("Your Data"))
-.container.j2-page
- = render 'settings_tabs'
- .col-md-9.col-xs-12.col-sm-8
- .panel.panel-default
- .panel-body
- %h2 Your Profile Data
- %p Everything we have about you! Really, not that much as you might expect.
-
- %h3 General
- .row
- .col-md-6.col-sm-6.col-xs-12
- %h4 Profile
-
- %p.data-heading User name
- %p.text-muted= current_user.screen_name
-
- %p.data-heading Display name
- %p.text-muted
- - if current_user.display_name.blank?
- None set!
- - else
- = current_user.display_name
-
- %p.data-heading Bio
- %p.text-muted
- - if current_user.bio.blank?
- None set!
- - else
- = current_user.bio
-
- %p.data-heading Location
- %p.text-muted
- - if current_user.location.blank?
- None set!
- - else
- = current_user.location
-
- %p.data-heading Website
- %p.text-muted
- - if current_user.website.blank?
- None set!
- - else
- = current_user.website
- .col-md-6.col-sm-6.col-xs-12
- %h4 Pictures
- %p.data-heading Profile picture
- .media
- .pull-left
- %img.profile--img{src: current_user.profile_picture.url(:medium)}
- .media-body
- %ul
- %li
- %a{href: current_user.profile_picture.url(:small)} Small
- %li
- %a{href: current_user.profile_picture.url(:medium)} Medium
- %li
- %a{href: current_user.profile_picture.url(:large)} Large
- %li
- %a{href: current_user.profile_picture.url(:original)} Original image
-
- %p.data-heading Header picture
- %img.data-header-preview{src: current_user.profile_header.url(:mobile)}
- %p
- %a{href: current_user.profile_header.url(:mobile)} Mobile
- |
- %a{href: current_user.profile_header.url(:web)} Web
- |
- %a{href: current_user.profile_header.url(:retina)} Retina
- |
- %a{href: current_user.profile_header.url(:original)} Original image
- .row
- .col-md-6.col-sm-6.col-xs-12
- %h4 Statistics
-
- %p.data-heading Answers
- %p.text-muted= current_user.answered_count
-
- %p.data-heading Questions
- %p.text-muted= current_user.asked_count
-
- %p.data-heading Following
- %p.text-muted= current_user.friend_count
-
- %p.data-heading Followers
- %p.text-muted= current_user.follower_count
-
- %p.data-heading Smiles
- %p.text-muted= current_user.smiled_count + current_user.comment_smiled_count
-
- %p.data-heading Comments
- %p.text-muted= current_user.commented_count
- .col-md-6.col-sm-6.col-xs-12
- %h4 Badges
-
- %p.data-heading Admin
- %p
- - if current_user.has_role?(:administrator)
- %span.label.label-success
- %i.fa.fa-fw.fa-check
- - else
- %span.label.label-danger
- %i.fa.fa-fw.fa-close
-
- %p.data-heading Moderator
- %p
- - if current_user.mod?
- %span.label.label-success
- %i.fa.fa-fw.fa-check
- - else
- %span.label.label-danger
- %i.fa.fa-fw.fa-close
-
- .row
- .col-md-6.col-sm-6.col-xs-12
- %h3 IP
- %p.data-heading Current Sign In
- %p.text-muted= current_user.current_sign_in_ip
-
- %p.data-heading Last Sign In
- %p.text-muted= current_user.last_sign_in_ip
- .col-md-6.col-sm-6.col-xs-12
- %h3 Miscellaneous
-
- %p.data-heading Locale
- %p.text-muted
- - if current_user.locale.blank?
- None set!
- - else
- = current_user.locale
-
- %p.data-heading Sign In count
- %p.text-muted= current_user.sign_in_count
- %h3 Dates
- .row
- .col-md-6.col-sm-6.col-xs-12
- %h4 Sign In
-
- %p.data-heading Current Sign In
- %p.text-muted= localize(current_user.current_sign_in_at)
-
- %p.data-heading Last Sign In
- %p.text-muted= localize(current_user.last_sign_in_at)
-
- %p.data-heading Remember me set at
- %p.text-muted= localize(current_user.remember_created_at)
- .col-md-6.col-sm-6.col-xs-12
- %h4 Create/Update
-
- %p.data-heading Account created
- %p.text-muted
- = localize(current_user.created_at)
- = " (#{time_ago_in_words(current_user.created_at)} ago)"
-
- %p.data-heading Account last updated
- %p.text-muted
- = localize(current_user.updated_at)
- = " (#{time_ago_in_words(current_user.updated_at)} ago)"
diff --git a/app/views/user/edit.haml b/app/views/user/edit.haml
new file mode 100644
index 00000000..43a76cb4
--- /dev/null
+++ b/app/views/user/edit.haml
@@ -0,0 +1,4 @@
+= render "settings/profile"
+
+- provide(:title, generate_title("Profile Settings"))
+- parent_layout "user/settings"
\ No newline at end of file
diff --git a/app/views/user/edit.html.haml b/app/views/user/edit.html.haml
deleted file mode 100644
index 19d368dd..00000000
--- a/app/views/user/edit.html.haml
+++ /dev/null
@@ -1,62 +0,0 @@
-- provide(:title, generate_title("Profile Settings"))
-.container.j2-page
- = render 'settings_tabs'
- .col-md-9.col-xs-12.col-sm-9
- = render 'layouts/messages'
- .panel.panel-default
- .panel-body
- = bootstrap_form_for(current_user, url: {action: "edit"}, :html => { :multipart => true }, method: "patch") do |f|
-
- = f.text_field :display_name, label: t('views.settings.profile.displayname')
-
- .media#profile-picture-media
- .pull-left
- %img.img-rounded.profile--img{src: current_user.profile_picture.url(:medium)}
- .media-body
- = f.file_field :profile_picture, label: t('views.settings.profile.avatar')
-
- .row#profile-picture-crop-controls{style: 'display: none;'}
- .col-sm-10.col-md-8
- %strong= t('views.settings.profile.avatar_adjust')
- %img#profile-picture-cropper{src: current_user.profile_picture.url(:medium)}
- .col-sm-2.col-md-4
- .btn-group
- %button#cropper-zoom-out.btn.btn-inverse{type: :button}
- %i.fa.fa-search-minus
- %button#cropper-zoom-in.btn.btn-inverse{type: :button}
- %i.fa.fa-search-plus
-
- .media#profile-header-media
- .pull-left
- %img.img-rounded.header--img{src: current_user.profile_header.url(:mobile)}
- .media-body
- = f.file_field :profile_header, label: t('views.settings.profile.header')
-
- .row#profile-header-crop-controls{style: 'display: none;'}
- .col-sm-10.col-md-8
- %strong= t('views.settings.profile.header_adjust')
- %img#profile-header-cropper{src: current_user.profile_header.url(:web)}
- .col-sm-2.col-md-4
- .btn-group
- %button#cropper-header-zoom-out.btn.btn-inverse{type: :button}
- %i.fa.fa-search-minus
- %button#cropper-header-zoom-in.btn.btn-inverse{type: :button}
- %i.fa.fa-search-plus
-
- = f.text_field :motivation_header, label: t('views.settings.profile.motivation'), placeholder: t('views.settings.profile.placeholder.motivation')
-
- = f.text_field :website, label: t('views.settings.profile.website'), placeholder: 'https://example.com'
-
- = f.text_field :location, label: t('views.settings.profile.location'), placeholder: t('views.settings.profile.placeholder.location')
-
- = f.text_area :bio, label: t('views.settings.profile.bio'), placeholder: t('views.settings.profile.placeholder.bio')
-
- = f.check_box :show_foreign_themes, label: 'Render other user themes when visiting their profile'
-
- - for attrib in %i(crop_x crop_y crop_w crop_h)
- = f.hidden_field attrib, id: attrib
-
- - for attrib in %i(crop_h_x crop_h_y crop_h_w crop_h_h)
- = f.hidden_field attrib, id: attrib
-
- = f.submit t('views.actions.save'), class: 'btn btn-primary'
diff --git a/app/views/user/edit_privacy.haml b/app/views/user/edit_privacy.haml
new file mode 100644
index 00000000..c422fb37
--- /dev/null
+++ b/app/views/user/edit_privacy.haml
@@ -0,0 +1,4 @@
+= render "settings/privacy"
+
+- provide(:title, generate_title("Privacy Settings"))
+- parent_layout "user/settings"
diff --git a/app/views/user/edit_privacy.html.haml b/app/views/user/edit_privacy.html.haml
deleted file mode 100644
index 526b6798..00000000
--- a/app/views/user/edit_privacy.html.haml
+++ /dev/null
@@ -1,14 +0,0 @@
-- provide(:title, generate_title("Privacy Settings"))
-.container.j2-page
- = render 'settings_tabs'
- .col-md-9.col-xs-12.col-sm-8
- = render 'layouts/messages'
- .panel.panel-default
- .panel-body
- = bootstrap_form_for(current_user, url: {action: "edit_privacy"}, method: "patch") do |f|
-
- = f.check_box :privacy_allow_anonymous_questions, label: t('views.settings.privacy.anonymous')
- = f.check_box :privacy_allow_public_timeline, label: t('views.settings.privacy.public')
- = f.check_box :privacy_allow_stranger_answers, label: t('views.settings.privacy.stranger')
-
- = f.submit t('views.actions.save'), class: 'btn btn-primary'
diff --git a/app/views/user/edit_theme.haml b/app/views/user/edit_theme.haml
new file mode 100644
index 00000000..38fec528
--- /dev/null
+++ b/app/views/user/edit_theme.haml
@@ -0,0 +1,4 @@
+= render "settings/theme"
+
+- provide(:title, generate_title("Theme Settings"))
+- parent_layout "user/settings"
\ No newline at end of file
diff --git a/app/views/user/edit_theme.html.haml b/app/views/user/edit_theme.html.haml
deleted file mode 100644
index ecfc0ad1..00000000
--- a/app/views/user/edit_theme.html.haml
+++ /dev/null
@@ -1,72 +0,0 @@
-- provide(:title, generate_title("Theme Settings"))
-.container.j2-page
- = render 'settings_tabs'
- .col-md-9.col-xs-12.col-sm-8
- = render 'layouts/messages'
- .panel.panel-default
- .panel-body
- %b Presets:
- %a{href: '#', class: 'theme_preset', data: {preset: 'rs'}} Retrospring Purple,
- %a{href: '#', class: 'theme_preset', data: {preset: 'dc'}} Dark Copycat,
- %a{href: '#', class: 'theme_preset', data: {preset: 'lc'}} Light Copycat
- = bootstrap_form_for(current_user.theme || Theme.new, url: {action: "update_theme"}, html: {id: 'update_theme'}, method: "patch") do |f|
- .row
- .col-md-6
- = f.text_field :primary_color, class: 'color', data: {default: 0x5E35B1}
- .col-md-6
- = f.text_field :primary_text, class: 'color', data: {default: 0xFFFFFF}
- .row
- .col-md-6
- = f.text_field :danger_color, class: 'color', data: {default: 0xFF0039}
- .col-md-6
- = f.text_field :danger_text, class: 'color', data: {default: 0xFFFFFF}
- .row
- .col-md-6
- = f.text_field :success_color, class: 'color', data: {default: 0x3FB618}
- .col-md-6
- = f.text_field :success_text, class: 'color', data: {default: 0xFFFFFF}
- .row
- .col-md-6
- = f.text_field :warning_color, class: 'color', data: {default: 0xFF7518}
- .col-md-6
- = f.text_field :warning_text, class: 'color', data: {default: 0xFFFFFF}
- .row
- .col-md-6
- = f.text_field :info_color, class: 'color', data: {default: 0x9954BB}
- .col-md-6
- = f.text_field :info_text, class: 'color', data: {default: 0xFFFFFF}
- .row
- .col-md-6
- = f.text_field :default_color, class: 'color', data: {default: 0x222222}
- .col-md-6
- = f.text_field :default_text, class: 'color', data: {default: 0xEEEEEE}
- .row
- .col-md-6
- = f.text_field :panel_color, class: 'color', data: {default: 0xF9F9F9}
- .col-md-6
- = f.text_field :panel_text, class: 'color', data: {default: 0x151515}
- .row
- .col-md-6
- = f.text_field :link_color, class: 'color', data: {default: 0x5E35B1}
- .col-md-6
- = f.text_field :background_color, class: 'color', data: {default: 0xFFFFFF}
- .row
- .col-md-6
- = f.text_field :background_text, class: 'color', data: {default: 0x222222}
- .col-md-6
- = f.text_field :background_muted, class: 'color', data: {default: 0xBBBBBB}
- .row
- .col-md-6
- = f.text_field :input_color, class: 'color', data: {default: 0xFFFFFF}
- .col-md-6
- = f.text_field :input_text, class: 'color', data: {default: 0x000000}
- .row
- .col-md-6
- = f.text_field :outline_color, class: 'color', data: {default: 0x5E35B1}
- .col-md-6
-
- .pull-left
- = f.submit t('views.actions.save'), class: 'btn btn-primary'
-
- .pull-right
- =button_to 'Delete Theme', delete_user_theme_path, data: { confirm: "Are you sure?" }, tabindex: -1, method: :delete, class: "btn btn-danger"
diff --git a/app/views/user/export.haml b/app/views/user/export.haml
index ef14b9b0..bc025d90 100644
--- a/app/views/user/export.haml
+++ b/app/views/user/export.haml
@@ -1,37 +1,4 @@
+= render "settings/export"
+
- provide(:title, generate_title("Export"))
-.container.j2-page
- = render 'settings_tabs'
- .col-md-9.col-xs-12.col-sm-8
- = render 'layouts/messages'
- .panel.panel-default
- .panel-body
- %h2 Export your data
- %p
- With the announcement of
- = succeed ',' do
- %a{href: 'http://blog.retrospring.net/saying-goodbye/'} shutting down Retrospring on June 8 2016
- we promised you one last feature: exporting all your data. The data is inside a
- %code= ".tar.gz"
- archive and available in three formats: YAML, JSON, and XML. The archive also contains a copy of your
- profile picture and header picture in all sizes.
- %p
- Please note that you can only export your data once a week. Exporting your data
- will take a while, so please be patient. You will receive a question once exporting
- is done.
- - if current_user.can_export?
- %form{action: begin_user_export_path, method: 'POST'}
- %p.centre
- %button#export-btn.btn.btn-lg.btn-primary{type: :submit} Export
- = hidden_field_tag :authenticity_token, form_authenticity_token
- - else
- %p.centre
- %button.btn.btn-lg.btn-primary.disabled{disabled: :disabled} Export
- %p
- - if current_user.export_url.nil?
- Once exporting your account is done, a download link will appear here.
- - else
- Here is your export from
- = succeed ':' do
- = current_user.export_created_at
- %a{href: current_user.export_url}
- = File.basename current_user.export_url
+- parent_layout "user/settings"
diff --git a/app/views/user/groups.haml b/app/views/user/groups.haml
new file mode 100644
index 00000000..0f08b0cf
--- /dev/null
+++ b/app/views/user/groups.haml
@@ -0,0 +1,9 @@
+%ul
+ - @groups.each do |group|
+ %li
+ - if group.private?
+ %i.fa.fa-lock
+ = group.display_name
+
+- provide(:title, user_title(@user, "groups"))
+- parent_layout "user/profile"
diff --git a/app/views/user/groups.html.haml b/app/views/user/groups.html.haml
deleted file mode 100644
index 34cf914f..00000000
--- a/app/views/user/groups.html.haml
+++ /dev/null
@@ -1,22 +0,0 @@
-- provide(:title, user_title(@user, "groups"))
-- no_header = unless @user.profile_header.exists? then "profile--no-header" else "" end
-#profile--header{class: no_header}
- %img.profile--header-img{src: @user.profile_header.url(:web)}
-.container.j2-page.headerable{class: no_header}
- .col-md-3.col-xs-12.col-sm-4
- = render 'user/profile_info'
- .hidden-xs= render 'shared/links'
- .col-md-9.col-xs-12.col-sm-8
- %h1.j2-lh.hidden-xs Groups
- %h1.visible-xs Groups
-
- %ul
- - @groups.each do |group|
- %li
- - if group.private?
- %i.fa.fa-lock
- = group.display_name
-
- .visible-xs= render 'shared/links'
-- if user_signed_in?
- = render 'user/modal_group_memberships'
diff --git a/app/views/user/questions.haml b/app/views/user/questions.haml
new file mode 100644
index 00000000..f606d663
--- /dev/null
+++ b/app/views/user/questions.haml
@@ -0,0 +1,12 @@
+#questions
+ - @questions.each do |q|
+ = render 'shared/question', q: q, type: nil
+
+= render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @questions_last_id
+
+- if @more_data_available
+ %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @questions_last_id }}
+ = t 'views.actions.load'
+
+- provide(:title, questions_title(@user))
+- parent_layout "user/profile"
\ No newline at end of file
diff --git a/app/views/user/questions.html.haml b/app/views/user/questions.html.haml
deleted file mode 100644
index efd269ec..00000000
--- a/app/views/user/questions.html.haml
+++ /dev/null
@@ -1,21 +0,0 @@
-- provide(:title, questions_title(@user))
-- no_header = unless @user.profile_header.exists? then "profile--no-header" else "" end
-#profile--header{class: no_header}
- %img.profile--header-img{src: @user.profile_header.url(:web)}
-.container.j2-page.headerable{class: no_header}
- .col-md-3.col-xs-12.col-sm-4.j2-col-reset
- = render 'user/profile_info'
- .hidden-xs= render 'shared/links'
- .col-md-9.col-xs-12.col-sm-8.j2-col-reset
- %h1.j2-lh.hidden-xs= @title
- %h1.visible-xs= @title
- #questions
- - @questions.each do |q|
- = render 'shared/question', q: q, type: nil
-
- = render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @questions_last_id
-
- - if @more_data_available
- %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @questions_last_id }}
- = t 'views.actions.load'
- .visible-xs= render 'shared/links'
diff --git a/app/views/user/show.haml b/app/views/user/show.haml
new file mode 100644
index 00000000..486b25e7
--- /dev/null
+++ b/app/views/user/show.haml
@@ -0,0 +1,14 @@
+.profile--panel-push-inner.hidden-xs
+- unless @user.banned?
+ #answers
+ - @answers.each do |a|
+ = render 'answerbox', a: a
+
+= render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @answers_last_id
+
+- if @more_data_available
+ %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @answers_last_id }}
+ = t 'views.actions.load'
+
+- provide(:title, user_title(@user))
+- parent_layout "user/profile"
diff --git a/app/views/user/show.html.haml b/app/views/user/show.html.haml
deleted file mode 100644
index c9ac350f..00000000
--- a/app/views/user/show.html.haml
+++ /dev/null
@@ -1,27 +0,0 @@
-- provide(:title, user_title(@user))
-- no_header = unless @user.profile_header.exists? then "profile--no-header" else "" end
-#profile--header{class: no_header}
- %img.profile--header-img{src: @user.profile_header.url(:web)}
-.container.j2-page.headerable{class: no_header}
- #profile-info.col-md-3.col-xs-12.col-sm-4.j2-col-reset
- = render 'user/profile_info'
- .hidden-xs= render 'shared/links'
- .col-md-9.col-xs-12.col-sm-8.j2-col-reset
- .profile--panel-push-inner.hidden-xs{class: no_header}
- = render 'shared/questionbox'
- - unless @user.banned?
- #answers
- - @answers.each do |a|
- = render 'shared/answerbox', a: a
-
- = render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @answers_last_id
-
- - if @more_data_available
- %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @answers_last_id }}
- = t 'views.actions.load'
- .visible-xs= render 'shared/links'
-- if user_signed_in?
- = render 'user/modal_group_memberships'
- - if current_user.mod? and @user != current_user
- = render 'user/modal_privileges'
- = render 'user/modal_ban'
diff --git a/app/views/user/show.js.erb b/app/views/user/show.js.erb
index 443b9d7b..be445de6 100644
--- a/app/views/user/show.js.erb
+++ b/app/views/user/show.js.erb
@@ -1,5 +1,5 @@
$('#answers').append('<% @answers.each do |a|
- %><%= j render 'shared/answerbox', a: a
+ %><%= j render 'answerbox', a: a
%><% end %>');
<% if @more_data_available %>
$('#pagination').html('<%= j render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @answers_last_id %>');
diff --git a/app/views/user/show_follow.haml b/app/views/user/show_follow.haml
new file mode 100644
index 00000000..15cf82e6
--- /dev/null
+++ b/app/views/user/show_follow.haml
@@ -0,0 +1,13 @@
+#users.row.row-cols-1.row-cols-sm-2.row-cols-md-3
+ - @users.each do |user|
+ .col
+ = render 'shared/userbox', user: user
+
+= render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @users_last_id
+
+- if @more_data_available
+ %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @users_last_id }}
+ = t 'views.actions.load'
+
+- provide(:title, user_title(@user, "friends and followers"))
+- parent_layout "user/profile"
diff --git a/app/views/user/show_follow.html.haml b/app/views/user/show_follow.html.haml
deleted file mode 100644
index f5b020bb..00000000
--- a/app/views/user/show_follow.html.haml
+++ /dev/null
@@ -1,24 +0,0 @@
-- provide(:title, user_title(@user, "friends and followers"))
-- no_header = unless @user.profile_header.exists? then "profile--no-header" else "" end
-#profile--header{class: no_header}
- %img.profile--header-img{src: @user.profile_header.url(:web)}
-.container.j2-page.headerable{class: no_header}
- .col-md-3.col-xs-12.col-sm-4.j2-col-reset
- = render 'user/profile_info'
- .hidden-xs= render 'shared/links'
- .col-md-9.col-xs-12.col-sm-8.j2-col-reset
- %h1.j2-lh.hidden-xs= @title
- %h1.visible-xs= @title
- #users
- - @users.each do |user|
- .col-md-4.col-sm-6.col-xs-12
- = render 'shared/userbox', user: user
-
- = render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @users_last_id
-
- - if @more_data_available
- %button#load-more-btn.btn.btn-default{type: :button, data: { last_id: @users_last_id }}
- = t 'views.actions.load'
- .visible-xs= render 'shared/links'
-- if user_signed_in?
- = render 'user/modal_group_memberships'
diff --git a/app/views/user/show_follow.js.erb b/app/views/user/show_follow.js.erb
index 6857406a..213d55f3 100644
--- a/app/views/user/show_follow.js.erb
+++ b/app/views/user/show_follow.js.erb
@@ -1,5 +1,5 @@
$('#users').append('<% @users.each do |user|
- %><%= j render 'shared/userbox', user: user
+ %>
<%= j render 'shared/userbox', user: user
%>
<% end %>');
<% if @more_data_available %>
$('#pagination').html('<%= j render 'shared/cursored_pagination_dummy', more_data_available: @more_data_available, last_id: @users_last_id %>');
diff --git a/app/views/user/theme.css.scss.erb b/app/views/user/theme.css.scss.erb
deleted file mode 100644
index b08d8cee..00000000
--- a/app/views/user/theme.css.scss.erb
+++ /dev/null
@@ -1,542 +0,0 @@
-// LEGEND
-
-// TYPE_COLOR: BACKGROUND COLOR
-// TYPE_BORDER: BORDER COLOR
-// TYPE_TEXT: TEXT COLOR
-
-// PRIMARY COLOR
-
-$primary_color: <%= @primary_color || "#5e35b1" %>;
-$primary_border: darken(adjust-hue($primary_color, -10), 5%);
-$primary_text: <%= @primary_text || "white" %>;
-
-// DANGER COLOR
-$danger_color: <%= @danger_color || "#FF0039" %>;
-$danger_border: darken(adjust-hue($danger_color, -10), 5%);
-$danger_text: <%= @danger_text || "white" %>;
-
-// SUCCESS COLOR
-
-$success_color: <%= @success_color || "#3FB618" %>;
-$success_border: darken(adjust-hue($success_color, -10), 5%);
-$success_text: <%= @success_text || "white" %>;
-
-// WARNING COLOR
-
-$warning_color: <%= @warning_color || "#FF7518" %>;
-$warning_border: darken(adjust-hue($warning_color, -10), 5%);
-$warning_text: <%= @warning_text || "white" %>;
-
-// INFO COLOR
-
-$info_color: <%= @info_color || "#9954BB" %>;
-$info_border: darken(adjust-hue($info_color, -10), 5%);
-$info_text: <%= @info_text || "white" %>;
-
-// DEFAULT COLOR
-
-$default_color: <%= @default_color || "#222222" %>;
-$default_border: darken(adjust-hue($default_color, -10), 5%);
-$default_text: <%= @default_text || "#eeeeee" %>;
-
-// PANEL COLOR
-
-$panel_color: <%= @panel_color || "#F9F9F9" %>;
-$panel_border: darken(adjust-hue($panel_color, -10), 5%);
-$panel_text: <%= @panel_text || "#151515" %>;
-
-// AUXILIARY COLOR
-
-$link_color: <%= @link_color || "#5E35B1" %>;
-
-$background_color: <%= @background_color || "#ffffff" %>;
-$background_text: <%= @background_text || "#222222" %>;
-$background_muted: <%= @background_muted || "#bbbbbb" %>;
-
-$input_color: <%= @input_color || "#ffffff" %>;
-$input_border: darken(adjust-hue($input_color, -10), 5%);
-$input_text: <%= @input_text || "#000000" %>;
-
-$outline_color: <%= @outline_color || "#5E35B1" %>;
-
-body#version1 {
- a, {
- &, &:hover, &:active {
- color: $link_color;
- }
- }
-
- :not(.sweet-alert) {
- h1, h2, h3, h4, h5, h6 {
- color: $background_text;
- }
- }
-
- &, * {
- outline-color: $outline_color;
- }
-
- hr, .locales #locales-panel ul {
- border-color: $link_color;
- }
-
- background-color: $background_color;
- color: $background_text;
-
- // Navigation
-
- nav.navbar {
-
- .active, li:hover {
- background: transparent;
- }
-
- .navbar-toggle {
- &, &:hover, &:active {
- border-color: $primary_border;
- background-color: $primary_color;
-
- .icon-bar {
- background-color: mix($primary_color, $primary_text, 70%);
- }
- }
-
- &:hover {
- background-color: mix($primary_color, $primary_text, 90%);
- }
- }
-
- .navbar-collapse {
- border-color: $primary_border;
- }
-
- // Nav Dropdown
-
- .dropdown.open .dropdown-toggle .badge {
- color: $primary_text;
- background-color: $primary_color;
- border-color: $primary_border;
- }
-
- &, .dropdown-menu {
- background-color: $primary_color;
- border-color: $primary_border;
- border-top: none;
-
- color: $primary_text;
-
- .media, .dropdown-header {
- color: $primary_text;
- }
-
- .notification--dropdown-media .notification--list .list-group-item {
- background-color: $primary_color;
- border-color: $primary_border;
-
- .notification--list-heading {
- color: $primary_text;
- }
- }
-
- .notification--heading a {
- border-color: $primary_text;
- }
-
- > li.divider {
- background-color: $primary_border;
- }
-
- > li {
- > a:hover {
- background-color: mix($primary_color, $primary_text, 80%);
- }
-
- a {
- &, &:hover, &:active {
- color: $primary_text;
- }
- }
- }
- }
-
- .navbar-nav > li > .btn > i {
- color: $primary_text;
- }
-
- // Nav Links
-
- a {
- &, &:hover, &:active {
- color: $primary_text;
- }
- }
-
- li:not(.profile--image-dropdown):before {
- background-color: $primary_text;
- }
- }
-
- // Notifications
-
- .media, #notifications .list-group-item {
- color: $panel_text;
- background: $panel_color;
- border-color: $panel_border;
- }
-
- #notifications .list-group-item:hover {
- border-color: $panel_border !important;
- }
-
- .media {
- background: transparent;
- }
-
- // Headers
-
- .j2-jumbo {
- background-color: $primary_color;
- border-color: $primary_border;
- }
-
- #profile--header.profile--no-header:before, .userbox--no-header:before {
- content: "";
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: $primary_color;
-
- img {
- opacity: 0;
- }
- }
-
- .userbox--no-header, .panel-body {
- position: relative;
- }
-
- // Panels, and modals
-
- .panel, .modal-dialog {
- border-color: $panel_border;
-
- .panel-heading, .panel-footer, .panel-body, .modal-header, .modal-footer, .modal-body, .modal-content {
- color: $panel_text;
- }
-
- a, a:hover, a:active {
- color: $link_color;
- }
-
- .answerbox--question-user, .answerbox--question-text, .answerbox--answer-user, .answerbox--answer-text {
- color: $panel_text;
-
- &.text-muted {
- color: mix($panel_text, $background_muted, 70%);
- }
- }
-
- input, textarea {
- background-color: $input_color;
- border-color: $input_border;
- color: $input_text;
- }
-
- select {
- background-color: $panel_color;
- border-color: $panel_border;
- }
-
- .input-group-addon {
- background: $panel_color;
- border: $panel_color;
- }
-
- &, .panel-heading, .panel-footer, .modal-header, .modal-footer {
- background-color: mix($panel_color, $panel_text, 90%);
- border-color: mix($panel_color, $panel_text, 85%);
- }
-
- .panel-body, .modal-body, .modal-content, .panel-question {
- background-color: $panel_color;
- }
- }
-
- // Non-navigation dropdowns
-
- .dropdown-menu {
- background-color: $panel_color;
- border-color: $panel_border;
- color: $panel_text;
-
- > li.divider {
- background-color: $panel_border;
- }
-
- > li {
- > a:hover {
- background-color: mix($panel_color, $panel_text, 90%);
- }
-
- a {
- &, &:hover, &:active {
- color: $panel_text;
- }
- }
- }
- }
-
- .text-muted {
- color: $background_muted;
- }
-
- // Tabs
- .nav-tabs {
- border-color: transparent;
- margin-top: -1px;
-
- li.active a, li:active a, li:hover a {
- background: mix($panel_color, $panel_text, 90%);
- color: mix($panel_text, $panel_color, 90%);
- }
- }
-
- // Lists
-
- .list-group .list-group-item {
- background-color: $panel_color;
- color: $panel_text;
- border-color: $panel_border;
-
- .badge {
- background-color: $panel_text;
- border-color: $panel_border;
- color: $panel_color;
- }
-
- &.active, &:hover {
- background-color: $primary_color;
- color: $primary_text;
- border-color: $primary_border;
-
- .badge {
- background-color: $primary_text;
- border-color: $primary_border;
- color: $primary_color;
- }
- }
- }
-
- // Buttons, Alerts, Labels, Panel Badges, Badges, List Items
-
- .btn-primary, .alert-primary, .label-primary, .panel-badge-primary, .badge-primary, .list-group-item-primary {
- color: $primary_text !important;
- background-color: $primary_color !important;
- border-color: $primary_border !important;
-
- .badge {
- color: $primary_color !important;
- background-color: $primary_text !important;
- border-color: $primary_border !important;
- }
- }
-
- .btn-link {
- color: $primary_text !important;
- }
-
- .panel-primary > .panel-heading {
- background-color: mix($primary_color, $primary_text, 90%) !important;
- border-color: mix($primary_color, $primary_text, 85%) !important;
- color: mix($primary_text, $primary_color, 90%) !important;
-
- &, .media * {
- color: mix($primary_text, $primary_color, 90%) !important;
- }
-
- .media a {
- color: mix(mix($primary_text, $primary_color, 90%), $link_color, 80%) !important;
- }
- }
-
- .btn-primary:hover {
- background-color: mix($primary_color, $primary_text, 90%) !important;
- }
-
- .btn-danger, .alert-danger, .label-danger, .panel-badge-danger, .badge-danger, .list-group-item-danger {
- color: $danger_text !important;
- background-color: $danger_color !important;
- border-color: $danger_border !important;
-
- .badge {
- color: $danger_color !important;
- background-color: $danger_text !important;
- border-color: $danger_border !important;
- }
- }
-
- .panel-danger > .panel-heading {
- background-color: mix($danger_color, $danger_text, 90%) !important;
- border-color: mix($danger_color, $danger_text, 85%) !important;
-
- &, .media * {
- color: mix($danger_text, $danger_color, 90%) !important;
- }
-
- .media a {
- color: mix(mix($danger_text, $danger_color, 90%), $link_color, 80%) !important;
- }
- }
-
- .btn-danger:hover {
- background-color: mix($danger_color, $danger_text, 90%) !important;
- }
-
- .btn-success, .alert-success, .label-success, .panel-badge-success, .badge-success, .list-group-item-success {
- color: $success_text !important;
- background-color: $success_color !important;
- border-color: $success_border !important;
-
- .badge {
- color: $success_color !important;
- background-color: $success_text !important;
- border-color: $success_border !important;
- }
- }
-
- .panel-success > .panel-heading {
- background-color: mix($success_color, $success_text, 90%) !important;
- border-color: mix($success_color, $success_text, 85%) !important;
- color: mix($success_text, $success_color, 90%) !important;
-
- &, .media * {
- color: mix($success_text, $success_color, 90%) !important;
- }
-
- .media a {
- color: mix(mix($success_text, $success_color, 90%), $link_color, 80%) !important;
- }
- }
-
- .btn-success:hover {
- background-color: mix($success_color, $success_text, 90%) !important;
- }
-
- .btn-warning, .alert-warning, .label-warning, .panel-badge-warning, .badge-warning, .list-group-item-warning {
- color: $warning_text !important;
- background-color: $warning_color !important;
- border-color: $warning_border !important;
-
- .badge {
- color: $warning_color !important;
- background-color: $warning_text !important;
- border-color: $warning_border !important;
- }
- }
-
- .panel-warning > .panel-heading {
- background-color: mix($warning_color, $warning_text, 90%) !important;
- border-color: mix($warning_color, $warning_text, 85%) !important;
- color: mix($warning_text, $warning_color, 90%) !important;
-
- &, .media * {
- color: mix($warning_text, $warning_color, 90%) !important;
- }
-
- .media a {
- color: mix(mix($warning_text, $warning_color, 90%), $link_color, 80%) !important;
- }
- }
-
- .btn-warning:hover {
- background-color: mix($warning_color, $warning_text, 90%) !important;
- }
-
- .btn-info, .alert-info, .label-info, .panel-badge-info, .badge-info, .list-group-item-info {
- color: $info_text !important;
- background-color: $info_color !important;
- border-color: $info_border !important;
-
- .badge {
- color: $info_color !important;
- background-color: $info_text !important;
- border-color: $info_border !important;
- }
- }
-
- .panel-info > .panel-heading {
- background-color: mix($info_color, $info_text, 90%) !important;
- border-color: mix($info_color, $info_text, 85%) !important;
- color: mix($info_text, $info_color, 90%) !important;
-
- &, .media * {
- color: mix($info_text, $info_color, 90%) !important;
- }
-
- .media a {
- color: mix(mix($info_text, $info_color, 90%), $link_color, 80%) !important;
- }
- }
-
- .btn-info:hover {
- background-color: mix($info_color, $info_text, 90%) !important;
- }
-
- .btn-default, .alert-default, .label-default, .panel-badge-default, .badge-default, .list-group-item-default {
- color: $default_text !important;
- background-color: $default_color !important;
- border-color: $default_border !important;
-
- .badge {
- color: $default_color !important;
- background-color: $default_text !important;
- border-color: $default_border !important;
- }
- }
-
- // .panel-default > .panel-heading {
- // background-color: mix($default_color, $default_text, 90%) !important;
- // border-color: mix($default_color, $default_text, 85%) !important;
- // color: mix($default_text, $default_color, 90%) !important;
- // }
-
- .btn-default:hover {
- background-color: mix($default_color, $default_text, 90%) !important;
- }
-
- // Reset debug
- #debug {
- background: white;
- color: black;
-
- hr {
- background-color: inherit;
- border-color: inherit;
- }
- }
-
- // Entry subtext
- .entry-subtext {
- color: mix($primary_color, $panel_text, 80%);
- }
-
- /* nprogress */
- $nprogress-color: lighten($primary_color, 25%);
-
- #nprogress {
- .bar {
- background: $nprogress-color;
- }
-
- .peg {
- box-shadow: 0 0 10px $nprogress-color, 0 0 5px $nprogress-color;
- }
-
- .spinner-icon {
- border-top-color: $nprogress-color;
- border-left-color: $nprogress-color;
- }
- }
-}
diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb
index e321065f..bc49d7dd 100644
--- a/config/initializers/assets.rb
+++ b/config/initializers/assets.rb
@@ -1,5 +1,15 @@
# Be sure to restart your server when you modify this file.
+unless Rails.env.production?
+ Rails.application.config.assets.configure do |env|
+ env.cache = Sprockets::Cache::FileStore.new(
+ ENV.fetch("SPROCKETS_CACHE", "#{env.root}/tmp/cache/assets"),
+ Rails.application.config.assets.cache_limit,
+ env.logger
+ )
+ end
+end
+
# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '1.0'
@@ -9,4 +19,4 @@ Rails.application.config.assets.version = '1.0'
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
Rails.application.config.assets.precompile += %w( moderation.js )
-Rails.application.config.assets.precompile += %w( i18n.js )
+Rails.application.config.assets.precompile += %w( i18n.js )
\ No newline at end of file
diff --git a/config/initializers/rails_admin.rb b/config/initializers/rails_admin.rb
index 1a6125be..f63405d2 100644
--- a/config/initializers/rails_admin.rb
+++ b/config/initializers/rails_admin.rb
@@ -3,6 +3,7 @@
# workaround to get pagination right
RailsAdmin.config do |config|
config.main_app_name = ['justask', 'Kontrollzentrum']
+ config.parent_controller = '::ApplicationController'
## == Authentication ==
config.authenticate_with do
diff --git a/config/routes.rb b/config/routes.rb
index 7ffc9036..c9e051e2 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -65,7 +65,6 @@ Rails.application.routes.draw do
match '/settings/theme', to: 'user#edit_theme', via: 'get', as: :edit_user_theme
match '/settings/theme', to: 'user#update_theme', via: 'patch', as: :update_user_theme
- match '/settings/theme/preview.css', to: 'user#preview_theme', via: 'post', as: :preview_user_theme
match '/settings/theme/delete', to: 'user#delete_theme', via: 'delete', as: :delete_user_theme
# resources :services, only: [:index, :destroy]
diff --git a/db/20150724154106_create_themes_table.rb b/db/20150724154106_create_themes_table.rb
deleted file mode 100644
index 0d326836..00000000
--- a/db/20150724154106_create_themes_table.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class CreateThemesTable < ActiveRecord::Migration[4.2]
- def change
- create_table :themes do |t|
- end
- end
-end
diff --git a/db/migrate/20200504214933_update_theme_fields.rb b/db/migrate/20200504214933_update_theme_fields.rb
new file mode 100644
index 00000000..ec577f1d
--- /dev/null
+++ b/db/migrate/20200504214933_update_theme_fields.rb
@@ -0,0 +1,46 @@
+class UpdateThemeFields < ActiveRecord::Migration[5.2]
+ def up
+ # CSS file related fields
+ remove_column :themes, :css_file_name
+ remove_column :themes, :css_content_type
+ remove_column :themes, :css_file_size
+ remove_column :themes, :css_updated_at
+
+ # Panel color fields -> Raised fields
+ rename_column :themes, :panel_color, :raised_background
+ remove_column :themes, :panel_text
+ add_column :themes, :raised_accent, :integer, default: 0xF7F7F7
+
+ # Default color -> Dark color
+ rename_column :themes, :default_color, :dark_color
+ rename_column :themes, :default_text, :dark_text
+
+ # Light color fields
+ add_column :themes, :light_color, :integer, default: 0xF8F9FA
+ add_column :themes, :light_text, :integer, default: 0x000000
+
+ # Rename some background_ fields
+ rename_column :themes, :background_text, :body_text
+ rename_column :themes, :background_muted, :muted_text
+
+ # Remove obsolete fields
+ remove_column :themes, :link_color
+ remove_column :themes, :outline_color
+
+ change_column_default :themes, :raised_background, 0xFFFFFF
+ change_column_default :themes, :dark_color, 0x343A40
+ change_column_default :themes, :body_text, 0x000000
+ change_column_default :themes, :muted_text, 0x6C757D
+ change_column_default :themes, :background_color, 0xF0EDF4
+ change_column_default :themes, :danger_color, 0xDC3545
+ change_column_default :themes, :warning_color, 0xFFC107
+ change_column_default :themes, :warning_text, 0x292929
+ change_column_default :themes, :info_color, 0x17A2B8
+ change_column_default :themes, :success_color, 0x28A745
+ change_column_default :themes, :input_color, 0xF0EDF4
+ end
+
+ def down
+ raise ActiveRecord::IrreversibleMigration
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 91feb5b1..0c1e34b5 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2020_04_25_194536) do
+ActiveRecord::Schema.define(version: 2020_05_04_214933) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -192,31 +192,27 @@ ActiveRecord::Schema.define(version: 2020_04_25_194536) do
t.integer "user_id", null: false
t.integer "primary_color", default: 6174129
t.integer "primary_text", default: 16777215
- t.integer "danger_color", default: 16711737
+ t.integer "danger_color", default: 14431557
t.integer "danger_text", default: 16777215
- t.integer "success_color", default: 4175384
+ t.integer "success_color", default: 2664261
t.integer "success_text", default: 16777215
- t.integer "warning_color", default: 16741656
- t.integer "warning_text", default: 16777215
- t.integer "info_color", default: 10048699
+ t.integer "warning_color", default: 16761095
+ t.integer "warning_text", default: 2697513
+ t.integer "info_color", default: 1548984
t.integer "info_text", default: 16777215
- t.integer "default_color", default: 2236962
- t.integer "default_text", default: 15658734
- t.integer "panel_color", default: 16382457
- t.integer "panel_text", default: 1381653
- t.integer "link_color", default: 6174129
- t.integer "background_color", default: 16777215
- t.integer "background_text", default: 2236962
- t.integer "background_muted", default: 12303291
- t.string "css_file_name"
- t.string "css_content_type"
- t.integer "css_file_size"
- t.datetime "css_updated_at"
+ t.integer "dark_color", default: 3422784
+ t.integer "dark_text", default: 15658734
+ t.integer "raised_background", default: 16777215
+ t.integer "background_color", default: 15789556
+ t.integer "body_text", default: 0
+ t.integer "muted_text", default: 7107965
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
- t.integer "input_color", default: 16777215, null: false
+ t.integer "input_color", default: 15789556, null: false
t.integer "input_text", default: 0, null: false
- t.integer "outline_color", default: 6174129, null: false
+ t.integer "raised_accent", default: 16250871
+ t.integer "light_color", default: 16316922
+ t.integer "light_text", default: 0
t.index ["user_id", "created_at"], name: "index_themes_on_user_id_and_created_at"
end
diff --git a/docker-compose.yml b/docker-compose.yml
index 90553f7d..659d7afe 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -10,8 +10,11 @@ services:
links:
- postgres
- redis
+ environment:
+ - SPROCKETS_CACHE=/cache
volumes:
- ./:/app
+ - cache:/cache
ports:
- 3000:3000
@@ -26,4 +29,7 @@ services:
- 5432:5432
environment:
POSTGRES_PASSWORD: justask
- POSTGRES_DB: justask_development
\ No newline at end of file
+ POSTGRES_DB: justask_development
+
+volumes:
+ cache:
\ No newline at end of file
diff --git a/spec/helpers/theme_helper_spec.rb b/spec/helpers/theme_helper_spec.rb
new file mode 100644
index 00000000..3776192d
--- /dev/null
+++ b/spec/helpers/theme_helper_spec.rb
@@ -0,0 +1,144 @@
+# frozen_string_literal: true
+
+require "rails_helper"
+
+describe ThemeHelper, :type => :helper do
+ describe "#render_theme" do
+ context "when target page doesn't have a theme" do
+ it "returns no theme" do
+ expect(helper.render_theme).to be_nil
+ end
+ end
+
+ context "when target page has a theme" do
+ before(:each) do
+ @user = FactoryBot.create(:user)
+ @user.theme = Theme.new
+ @user.save!
+ end
+
+ it "returns a theme" do
+ expect(helper.render_theme).to include('