pull/332/head
tidusjar 9 years ago
parent 071daf4ab4
commit 0dd30968d5

@ -77,6 +77,7 @@
<Compile Include="Models\UserProperties.cs" /> <Compile Include="Models\UserProperties.cs" />
<Compile Include="SettingModels\AuthenticationSettings.cs" /> <Compile Include="SettingModels\AuthenticationSettings.cs" />
<Compile Include="SettingModels\HeadphonesSettings.cs" /> <Compile Include="SettingModels\HeadphonesSettings.cs" />
<Compile Include="SettingModels\LandingPageSettings.cs" />
<Compile Include="SettingModels\SlackNotificationSettings.cs" /> <Compile Include="SettingModels\SlackNotificationSettings.cs" />
<Compile Include="SettingModels\PushoverNotificationSettings.cs" /> <Compile Include="SettingModels\PushoverNotificationSettings.cs" />
<Compile Include="SettingModels\PushBulletNotificationSettings.cs" /> <Compile Include="SettingModels\PushBulletNotificationSettings.cs" />

@ -0,0 +1,40 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: LandingPageSettings.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
using System;
namespace PlexRequests.Core.SettingModels
{
public class LandingPageSettings : Settings
{
public bool Enabled { get; set; }
public bool NoticeEnable { get; set; }
public string NoticeMessage { get; set; }
public bool EnabledNoticeTime { get; set; }
public DateTime NoticeStart { get; set; }
public DateTime NoticeEnd { get; set; }
}
}

