Merge pull request #184 from Retrospring/mobile-layout
Adjust site layout to be nicer to use on smaller screens
This commit is contained in:
commit
89ce3e6e53
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
@import
|
@import
|
||||||
"overrides/alerts",
|
"overrides/alerts",
|
||||||
|
"overrides/badges",
|
||||||
"overrides/bootstrap-datetimepicker",
|
"overrides/bootstrap-datetimepicker",
|
||||||
"overrides/buttons",
|
"overrides/buttons",
|
||||||
"overrides/colors",
|
"overrides/colors",
|
||||||
|
@ -81,6 +82,7 @@
|
||||||
"components/inbox-entry",
|
"components/inbox-entry",
|
||||||
"components/jumbotron",
|
"components/jumbotron",
|
||||||
"components/locales",
|
"components/locales",
|
||||||
|
"components/mobile-nav",
|
||||||
"components/notifications",
|
"components/notifications",
|
||||||
"components/profile",
|
"components/profile",
|
||||||
"components/question",
|
"components/question",
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0px;
|
bottom: unquote('calc(#{$navbar-height} + env(safe-area-inset-bottom))');
|
||||||
right: 0px;
|
right: 0px;
|
||||||
margin-right: 7px;
|
margin-right: 7px;
|
||||||
margin-bottom: 7px;
|
margin-bottom: 7px;
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
.container--main {
|
.container--main {
|
||||||
padding-top: map-get($spacers, 3);
|
padding-top: map-get($spacers, 3);
|
||||||
padding-bottom: map-get($spacers, 3);
|
padding-bottom: map-get($spacers, 3);
|
||||||
|
// Sass doesn't know about the safe-area-inset-* env vars and throws a syntax error
|
||||||
|
// We can get around this by using unquote()
|
||||||
|
// Sass also has its own built-in max() function which is not the same as the CSS one
|
||||||
|
// In order to use the correct one we can write it as Max() instead
|
||||||
|
padding-left: unquote('Max(15px, env(safe-area-inset-left))');
|
||||||
|
padding-right: unquote('Max(15px, env(safe-area-inset-right))');
|
||||||
}
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
#rs-mobile-nav {
|
||||||
|
.container {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
padding: 4px 0 unquote('calc(env(safe-area-inset-bottom) + 4px)') 0;
|
||||||
|
|
||||||
|
.navbar-icon-row {
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-around;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.fa {
|
||||||
|
padding-top: 8px;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
transform: translateX(16px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#rs-mobile-nav-profile {
|
||||||
|
position: fixed;
|
||||||
|
bottom: unquote("calc(env(safe-area-inset-bottom) + #{$navbar-height + 2px})");
|
||||||
|
right: unquote("calc(env(safe-area-inset-right) + 15px)");
|
||||||
|
left: unset;
|
||||||
|
top: unset;
|
||||||
|
}
|
|
@ -3,5 +3,15 @@ body {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
color: RGB(var(--body-text));
|
color: RGB(var(--body-text));
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
|
@include media-breakpoint-up('lg') {
|
||||||
padding-top: $navbar-height;
|
padding-top: $navbar-height;
|
||||||
|
}
|
||||||
|
@include media-breakpoint-down('md') {
|
||||||
|
padding-bottom: $navbar-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.not-logged-in {
|
||||||
|
padding-top: $navbar-height;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
@each $color in $color-names {
|
||||||
|
.badge-#{$color} {
|
||||||
|
color: var(--#{$color});
|
||||||
|
background-color: RGB(var(--#{$color}-text));
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,14 +16,17 @@ module ApplicationHelper
|
||||||
].compact.join(" ")
|
].compact.join(" ")
|
||||||
|
|
||||||
unless options[:icon].nil?
|
unless options[:icon].nil?
|
||||||
body = "#{content_tag(:i, '', class: "mdi-#{options[:icon]}")} #{body}"
|
if options[:icon_only]
|
||||||
|
body = "#{content_tag(:i, '', class: "fa fa-#{options[:icon]}", title: body)}"
|
||||||
|
else
|
||||||
|
body = "#{content_tag(:i, '', class: "fa fa-#{options[:icon]}")} #{body}"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
unless options[:badge].nil?
|
unless options[:badge].nil?
|
||||||
# TODO: make this prettier?
|
badge_class = "badge"
|
||||||
body << " #{
|
badge_class << " badge-#{options[:badge_color]}" unless options[:badge_color].nil?
|
||||||
content_tag(:span, options[:badge], class: ("badge#{
|
badge_class << " badge-pill" if options[:badge_pill]
|
||||||
" badge-#{options[:badge_color]}" unless options[:badge_color].nil?
|
body += " #{content_tag(:span, options[:badge], class: badge_class)}"
|
||||||
}"))}"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
content_tag(:li, link_to(body.html_safe, path, class: "nav-link"), class: classes)
|
content_tag(:li, link_to(body.html_safe, path, class: "nav-link"), class: classes)
|
||||||
|
|
|
@ -50,12 +50,21 @@ module ThemeHelper
|
||||||
def theme_color
|
def theme_color
|
||||||
theme = get_active_theme
|
theme = get_active_theme
|
||||||
if theme
|
if theme
|
||||||
"##{get_hex_color_from_theme_value(theme.primary_color)}"
|
theme.theme_color
|
||||||
else
|
else
|
||||||
'#5e35b1'
|
'#5e35b1'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def mobile_theme_color
|
||||||
|
theme = get_active_theme
|
||||||
|
if theme
|
||||||
|
theme.mobile_theme_color
|
||||||
|
else
|
||||||
|
'#f0edf4'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def get_active_theme
|
def get_active_theme
|
||||||
if @user&.theme
|
if @user&.theme
|
||||||
if user_signed_in?
|
if user_signed_in?
|
||||||
|
|
|
@ -20,4 +20,8 @@ class Theme < ApplicationRecord
|
||||||
def theme_color
|
def theme_color
|
||||||
('#' + ('0000000' + primary_color.to_s(16))[-6, 6])
|
('#' + ('0000000' + primary_color.to_s(16))[-6, 6])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def mobile_theme_color
|
||||||
|
('#' + ('0000000' + background_color.to_s(16))[-6, 6])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- provide(:title, generate_title('Edit announcement'))
|
- provide(:title, generate_title('Edit announcement'))
|
||||||
.container.container--main
|
.container-lg.container--main
|
||||||
.card
|
.card
|
||||||
.card-body
|
.card-body
|
||||||
= bootstrap_form_for(@announcement, url: { action: 'update' }, method: 'PATCH') do |f|
|
= bootstrap_form_for(@announcement, url: { action: 'update' }, method: 'PATCH') do |f|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- provide(:title, generate_title('Announcements'))
|
- provide(:title, generate_title('Announcements'))
|
||||||
.container.container--main
|
.container-lg.container--main
|
||||||
- @announcements.each do |announcement|
|
- @announcements.each do |announcement|
|
||||||
.card
|
.card
|
||||||
.card-body
|
.card-body
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- provide(:title, generate_title('Add new announcement'))
|
- provide(:title, generate_title('Add new announcement'))
|
||||||
.container.container--main
|
.container-lg.container--main
|
||||||
.card
|
.card
|
||||||
.card-body
|
.card-body
|
||||||
= bootstrap_form_for(@announcement, url: { action: 'create' }) do |f|
|
= bootstrap_form_for(@announcement, url: { action: 'create' }) do |f|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
- provide(:title, answer_title(@answer))
|
- provide(:title, answer_title(@answer))
|
||||||
- provide(:og, answer_opengraph(@answer))
|
- provide(:og, answer_opengraph(@answer))
|
||||||
.container.container--main
|
.container-lg.container--main
|
||||||
= render 'answerbox', a: @answer, display_all: @display_all
|
= render 'answerbox', a: @answer, display_all: @display_all
|
||||||
|
|
|
@ -3,7 +3,11 @@
|
||||||
%head
|
%head
|
||||||
%meta{ charset: 'utf-8' }
|
%meta{ charset: 'utf-8' }
|
||||||
%meta{ 'http-equiv': 'X-UA-Compatible', content: 'IE=edge' }
|
%meta{ 'http-equiv': 'X-UA-Compatible', content: 'IE=edge' }
|
||||||
%meta{ name: 'viewport', content: 'width=device-width, initial-scale=1, user-scalable=no' }
|
%meta{ name: 'viewport', content: 'width=device-width, initial-scale=1, user-scalable=no, viewport-fit=cover' }
|
||||||
|
- if user_signed_in?
|
||||||
|
%meta{ name: 'theme-color', content: theme_color, media: '(min-width: 993px)' }
|
||||||
|
%meta{ name: 'theme-color', content: mobile_theme_color, media: '(max-width: 992px)' }
|
||||||
|
- else
|
||||||
%meta{ name: 'theme-color', content: theme_color }
|
%meta{ name: 'theme-color', content: theme_color }
|
||||||
%link{ rel: 'apple-touch-icon', href: '/apple-touch-icon-precomposed.png' }
|
%link{ rel: 'apple-touch-icon', href: '/apple-touch-icon-precomposed.png' }
|
||||||
%link{ rel: 'icon', href: '/images/favicon/favicon-16.png', sizes: '16x16' }
|
%link{ rel: 'icon', href: '/images/favicon/favicon-16.png', sizes: '16x16' }
|
||||||
|
@ -19,7 +23,7 @@
|
||||||
= csrf_meta_tags
|
= csrf_meta_tags
|
||||||
= yield(:og)
|
= yield(:og)
|
||||||
= yield(:meta)
|
= yield(:meta)
|
||||||
%body
|
%body{ class: user_signed_in? ? '' : 'not-logged-in' }
|
||||||
- if user_signed_in?
|
- if user_signed_in?
|
||||||
= render 'navigation/main'
|
= render 'navigation/main'
|
||||||
- else
|
- else
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.container.container--main
|
.container-lg.container--main
|
||||||
.row
|
.row
|
||||||
.col-md-3.col-sm-4.d-none.d-sm-block
|
.col-md-3.col-sm-4.d-none.d-sm-block
|
||||||
= render 'shared/sidebar'
|
= render 'shared/sidebar'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.container.container--main
|
.container-lg.container--main
|
||||||
.row
|
.row
|
||||||
.col-md-3.col-xs-12.col-sm-4.order-2.order-sm-1
|
.col-md-3.col-xs-12.col-sm-4.order-2.order-sm-1
|
||||||
= render 'inbox/sidebar', delete_id: @delete_id, disabled: @disabled, inbox_count: @inbox_count
|
= render 'inbox/sidebar', delete_id: @delete_id, disabled: @disabled, inbox_count: @inbox_count
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
= render 'navigation/moderation'
|
= render 'navigation/moderation'
|
||||||
.container.container--main
|
.container-lg.container--main
|
||||||
.row
|
.row
|
||||||
.col-md-3.col-sm-4.col-xs-12
|
.col-md-3.col-sm-4.col-xs-12
|
||||||
= render 'tabs/moderation'
|
= render 'tabs/moderation'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
= render 'navigation/notification'
|
= render 'navigation/notification'
|
||||||
.container.container--main
|
.container-lg.container--main
|
||||||
.row
|
.row
|
||||||
.col-md-3.col-xs-12.col-sm-4
|
.col-md-3.col-xs-12.col-sm-4
|
||||||
= render 'tabs/notifications'
|
= render 'tabs/notifications'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.container.container--main
|
.container-lg.container--main
|
||||||
.row
|
.row
|
||||||
.col-md-3.col-xs-12.col-sm-4
|
.col-md-3.col-xs-12.col-sm-4
|
||||||
= render 'tabs/settings'
|
= render 'tabs/settings'
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
%nav.navbar.navbar-themed.navbar-expand-lg.bg-primary.fixed-top.d-lg-block.d-none{ role: :navigation }
|
||||||
|
.container{ class: ios_web_app? ? 'ios-web-app' : '' }
|
||||||
|
%a.navbar-brand{ href: '/' }
|
||||||
|
= APP_CONFIG['site_name']
|
||||||
|
%ul.nav.navbar-nav.mr-auto
|
||||||
|
= nav_entry t('views.navigation.timeline'), root_path, icon: 'home'
|
||||||
|
= nav_entry t('views.navigation.inbox'), '/inbox', icon: 'inbox', badge: inbox_count
|
||||||
|
- if APP_CONFIG.dig(:features, :discover, :enabled) || current_user.mod?
|
||||||
|
= nav_entry t('views.navigation.discover'), discover_path, icon: 'compass'
|
||||||
|
%ul.nav.navbar-nav
|
||||||
|
- if @user.present? && @user != current_user
|
||||||
|
%li.nav-item.d-none.d-sm-block{ data: { toggle: 'tooltip', placement: 'bottom' }, title: t('views.actions.list') }
|
||||||
|
%a.nav-link{ href: '#', data: { target: '#modal-list-memberships', toggle: :modal } }
|
||||||
|
%i.fa.fa-list.hidden-xs
|
||||||
|
%span.d-none.d-sm-inline.d-md-none= t('views.actions.list')
|
||||||
|
= render 'navigation/main/notifications'
|
||||||
|
%li.nav-item.d-none.d-sm-block{ data: { toggle: 'tooltip', placement: 'bottom' }, title: t('views.actions.ask_question') }
|
||||||
|
%a.nav-link{ href: '#', name: 'toggle-all-ask', data: { target: '#modal-ask-followers', toggle: :modal } }
|
||||||
|
%i.fa.fa-pencil-square-o
|
||||||
|
= render 'navigation/main/profile'
|
|
@ -1,26 +1,5 @@
|
||||||
%nav.navbar.navbar-themed.navbar-expand-lg.bg-primary.fixed-top{ role: :navigation }
|
= render 'navigation/desktop'
|
||||||
.container{ class: ios_web_app? ? 'ios-web-app' : '' }
|
= render 'navigation/mobile'
|
||||||
%a.navbar-brand{ href: '/' }= APP_CONFIG['site_name']
|
|
||||||
%button.navbar-toggler{ data: { target: '#j2-main-navbar-collapse', toggle: :collapse }, type: :button }
|
|
||||||
%span.sr-only Toggle navigation
|
|
||||||
%span.navbar-toggler-icon
|
|
||||||
.collapse.navbar-collapse#j2-main-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
|
|
||||||
- if @user.present? && @user != current_user
|
|
||||||
%li.nav-item.d-none.d-sm-block{ data: { toggle: 'tooltip', placement: 'bottom' }, title: t('views.actions.list') }
|
|
||||||
%a.nav-link{ href: '#', data: { target: '#modal-list-memberships', toggle: :modal } }
|
|
||||||
%i.fa.fa-list.hidden-xs
|
|
||||||
%span.d-none.d-sm-inline.d-md-none= t('views.actions.list')
|
|
||||||
= render 'navigation/main/notifications'
|
|
||||||
%li.nav-item.d-none.d-sm-block{ data: { toggle: 'tooltip', placement: 'bottom' }, title: t('views.actions.ask_question') }
|
|
||||||
%a.nav-link{ href: '#', name: 'toggle-all-ask', data: { target: '#modal-ask-followers', toggle: :modal } }
|
|
||||||
%i.fa.fa-pencil-square-o
|
|
||||||
= render 'navigation/main/profile'
|
|
||||||
|
|
||||||
= render 'modal/ask'
|
= render 'modal/ask'
|
||||||
%button.btn.btn-primary.btn-fab.d-block.d-sm-none{ data: { target: '#modal-ask-followers', toggle: :modal }, type: 'button' }
|
%button.btn.btn-primary.btn-fab.d-block.d-sm-none{ data: { target: '#modal-ask-followers', toggle: :modal }, type: 'button' }
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
= render 'navigation/mobile/profile'
|
||||||
|
- notifications_icon = notification_count.nil? ? 'bell-o' : 'bell'
|
||||||
|
%nav.navbar.navbar-themed.bg-primary.fixed-bottom.d-lg-none.d-block#rs-mobile-nav{ role: :navigation }
|
||||||
|
.container{ class: ios_web_app? ? 'ios-web-app' : '' }
|
||||||
|
%ul.nav.navbar-nav.navbar-icon-row
|
||||||
|
= nav_entry t('views.navigation.timeline'), root_path, icon: 'home', icon_only: true
|
||||||
|
= nav_entry t('views.navigation.inbox'), '/inbox',
|
||||||
|
badge: inbox_count, badge_color: 'primary', badge_pill: true,
|
||||||
|
icon: 'inbox', icon_only: true
|
||||||
|
- if APP_CONFIG.dig(:features, :discover, :enabled) || current_user.mod?
|
||||||
|
= nav_entry t('views.navigation.discover'), discover_path, icon: 'compass', icon_only: true
|
||||||
|
= nav_entry t('views.navigation.notifications'), '/notifications',
|
||||||
|
badge: notification_count, badge_color: 'primary', badge_pill: true,
|
||||||
|
icon: notifications_icon, icon_only: true
|
||||||
|
%li.nav-item.profile--image-dropdown
|
||||||
|
%a.nav-link{ href: '#', data: { toggle: 'dropdown', target: '#rs-mobile-nav-profile' }, aria: { controls: 'rs-mobile-nav-profile', expanded: 'false' } }
|
||||||
|
%img.avatar-md.d-inline{ src: current_user.profile_picture.url(:small) }
|
|
@ -0,0 +1,31 @@
|
||||||
|
.dropdown-menu#rs-mobile-nav-profile
|
||||||
|
%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'
|
|
@ -1,4 +1,4 @@
|
||||||
.container.container--main
|
.container-lg.container--main
|
||||||
.row.justify-content-center
|
.row.justify-content-center
|
||||||
.col-md-5.totp-setup__recovery-container
|
.col-md-5.totp-setup__recovery-container
|
||||||
.card
|
.card
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- provide(:title, generate_title('Privacy Policy'))
|
- provide(:title, generate_title('Privacy Policy'))
|
||||||
.container.container--main
|
.container-lg.container--main
|
||||||
.card
|
.card
|
||||||
.card-body
|
.card-body
|
||||||
= raw_markdown_io 'service-docs/en/policy/privacy.md'
|
= raw_markdown_io 'service-docs/en/policy/privacy.md'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- provide(:title, generate_title('Terms of Service'))
|
- provide(:title, generate_title('Terms of Service'))
|
||||||
.container.container--main
|
.container-lg.container--main
|
||||||
.card
|
.card
|
||||||
.card-body
|
.card-body
|
||||||
= raw_markdown_io 'service-docs/en/policy/terms.md'
|
= raw_markdown_io 'service-docs/en/policy/terms.md'
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :theme do
|
||||||
|
primary_color { 9_342_168 }
|
||||||
|
primary_text { 16_777_215 }
|
||||||
|
danger_color { 14_257_035 }
|
||||||
|
danger_text { 16_777_215 }
|
||||||
|
success_color { 12_573_067 }
|
||||||
|
success_text { 16_777_215 }
|
||||||
|
warning_color { 14_261_899 }
|
||||||
|
warning_text { 16_777_215 }
|
||||||
|
info_color { 9_165_273 }
|
||||||
|
info_text { 16_777_215 }
|
||||||
|
dark_color { 6_710_886 }
|
||||||
|
dark_text { 15_658_734 }
|
||||||
|
raised_background { 16_777_215 }
|
||||||
|
background_color { 13_026_795 }
|
||||||
|
body_text { 3_355_443 }
|
||||||
|
muted_text { 3_355_443 }
|
||||||
|
input_color { 15_789_556 }
|
||||||
|
input_text { 6_710_886 }
|
||||||
|
raised_accent { 16_250_871 }
|
||||||
|
light_color { 16_316_922 }
|
||||||
|
light_text { 0 }
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,6 +3,40 @@
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe ApplicationHelper, :type => :helper do
|
describe ApplicationHelper, :type => :helper do
|
||||||
|
describe '#nav_entry' do
|
||||||
|
it 'should return a HTML navigation item which links to a given address' do
|
||||||
|
allow(self).to receive(:current_page?).and_return(false)
|
||||||
|
expect(nav_entry('Example', '/example')).to(
|
||||||
|
eq('<li class="nav-item "><a class="nav-link" href="/example">Example</a></li>')
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return with an active attribute if the link matches the current URL' do
|
||||||
|
allow(self).to receive(:current_page?).and_return(true)
|
||||||
|
expect(nav_entry('Example', '/example')).to(
|
||||||
|
eq('<li class="nav-item active "><a class="nav-link" href="/example">Example</a></li>')
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should include an icon if given' do
|
||||||
|
allow(self).to receive(:current_page?).and_return(false)
|
||||||
|
expect(nav_entry('Example', '/example', icon: 'beaker')).to(
|
||||||
|
eq('<li class="nav-item "><a class="nav-link" href="/example"><i class="fa fa-beaker"></i> Example</a></li>')
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should include a badge if given' do
|
||||||
|
allow(self).to receive(:current_page?).and_return(false)
|
||||||
|
expect(nav_entry('Example', '/example', badge: 3)).to(
|
||||||
|
eq('<li class="nav-item "><a class="nav-link" href="/example">Example <span class="badge">3</span></a></li>')
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(nav_entry('Example', '/example', badge: 3, badge_color: 'primary', badge_pill: true)).to(
|
||||||
|
eq('<li class="nav-item "><a class="nav-link" href="/example">Example <span class="badge badge-primary badge-pill">3</span></a></li>')
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "#bootstrap_color" do
|
describe "#bootstrap_color" do
|
||||||
it 'should map error and alert to danger' do
|
it 'should map error and alert to danger' do
|
||||||
expect(bootstrap_color("error")).to eq("danger")
|
expect(bootstrap_color("error")).to eq("danger")
|
||||||
|
|
|
@ -141,4 +141,54 @@ describe ThemeHelper, :type => :helper do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#theme_color' do
|
||||||
|
subject { helper.theme_color }
|
||||||
|
|
||||||
|
context 'when user is signed in' do
|
||||||
|
let(:user) { FactoryBot.create(:user) }
|
||||||
|
let(:theme) { FactoryBot.create(:theme, user: user) }
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
user.theme = theme
|
||||||
|
user.save!
|
||||||
|
sign_in(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return the user theme\'s primary color' do
|
||||||
|
expect(subject).to eq('#8e8cd8')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'user is not signed in' do
|
||||||
|
it 'should return the default primary color' do
|
||||||
|
expect(subject).to eq('#5e35b1')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#mobile_theme_color' do
|
||||||
|
subject { helper.mobile_theme_color }
|
||||||
|
|
||||||
|
context 'when user is signed in' do
|
||||||
|
let(:user) { FactoryBot.create(:user) }
|
||||||
|
let(:theme) { FactoryBot.create(:theme, user: user) }
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
user.theme = theme
|
||||||
|
user.save!
|
||||||
|
sign_in(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return the user theme\'s background color' do
|
||||||
|
expect(subject).to eq('#c6c5eb')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'user is not signed in' do
|
||||||
|
it 'should return the default background color' do
|
||||||
|
expect(subject).to eq('#f0edf4')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe(Theme, type: :model) do
|
||||||
|
context 'user-defined theme' do
|
||||||
|
let(:user) { FactoryBot.create(:user) }
|
||||||
|
let(:theme) { FactoryBot.create(:theme, user: user) }
|
||||||
|
|
||||||
|
describe '#theme_color' do
|
||||||
|
subject { theme.theme_color }
|
||||||
|
|
||||||
|
it 'should return the theme\'s primary colour as a hex triplet' do
|
||||||
|
expect(subject).to eq('#8e8cd8')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#mobile_theme_color' do
|
||||||
|
subject { theme.mobile_theme_color }
|
||||||
|
|
||||||
|
it 'should return the theme\'s background colour as a hex triplet' do
|
||||||
|
expect(subject).to eq('#c6c5eb')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue