diff --git a/src/js/components/Notifications.js b/src/js/components/Notifications.js index d3f23002..a45e2c5c 100755 --- a/src/js/components/Notifications.js +++ b/src/js/components/Notifications.js @@ -76,19 +76,24 @@ export default class Notifications extends React.Component{ } var load_queue = this.props.load_queue - var is_loading = false + var load_count = 0 for (var key in load_queue){ if (load_queue.hasOwnProperty(key)){ - is_loading = true - break + load_count++ } } - if (is_loading){ + if (load_count > 0){ + var className = "loading " + if (load_count > 20){ + className += 'high' + } else if (load_count > 5){ + className += 'medium' + } else { + className += 'low' + } return ( -
- Loading -
+
) } else { return null @@ -98,6 +103,7 @@ export default class Notifications extends React.Component{ render(){ return (
+ {this.renderLoader()} {this.renderNotifications()} {this.renderProcesses()}
diff --git a/src/scss/components/_notifications.scss b/src/scss/components/_notifications.scss index b1a0cbef..ac8e04dd 100755 --- a/src/scss/components/_notifications.scss +++ b/src/scss/components/_notifications.scss @@ -3,7 +3,7 @@ .notifications { position: fixed; bottom: 15px; - right: 15px; + right: 30px; z-index: 99; pointer-events: none; width: 200px; @@ -62,7 +62,7 @@ bottom: 0; left: 0; right: 0; - height: 3px; + height: 4px; z-index: 1; } } @@ -86,6 +86,29 @@ } } + .loading { + @include pulse(0.1s); + position: fixed; + bottom: 8px; + right: 8px; + width: 5px; + height: 5px; + border-radius: 50%; + background: $mid_grey; + + &.high { + background: $red; + } + + &.medium { + background: $orange; + } + + &.low { + background: $green; + } + } + @include responsive( $bp_medium ){ bottom: 48px; left: 0; diff --git a/src/scss/global/_variables.scss b/src/scss/global/_variables.scss index 2db1f978..69fe013b 100755 --- a/src/scss/global/_variables.scss +++ b/src/scss/global/_variables.scss @@ -45,6 +45,10 @@ $bp_shallow: 650px; } } +/** + * General animations + **/ + @mixin animate( $duration: 0.2s, $easing: ease-in-out ){ -webkit-transition: all $duration $easing; -moz-transition: all $duration $easing; @@ -59,12 +63,6 @@ $bp_shallow: 650px; transition: none !important; } -@keyframes slideloader { - 0% { left: 0%; right: 100%; } - 50% { left: 0%; right: 0%; } - 100% { left: 100%; right: 0%; } -} - @keyframes shrink_from_right { from { width: 100%; } to { width: 0%; } @@ -88,11 +86,36 @@ $bp_shallow: 650px; animation-iteration-count: infinite; } +@keyframes pulse { + 0% { opacity: 0; } + 50% { opacity: 1; } + 100% { opacity: 0; } +} + +@mixin pulse( $duration: 0.5s ){ + animation-name: pulse; + animation-duration: $duration; + animation-timing-function: linear; + animation-iteration-count: infinite; +} + @mixin blur( $size: 10px ) { -webkit-filter: blur( $size ); filter: blur( $size ); } +@keyframes slideloader { + 0% { left: 0%; right: 100%; } + 50% { left: 0%; right: 0%; } + 100% { left: 100%; right: 0%; } +} + + +/** + * Grid layout + * Produces most album/playlist/artist grids + **/ + @mixin grid_item( $cols, $gap: 2% ){ width: ( 0% + ( 100 / $cols ) - ( $gap * 2 ) + ( ( $gap * 2 ) / $cols ) ); box-sizing: border-box; @@ -108,6 +131,12 @@ $bp_shallow: 650px; } } + +/** + * Responsive rules + * Creates @media wrappers + **/ + @mixin responsive( $max_width: null, $min_width: null, $max_height: null, $min_height: null ){ @if $max_width and $max_height { @media( max-width: $max_width ), ( max-height: $max_height ){ @@ -131,5 +160,3 @@ $bp_shallow: 650px; } } } - -