@ -74,6 +74,7 @@ namespace PlexRequests.UI.Tests
private Mock<ICacheProvider> Cache { get; set; } private Mock<ICacheProvider> Cache { get; set; }
private Mock<ISettingsService<LogSettings>> Log { get; set; } private Mock<ISettingsService<LogSettings>> Log { get; set; }
private Mock<ISettingsService<SlackNotificationSettings>> SlackSettings { get; set; } private Mock<ISettingsService<SlackNotificationSettings>> SlackSettings { get; set; }
private Mock<ISettingsService<LandingPageSettings>> LandingPageSettings { get; set; }
private Mock<ISlackApi> SlackApi { get; set; } private Mock<ISlackApi> SlackApi { get; set; }
private ConfigurableBootstrapper Bootstrapper { get; set; } private ConfigurableBootstrapper Bootstrapper { get; set; }
@ -109,6 +110,8 @@ namespace PlexRequests.UI.Tests
Log = new Mock<ISettingsService<LogSettings>>(); Log = new Mock<ISettingsService<LogSettings>>();
SlackApi = new Mock<ISlackApi>(); SlackApi = new Mock<ISlackApi>();
SlackSettings = new Mock<ISettingsService<SlackNotificationSettings>>(); SlackSettings = new Mock<ISettingsService<SlackNotificationSettings>>();
LandingPageSettings = new Mock<ISettingsService<LandingPageSettings>>();
Bootstrapper = new ConfigurableBootstrapper(with => Bootstrapper = new ConfigurableBootstrapper(with =>
{ {
@ -133,6 +136,7 @@ namespace PlexRequests.UI.Tests
with.Dependency(Cache.Object); with.Dependency(Cache.Object);
with.Dependency(Log.Object); with.Dependency(Log.Object);
with.Dependency(SlackApi.Object); with.Dependency(SlackApi.Object);
with.Dependency(LandingPageSettings.Object);
with.Dependency(SlackSettings.Object); with.Dependency(SlackSettings.Object);
with.RootPathProvider<TestRootPathProvider>(); with.RootPathProvider<TestRootPathProvider>();
with.RequestStartup((container, pipelines, context) => with.RequestStartup((container, pipelines, context) =>

@ -81,6 +81,7 @@ namespace PlexRequests.UI
container.Register<ISettingsService<HeadphonesSettings>, SettingsServiceV2<HeadphonesSettings>>(); container.Register<ISettingsService<HeadphonesSettings>, SettingsServiceV2<HeadphonesSettings>>();
container.Register<ISettingsService<LogSettings>, SettingsServiceV2<LogSettings>>(); container.Register<ISettingsService<LogSettings>, SettingsServiceV2<LogSettings>>();
container.Register<ISettingsService<SlackNotificationSettings>, SettingsServiceV2<SlackNotificationSettings>>(); container.Register<ISettingsService<SlackNotificationSettings>, SettingsServiceV2<SlackNotificationSettings>>();
container.Register<ISettingsService<LandingPageSettings>, SettingsServiceV2<LandingPageSettings>>();
// Repo's // Repo's
container.Register<IRepository<LogEntity>, GenericRepository<LogEntity>>(); container.Register<IRepository<LogEntity>, GenericRepository<LogEntity>>();

@ -1,250 +0,0 @@
//
// Checkboxes
// --------------------------------------------------
$font-family-icon: 'FontAwesome' !default;
$fa-var-check: "\f00c" !default;
$check-icon: $fa-var-check !default;
@mixin checkbox-variant($parent, $color) {
#{$parent} input[type="checkbox"]:checked + label,
#{$parent} input[type="radio"]:checked + label {
&::before {
background-color: $color;
border-color: $color;
}
&::after{
color: #fff;
}
}
}
@mixin checkbox-variant-indeterminate($parent, $color) {
#{$parent} input[type="checkbox"]:indeterminate + label,
#{$parent} input[type="radio"]:indeterminate + label {
&::before {
background-color: $color;
border-color: $color;
}
&::after{
background-color: #fff;
}
}
}
.abc-checkbox{
padding-left: 20px;
label{
display: inline-block;
vertical-align: middle;
position: relative;
padding-left: 5px;
&::before{
cursor: pointer;
content: "";
display: inline-block;
position: absolute;
width: 17px;
height: 17px;
left: 0;
margin-left: -20px;
border: 1px solid $input-border-color;
border-radius: 3px;
background-color: #fff;
@include transition(border 0.15s ease-in-out, color 0.15s ease-in-out);
}
&::after{
cursor: pointer;
display: inline-block;
position: absolute;
width: 16px;
height: 16px;
left: 0;
top: 0;
margin-left: -20px;
padding-left: 3px;
padding-top: 1px;
font-size: 11px;
color: $input-color;
}
}
input[type="checkbox"],
input[type="radio"] {
cursor: pointer;
opacity: 0;
z-index: 1;
&:focus + label::before{
@include tab-focus();
}
&:checked + label::after{
font-family: $font-family-icon;
content: $check-icon;
}
&:indeterminate + label::after{
display: block;
content: "";
width: 10px;
height: 3px;
background-color: #555555;
border-radius: 2px;
margin-left: -16.5px;
margin-top: 7px;
}
&:disabled + label{
opacity: 0.65;
&::before{
background-color: $input-bg-disabled;
cursor: not-allowed;
}
}
}
&.abc-checkbox-circle label::before{
border-radius: 50%;
}
&.checkbox-inline{
margin-top: 0;
}
}
@include checkbox-variant('.abc-checkbox-primary', $brand-primary);
@include checkbox-variant('.abc-checkbox-danger', $brand-danger);
@include checkbox-variant('.abc-checkbox-info', $brand-info);
@include checkbox-variant('.abc-checkbox-warning', $brand-warning);
@include checkbox-variant('.abc-checkbox-success', $brand-success);
@include checkbox-variant-indeterminate('.abc-checkbox-primary', $brand-primary);
@include checkbox-variant-indeterminate('.abc-checkbox-danger', $brand-danger);
@include checkbox-variant-indeterminate('.abc-checkbox-info', $brand-info);
@include checkbox-variant-indeterminate('.abc-checkbox-warning', $brand-warning);
@include checkbox-variant-indeterminate('.abc-checkbox-success', $brand-success);
//
// Radios
// --------------------------------------------------
@mixin radio-variant($parent, $color) {
#{$parent} input[type="radio"]{
+ label{
&::after{
background-color: $color;
}
}
&:checked + label{
&::before {
border-color: $color;
}
&::after{
background-color: $color;
}
}
}
}
.abc-radio{
padding-left: 20px;
label{
display: inline-block;
vertical-align: middle;
position: relative;
padding-left: 5px;
&::before{
cursor: pointer;
content: "";
display: inline-block;
position: absolute;
width: 17px;
height: 17px;
left: 0;
margin-left: -20px;
border: 1px solid $input-border-color;
border-radius: 50%;
background-color: #fff;
@include transition(border 0.15s ease-in-out);
}
&::after{
cursor: pointer;
display: inline-block;
position: absolute;
content: " ";
width: 11px;
height: 11px;
left: 3px;
top: 3px;
margin-left: -20px;
border-radius: 50%;
background-color: $input-color;
transform: scale(0, 0);
transition: transform .1s cubic-bezier(.8,-0.33,.2,1.33);
//curve - http://cubic-bezier.com/#.8,-0.33,.2,1.33
}
}
input[type="radio"]{
cursor: pointer;
opacity: 0;
z-index: 1;
&:focus + label::before{
@include tab-focus();
}
&:checked + label::after{
transform: scale(1, 1);
}
&:disabled + label{
opacity: 0.65;
&::before{
cursor: not-allowed;
}
}
}
&.radio-inline{
margin-top: 0;
}
}
@include radio-variant('.abc-radio-primary', $brand-primary);
@include radio-variant('.abc-radio-danger', $brand-danger);
@include radio-variant('.abc-radio-info', $brand-info);
@include radio-variant('.abc-radio-warning', $brand-warning);
@include radio-variant('.abc-radio-success', $brand-success);
input[type="checkbox"],
input[type="radio"] {
&.styled:checked + label:after {
font-family: $font-family-icon;
content: $check-icon;
}
.styled:checked + label {
&::before {
color: #fff;
}
&::after {
color: #fff;
}
}
}

@ -0,0 +1,17 @@
// Import bootstrap variables including default color palette and fonts
@import "bootstrap/less/variables.less";
// Import datepicker component
@import "_bootstrap-datetimepicker.less";
//this is here so the compiler doesn't complain about a missing bootstrap mixin
.sr-only {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0,0,0,0);
border: 0;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,202 @@
/*!
* Datetimepicker for Bootstrap 3
* ! version : 4.7.14
* https://github.com/Eonasdan/bootstrap-datetimepicker/
*/
.sr-only, .bootstrap-datetimepicker-widget .btn[data-action="incrementHours"]::after, .bootstrap-datetimepicker-widget .btn[data-action="incrementMinutes"]::after, .bootstrap-datetimepicker-widget .btn[data-action="decrementHours"]::after, .bootstrap-datetimepicker-widget .btn[data-action="decrementMinutes"]::after, .bootstrap-datetimepicker-widget .btn[data-action="showHours"]::after, .bootstrap-datetimepicker-widget .btn[data-action="showMinutes"]::after, .bootstrap-datetimepicker-widget .btn[data-action="togglePeriod"]::after, .bootstrap-datetimepicker-widget .btn[data-action="clear"]::after, .bootstrap-datetimepicker-widget .btn[data-action="today"]::after, .bootstrap-datetimepicker-widget .picker-switch::after, .bootstrap-datetimepicker-widget table th.prev::after, .bootstrap-datetimepicker-widget table th.next::after {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0; }
.bootstrap-datetimepicker-widget {
list-style: none; }
.bootstrap-datetimepicker-widget.dropdown-menu {
margin: 2px 0;
padding: 4px;
width: 19em; }
@media (min-width: 768px) {
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
width: 38em; } }
@media (min-width: 768px) {
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
width: 38em; } }
@media (min-width: 768px) {
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
width: 38em; } }
.bootstrap-datetimepicker-widget.dropdown-menu:before, .bootstrap-datetimepicker-widget.dropdown-menu:after {
content: '';
display: inline-block;
position: absolute; }
.bootstrap-datetimepicker-widget.dropdown-menu.bottom:before {
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-bottom-color: rgba(0, 0, 0, 0.2);
top: -7px;
left: 7px; }
.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after {
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid white;
top: -6px;
left: 8px; }
.bootstrap-datetimepicker-widget.dropdown-menu.top:before {
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-top: 7px solid #ccc;
border-top-color: rgba(0, 0, 0, 0.2);
bottom: -7px;
left: 6px; }
.bootstrap-datetimepicker-widget.dropdown-menu.top:after {
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid white;
bottom: -6px;
left: 7px; }
.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:before {
left: auto;
right: 6px; }
.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:after {
left: auto;
right: 7px; }
.bootstrap-datetimepicker-widget .list-unstyled {
margin: 0; }
.bootstrap-datetimepicker-widget a[data-action] {
padding: 6px 0; }
.bootstrap-datetimepicker-widget a[data-action]:active {
box-shadow: none; }
.bootstrap-datetimepicker-widget .timepicker-hour, .bootstrap-datetimepicker-widget .timepicker-minute, .bootstrap-datetimepicker-widget .timepicker-second {
width: 54px;
font-weight: bold;
font-size: 1.2em;
margin: 0; }
.bootstrap-datetimepicker-widget button[data-action] {
padding: 6px; }
.bootstrap-datetimepicker-widget .btn[data-action="incrementHours"]::after {
content: "Increment Hours"; }
.bootstrap-datetimepicker-widget .btn[data-action="incrementMinutes"]::after {
content: "Increment Minutes"; }
.bootstrap-datetimepicker-widget .btn[data-action="decrementHours"]::after {
content: "Decrement Hours"; }
.bootstrap-datetimepicker-widget .btn[data-action="decrementMinutes"]::after {
content: "Decrement Minutes"; }
.bootstrap-datetimepicker-widget .btn[data-action="showHours"]::after {
content: "Show Hours"; }
.bootstrap-datetimepicker-widget .btn[data-action="showMinutes"]::after {
content: "Show Minutes"; }
.bootstrap-datetimepicker-widget .btn[data-action="togglePeriod"]::after {
content: "Toggle AM/PM"; }
.bootstrap-datetimepicker-widget .btn[data-action="clear"]::after {
content: "Clear the picker"; }
.bootstrap-datetimepicker-widget .btn[data-action="today"]::after {
content: "Set the date to today"; }
.bootstrap-datetimepicker-widget .picker-switch {
text-align: center; }
.bootstrap-datetimepicker-widget .picker-switch::after {
content: "Toggle Date and Time Screens"; }
.bootstrap-datetimepicker-widget .picker-switch td {
padding: 0;
margin: 0;
height: auto;
width: auto;
line-height: inherit; }
.bootstrap-datetimepicker-widget .picker-switch td span {
line-height: 2.5;
height: 2.5em;
width: 100%; }
.bootstrap-datetimepicker-widget table {
width: 100%;
margin: 0; }
.bootstrap-datetimepicker-widget table td,
.bootstrap-datetimepicker-widget table th {
text-align: center;
border-radius: #333333; }
.bootstrap-datetimepicker-widget table th {
height: 20px;
line-height: 20px;
width: 20px; }
.bootstrap-datetimepicker-widget table th.picker-switch {
width: 145px; }
.bootstrap-datetimepicker-widget table th.disabled, .bootstrap-datetimepicker-widget table th.disabled:hover {
background: none;
color: gray;
cursor: not-allowed; }
.bootstrap-datetimepicker-widget table th.prev::after {
content: "Previous Month"; }
.bootstrap-datetimepicker-widget table th.next::after {
content: "Next Month"; }
.bootstrap-datetimepicker-widget table thead tr:first-child th {
cursor: pointer; }
.bootstrap-datetimepicker-widget table thead tr:first-child th:hover {
background: gray; }
.bootstrap-datetimepicker-widget table td {
height: 54px;
line-height: 54px;
width: 54px; }
.bootstrap-datetimepicker-widget table td.cw {
font-size: .8em;
height: 20px;
line-height: 20px;
color: gray; }
.bootstrap-datetimepicker-widget table td.day {
height: 20px;
line-height: 20px;
width: 20px; }
.bootstrap-datetimepicker-widget table td.day:hover, .bootstrap-datetimepicker-widget table td.hour:hover, .bootstrap-datetimepicker-widget table td.minute:hover, .bootstrap-datetimepicker-widget table td.second:hover {
background: gray;
cursor: pointer; }
.bootstrap-datetimepicker-widget table td.old, .bootstrap-datetimepicker-widget table td.new {
color: gray; }
.bootstrap-datetimepicker-widget table td.today {
position: relative; }
.bootstrap-datetimepicker-widget table td.today:before {
content: '';
display: inline-block;
border: 0 0 7px 7px solid transparent;
border-bottom-color: #df691a;
border-top-color: rgba(0, 0, 0, 0.2);
position: absolute;
bottom: 4px;
right: 4px; }
.bootstrap-datetimepicker-widget table td.active, .bootstrap-datetimepicker-widget table td.active:hover {
background-color: #df691a;
color: #ff761b;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); }
.bootstrap-datetimepicker-widget table td.active.today:before {
border-bottom-color: #fff; }
.bootstrap-datetimepicker-widget table td.disabled, .bootstrap-datetimepicker-widget table td.disabled:hover {
background: none;
color: gray;
cursor: not-allowed; }
.bootstrap-datetimepicker-widget table td span {
display: inline-block;
width: 54px;
height: 54px;
line-height: 54px;
margin: 2px 1.5px;
cursor: pointer;
border-radius: #333333; }
.bootstrap-datetimepicker-widget table td span:hover {
background: gray; }
.bootstrap-datetimepicker-widget table td span.active {
background-color: #df691a;
color: #ff761b;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); }
.bootstrap-datetimepicker-widget table td span.old {
color: gray; }
.bootstrap-datetimepicker-widget table td span.disabled, .bootstrap-datetimepicker-widget table td span.disabled:hover {
background: none;
color: gray;
cursor: not-allowed; }
.bootstrap-datetimepicker-widget.usetwentyfour td.hour {
height: 27px;
line-height: 27px; }
.input-group.date .input-group-addon {
cursor: pointer; }

File diff suppressed because one or more lines are too long

@ -0,0 +1,353 @@
/*!
* Datetimepicker for Bootstrap 3
* ! version : 4.7.14
* https://github.com/Eonasdan/bootstrap-datetimepicker/
*/
$bs-datetimepicker-timepicker-font-size: 1.2em !default;
$bs-datetimepicker-active-bg: #df691a !default;
$bs-datetimepicker-active-color: #ff761b !default;
$bs-datetimepicker-border-radius: #333333 !default;
$bs-datetimepicker-btn-hover-bg: gray !default;
$bs-datetimepicker-disabled-color: gray !default;
$bs-datetimepicker-alternate-color: gray !default;
$bs-datetimepicker-secondary-border-color: #ccc !default;
$bs-datetimepicker-secondary-border-color-rgba: rgba(0, 0, 0, 0.2) !default;
$bs-datetimepicker-primary-border-color: white !default;
$bs-datetimepicker-text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25) !default;
.sr-only {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0,0,0,0);
border: 0;
}
.bootstrap-datetimepicker-widget {
list-style: none;
&.dropdown-menu {
margin: 2px 0;
padding: 4px;
width: 19em;
&.timepicker-sbs {
@media (min-width: 768px) {
width: 38em;
}
@media (min-width: 768px) {
width: 38em;
}
@media (min-width: 768px) {
width: 38em;
}
}
&:before, &:after {
content: '';
display: inline-block;
position: absolute;
}
&.bottom {
&:before {
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid $bs-datetimepicker-secondary-border-color;
border-bottom-color: $bs-datetimepicker-secondary-border-color-rgba;
top: -7px;
left: 7px;
}
&:after {
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid $bs-datetimepicker-primary-border-color;
top: -6px;
left: 8px;
}
}
&.top {
&:before {
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-top: 7px solid $bs-datetimepicker-secondary-border-color;
border-top-color: $bs-datetimepicker-secondary-border-color-rgba;
bottom: -7px;
left: 6px;
}
&:after {
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid $bs-datetimepicker-primary-border-color;
bottom: -6px;
left: 7px;
}
}
&.pull-right {
&:before {
left: auto;
right: 6px;
}
&:after {
left: auto;
right: 7px;
}
}
}
.list-unstyled {
margin: 0;
}
a[data-action] {
padding: 6px 0;
}
a[data-action]:active {
box-shadow: none;
}
.timepicker-hour, .timepicker-minute, .timepicker-second {
width: 54px;
font-weight: bold;
font-size: $bs-datetimepicker-timepicker-font-size;
margin: 0;
}
button[data-action] {
padding: 6px;
}
.btn[data-action="incrementHours"]::after {
@extend .sr-only;
content: "Increment Hours";
}
.btn[data-action="incrementMinutes"]::after {
@extend .sr-only;
content: "Increment Minutes";
}
.btn[data-action="decrementHours"]::after {
@extend .sr-only;
content: "Decrement Hours";
}
.btn[data-action="decrementMinutes"]::after {
@extend .sr-only;
content: "Decrement Minutes";
}
.btn[data-action="showHours"]::after {
@extend .sr-only;
content: "Show Hours";
}
.btn[data-action="showMinutes"]::after {
@extend .sr-only;
content: "Show Minutes";
}
.btn[data-action="togglePeriod"]::after {
@extend .sr-only;
content: "Toggle AM/PM";
}
.btn[data-action="clear"]::after {
@extend .sr-only;
content: "Clear the picker";
}
.btn[data-action="today"]::after {
@extend .sr-only;
content: "Set the date to today";
}
.picker-switch {
text-align: center;
&::after {
@extend .sr-only;
content: "Toggle Date and Time Screens";
}
td {
padding: 0;
margin: 0;
height: auto;
width: auto;
line-height: inherit;
span {
line-height: 2.5;
height: 2.5em;
width: 100%;
}
}
}
table {
width: 100%;
margin: 0;
& td,
& th {
text-align: center;
border-radius: $bs-datetimepicker-border-radius;
}
& th {
height: 20px;
line-height: 20px;
width: 20px;
&.picker-switch {
width: 145px;
}
&.disabled,
&.disabled:hover {
background: none;
color: $bs-datetimepicker-disabled-color;
cursor: not-allowed;
}
&.prev::after {
@extend .sr-only;
content: "Previous Month";
}
&.next::after {
@extend .sr-only;
content: "Next Month";
}
}
& thead tr:first-child th {
cursor: pointer;
&:hover {
background: $bs-datetimepicker-btn-hover-bg;
}
}
& td {
height: 54px;
line-height: 54px;
width: 54px;
&.cw {
font-size: .8em;
height: 20px;
line-height: 20px;
color: $bs-datetimepicker-alternate-color;
}
&.day {
height: 20px;
line-height: 20px;
width: 20px;
}
&.day:hover,
&.hour:hover,
&.minute:hover,
&.second:hover {
background: $bs-datetimepicker-btn-hover-bg;
cursor: pointer;
}
&.old,
&.new {
color: $bs-datetimepicker-alternate-color;
}
&.today {
position: relative;
&:before {
content: '';
display: inline-block;
border: 0 0 7px 7px solid transparent;
border-bottom-color: $bs-datetimepicker-active-bg;
border-top-color: $bs-datetimepicker-secondary-border-color-rgba;
position: absolute;
bottom: 4px;
right: 4px;
}
}
&.active,
&.active:hover {
background-color: $bs-datetimepicker-active-bg;
color: $bs-datetimepicker-active-color;
text-shadow: $bs-datetimepicker-text-shadow;
}
&.active.today:before {
border-bottom-color: #fff;
}
&.disabled,
&.disabled:hover {
background: none;
color: $bs-datetimepicker-disabled-color;
cursor: not-allowed;
}
span {
display: inline-block;
width: 54px;
height: 54px;
line-height: 54px;
margin: 2px 1.5px;
cursor: pointer;
border-radius: $bs-datetimepicker-border-radius;
&:hover {
background: $bs-datetimepicker-btn-hover-bg;
}
&.active {
background-color: $bs-datetimepicker-active-bg;
color: $bs-datetimepicker-active-color;
text-shadow: $bs-datetimepicker-text-shadow;
}
&.old {
color: $bs-datetimepicker-alternate-color;
}
&.disabled,
&.disabled:hover {
background: none;
color: $bs-datetimepicker-disabled-color;
cursor: not-allowed;
}
}
}
}
&.usetwentyfour {
td.hour {
height: 27px;
line-height: 27px;
}
}
}
.input-group.date {
& .input-group-addon {
cursor: pointer;
}
}

@ -66,6 +66,7 @@ namespace PlexRequests.UI.Helpers
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/awesome-bootstrap-checkbox.css\" type=\"text/css\"/>"); sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/awesome-bootstrap-checkbox.css\" type=\"text/css\"/>");
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/base.css\" type=\"text/css\"/>"); sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/base.css\" type=\"text/css\"/>");
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/Themes/{settings.ThemeName}\" type=\"text/css\"/>"); sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/Themes/{settings.ThemeName}\" type=\"text/css\"/>");
sb.AppendLine($"<link rel=\"stylesheet\" href=\"{content}/Content/datepicker.min.css\" type=\"text/css\"/>");
sb.AppendLine($"<script src=\"{content}/Content/jquery-2.2.1.min.js\"></script>"); sb.AppendLine($"<script src=\"{content}/Content/jquery-2.2.1.min.js\"></script>");
sb.AppendLine($"<script src=\"{content}/Content/handlebars.min.js\"></script>"); sb.AppendLine($"<script src=\"{content}/Content/handlebars.min.js\"></script>");
@ -75,6 +76,7 @@ namespace PlexRequests.UI.Helpers
sb.AppendLine($"<script src=\"{content}/Content/pace.min.js\"></script>"); sb.AppendLine($"<script src=\"{content}/Content/pace.min.js\"></script>");
sb.AppendLine($"<script src=\"{content}/Content/jquery.mixitup.js\"></script>"); sb.AppendLine($"<script src=\"{content}/Content/jquery.mixitup.js\"></script>");
sb.AppendLine($"<script src=\"{content}/Content/moment.min.js\"></script>"); sb.AppendLine($"<script src=\"{content}/Content/moment.min.js\"></script>");
sb.AppendLine($"<script src=\"{content}/Content/bootstrap-datetimepicker.min.js\"></script>");
return helper.Raw(sb.ToString()); return helper.Raw(sb.ToString());

@ -55,6 +55,7 @@ using PlexRequests.UI.Helpers;
using PlexRequests.UI.Models; using PlexRequests.UI.Models;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Threading.Tasks;
using Nancy.Json; using Nancy.Json;
using Nancy.Security; using Nancy.Security;
@ -83,6 +84,7 @@ namespace PlexRequests.UI.Modules
private INotificationService NotificationService { get; } private INotificationService NotificationService { get; }
private ICacheProvider Cache { get; } private ICacheProvider Cache { get; }
private ISettingsService<SlackNotificationSettings> SlackSettings { get; } private ISettingsService<SlackNotificationSettings> SlackSettings { get; }
private ISettingsService<LandingPageSettings> LandingSettings { get; }
private ISlackApi SlackApi { get; } private ISlackApi SlackApi { get; }
private static Logger Log = LogManager.GetCurrentClassLogger(); private static Logger Log = LogManager.GetCurrentClassLogger();
@ -105,7 +107,7 @@ namespace PlexRequests.UI.Modules
ISettingsService<HeadphonesSettings> headphones, ISettingsService<HeadphonesSettings> headphones,
ISettingsService<LogSettings> logs, ISettingsService<LogSettings> logs,
ICacheProvider cache, ISettingsService<SlackNotificationSettings> slackSettings, ICacheProvider cache, ISettingsService<SlackNotificationSettings> slackSettings,
ISlackApi slackApi) : base("admin", prService) ISlackApi slackApi, ISettingsService<LandingPageSettings> lp) : base("admin", prService)
{ {
PrService = prService; PrService = prService;
CpService = cpService; CpService = cpService;
@ -128,6 +130,7 @@ namespace PlexRequests.UI.Modules
Cache = cache; Cache = cache;
SlackSettings = slackSettings; SlackSettings = slackSettings;
SlackApi = slackApi; SlackApi = slackApi;
LandingSettings = lp;
this.RequiresClaims(UserClaims.Admin); this.RequiresClaims(UserClaims.Admin);
@ -186,6 +189,9 @@ namespace PlexRequests.UI.Modules
Get["/slacknotification"] = _ => SlackNotifications(); Get["/slacknotification"] = _ => SlackNotifications();
Post["/slacknotification"] = _ => SaveSlackNotifications(); Post["/slacknotification"] = _ => SaveSlackNotifications();
Get["/landingpage", true] = async (x,ct) => await LandingPage();
Post["/landingpage"] = _ => SaveSlackNotifications();
} }
private Negotiator Authentication() private Negotiator Authentication()
@ -806,5 +812,12 @@ namespace PlexRequests.UI.Modules
? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for Slack Notifications!" } ? new JsonResponseModel { Result = true, Message = "Successfully Updated the Settings for Slack Notifications!" }
: new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." }); : new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." });
} }
private async Task<Negotiator> LandingPage()
{
var settings = await LandingSettings.GetSettingsAsync();
return View["LandingPage", settings];
}
} }
} }

@ -0,0 +1,41 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: LandingPageModule.cs
// Created By: Jamie Rees
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ************************************************************************/
#endregion
using PlexRequests.Core;
using PlexRequests.Core.SettingModels;
namespace PlexRequests.UI.Modules
{
public class LandingPageModule : BaseModule
{
public LandingPageModule(ISettingsService<PlexRequestSettings> settingsService, ISettingsService<LandingPageSettings> landing) : base("landing", settingsService)
{
LandingSettings = landing;
}
private ISettingsService<LandingPageSettings> LandingSettings { get; }
}
}

@ -193,6 +193,7 @@
<Compile Include="Modules\BaseApiModule.cs" /> <Compile Include="Modules\BaseApiModule.cs" />
<Compile Include="Modules\BaseModule.cs" /> <Compile Include="Modules\BaseModule.cs" />
<Compile Include="Modules\IssuesModule.cs" /> <Compile Include="Modules\IssuesModule.cs" />
<Compile Include="Modules\LandingPageModule.cs" />
<Compile Include="Modules\UpdateCheckerModule.cs" /> <Compile Include="Modules\UpdateCheckerModule.cs" />
<Compile Include="Start\StartupOptions.cs" /> <Compile Include="Start\StartupOptions.cs" />
<Compile Include="Start\UpdateValue.cs" /> <Compile Include="Start\UpdateValue.cs" />
@ -243,6 +244,13 @@
<Compile Include="Startup.cs" /> <Compile Include="Startup.cs" />
<Compile Include="Validators\PlexRequestsValidator.cs" /> <Compile Include="Validators\PlexRequestsValidator.cs" />
<Compile Include="Modules\UserManagementModule.cs" /> <Compile Include="Modules\UserManagementModule.cs" />
<Content Include="Content\datepicker.css">
<DependentUpon>datepicker.scss</DependentUpon>
</Content>
<Content Include="Content\datepicker.min.css">
<DependentUpon>datepicker.css</DependentUpon>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Content\issue-details.js"> <Content Include="Content\issue-details.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@ -319,6 +327,13 @@
<DependentUpon>plex.css</DependentUpon> <DependentUpon>plex.css</DependentUpon>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="Content\bootstrap-datetimepicker.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Scripts\bootstrap-datetimepicker.js" />
<Content Include="Scripts\bootstrap-datetimepicker.min.js" />
<Content Include="Scripts\bootstrap.js" />
<Content Include="Scripts\bootstrap.min.js" />
<Content Include="Views\ApiDocs\index.html"> <Content Include="Views\ApiDocs\index.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@ -400,10 +415,11 @@
<None Include="compilerconfig.json.defaults"> <None Include="compilerconfig.json.defaults">
<DependentUpon>compilerconfig.json</DependentUpon> <DependentUpon>compilerconfig.json</DependentUpon>
</None> </None>
<None Include="Content\awesome-bootstrap-checkbox.scss"> <None Include="Content\datepicker.scss">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Include="Content\base.scss" /> <None Include="Content\base.scss" />
<None Include="Content\bootstrap-datetimepicker-build.less" />
<None Include="Content\Themes\original.scss" /> <None Include="Content\Themes\original.scss" />
<None Include="Content\Themes\plex.scss" /> <None Include="Content\Themes\plex.scss" />
<Content Include="Content\pace.min.js"> <Content Include="Content\pace.min.js">
@ -524,6 +540,9 @@
<Content Include="Views\Issues\Details.cshtml"> <Content Include="Views\Issues\Details.cshtml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Content Include="Views\Admin\LandingPage.cshtml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="Web.Debug.config"> <None Include="Web.Debug.config">
<DependentUpon>web.config</DependentUpon> <DependentUpon>web.config</DependentUpon>
</None> </None>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -0,0 +1,146 @@
@using PlexRequests.UI.Helpers
@Html.Partial("_Sidebar")
@{
var baseUrl = Html.GetBaseUrl();
var formAction = "/admin";
if (!string.IsNullOrEmpty(baseUrl.ToHtmlString()))
{
formAction = "/" + baseUrl.ToHtmlString() + formAction;
}
}
<div class="col-sm-8 col-sm-push-1">
<form class="form-horizontal" method="POST" id="mainForm">
<fieldset>
<legend>Landing Page Settings</legend>
<div class="form-group">
<div class="checkbox">
@if (Model.Enabled)
{
<input type="checkbox" id="Enabled" name="Enabled" checked="checked"><label for="Enabled">Enabled</label>
}
else
{
<input type="checkbox" id="Enabled" name="Enabled"><label for="Enabled">Enabled</label>
}
</div>
</div>
<small>If enabled then all users will be redirected to the landing page instead of the login page.</small>
<br/>
<div class="form-group">
<div class="checkbox">
@if (Model.NoticeEnable)
{
<input type="checkbox" id="NoticeEnable" name="NoticeEnable" checked="checked"><label for="NoticeEnable">Enable a notice</label>
}
else
{
<input type="checkbox" id="NoticeEnable" name="NoticeEnable"><label for="NoticeEnable">Enable a notice</label>
}
</div>
</div>
<p class="form-group">Notice Message</p>
<div class="form-group">
<div>
<input type="text" class="form-control-custom form-control " id="NoticeMessage" name="NoticeMessage" placeholder="e.g. Plex will be down for maintaince" value="@Model.NoticeMessage">
</div>
</div>
<div class="form-group">
<div class="checkbox">
@if (Model.EnabledNoticeTime)
{
<input type="checkbox" id="EnabledNoticeTime" name="EnabledNoticeTime" checked="checked"><label for="EnabledNoticeTime">Enable a time limit for the notices</label>
}
else
{
<input type="checkbox" id="EnabledNoticeTime" name="EnabledNoticeTime"><label for="EnabledNoticeTime">Enable a time limit for the notices</label>
}
</div>
</div>
<div class="form-group">
<div class='input-group date' id='datetimepicker6'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class="form-group">
<div class='input-group date' id='datetimepicker7'>
<input type='text' class="form-control"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class="form-group">
<div>
<button type="submit" id="save" class="btn btn-primary-outline">Submit</button>
</div>
</div>
</fieldset>
</form>
</div>
<script>
$(function () {
$('#save').click(function (e) {
e.preventDefault();
var theme = $("#themes option:selected").val();
var $form = $("#mainForm");
var data = $form.serialize();
data = data + "&themeName=" + theme;
$.ajax({
type: $form.prop("method"),
data: data,
url: $form.prop("action"),
dataType: "json",
success: function (response) {
if (response.result === true) {
generateNotify("Success!", "success");
} else {
generateNotify(response.message, "warning");
}
},
error: function (e) {
console.log(e);
generateNotify("Something went wrong!", "danger");
}
});
});
$('#datetimepicker6').datetimepicker({
dayViewHeaderFormat: 'MMMM YYYY'
});
$('#datetimepicker7').datetimepicker({
useCurrent: false //Important! See issue #1075
});
$("#datetimepicker6").on("dp.change", function (e) {
$('#datetimepicker7').data("DateTimePicker").minDate(e.date);
});
$("#datetimepicker7").on("dp.change", function (e) {
$('#datetimepicker6').data("DateTimePicker").maxDate(e.date);
});
});
</script>

@ -2,6 +2,7 @@
<div class="col-lg-3 col-md-3 col-sm-4"> <div class="col-lg-3 col-md-3 col-sm-4">
<div class="list-group table-of-contents"> <div class="list-group table-of-contents">
@Html.GetSidebarUrl(Context, "/admin", "Plex Request") @Html.GetSidebarUrl(Context, "/admin", "Plex Request")
@Html.GetSidebarUrl(Context, "/admin/landingpage", "Landing Page")
@Html.GetSidebarUrl(Context, "/admin/authentication", "Authentication") @Html.GetSidebarUrl(Context, "/admin/authentication", "Authentication")
@Html.GetSidebarUrl(Context, "/admin/plex", "Plex") @Html.GetSidebarUrl(Context, "/admin/plex", "Plex")
@Html.GetSidebarUrl(Context, "/admin/couchpotato", "CouchPotato") @Html.GetSidebarUrl(Context, "/admin/couchpotato", "CouchPotato")

@ -26,5 +26,13 @@
{ {
"outputFile": "Content/Themes/original.css", "outputFile": "Content/Themes/original.css",
"inputFile": "Content/Themes/original.scss" "inputFile": "Content/Themes/original.scss"
},
{
"outputFile": "Content/_bootstrap-datetimepicker.css",
"inputFile": "Content/_bootstrap-datetimepicker.less"
},
{
"outputFile": "Content/datepicker.css",
"inputFile": "Content/datepicker.scss"
} }
] ]

@ -1,16 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="bootstrap.less" version="3.3.5" targetFramework="net45" />
<package id="Bootstrap.v3.Datetimepicker" version="4.15.35.1" targetFramework="net45" />
<package id="CommandLineParser" version="2.0.275-beta" targetFramework="net45" /> <package id="CommandLineParser" version="2.0.275-beta" targetFramework="net45" />
<package id="Common.Logging" version="3.0.0" targetFramework="net45" /> <package id="Common.Logging" version="3.0.0" targetFramework="net45" />
<package id="Common.Logging.Core" version="3.0.0" targetFramework="net45" /> <package id="Common.Logging.Core" version="3.0.0" targetFramework="net45" />
<package id="Dapper" version="1.42" targetFramework="net45" /> <package id="Dapper" version="1.42" targetFramework="net45" />
<package id="FluentValidation" version="6.2.1.0" targetFramework="net45" /> <package id="FluentValidation" version="6.2.1.0" targetFramework="net45" />
<package id="jQuery" version="1.9.1" targetFramework="net45" />
<package id="MarkdownSharp" version="1.13.0.0" targetFramework="net45" /> <package id="MarkdownSharp" version="1.13.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="2.0.30506.0" targetFramework="net45" /> <package id="Microsoft.AspNet.Razor" version="2.0.30506.0" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" /> <package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net45" /> <package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.0" targetFramework="net45" /> <package id="Microsoft.Owin.Host.SystemWeb" version="3.0.0" targetFramework="net45" />
<package id="Microsoft.Owin.Hosting" version="3.0.1" targetFramework="net45" /> <package id="Microsoft.Owin.Hosting" version="3.0.1" targetFramework="net45" />
<package id="Moment.js" version="2.9.0" targetFramework="net45" />
<package id="Mono.Posix" version="4.0.0.0" targetFramework="net45" /> <package id="Mono.Posix" version="4.0.0.0" targetFramework="net45" />
<package id="Nancy" version="1.4.3" targetFramework="net45" /> <package id="Nancy" version="1.4.3" targetFramework="net45" />
<package id="Nancy.Authentication.Basic" version="1.4.1" targetFramework="net45" /> <package id="Nancy.Authentication.Basic" version="1.4.1" targetFramework="net45" />

Loading…
Cancel
Save