48 | )
49 | }
50 | }
51 |
52 | export default DeletePlaylistModal
53 |
--------------------------------------------------------------------------------
/src/components/modals/UnfollowPlaylistModal.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | class UnfollowPlaylistModal extends Component {
4 | render() {
5 | return (
6 |
7 |
this.props.closeModal()}
9 | className="modal-background"
10 | />
11 |
12 |
Sluta Följ Spellista
13 |
20 | Är du säker på att du vill sluta följa denna spellista?
21 |
22 |
40 |
41 |
42 |
48 | )
49 | }
50 | }
51 |
52 | export default UnfollowPlaylistModal
53 |
--------------------------------------------------------------------------------
/src/helpers/renderer.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { renderToString } from 'react-dom/server'
3 | import { StaticRouter } from 'react-router-dom'
4 |
5 | import { Provider } from 'react-redux'
6 | import { renderRoutes } from 'react-router-config'
7 | import serialize from 'serialize-javascript'
8 | import Routes from '../routes'
9 |
10 | export default (req, store, context) => {
11 | const content = renderToString(
12 |
13 |
14 | {renderRoutes(Routes)}
15 |
16 |
17 | )
18 |
19 | return `
20 |
21 |
22 |
23 |
24 |
25 |
26 |
Soundize - Music for everyone
27 |
28 |
29 |
32 |
${content}
33 |
36 |
37 |
38 |
39 |
40 | `
41 | }
42 |
--------------------------------------------------------------------------------
/src/helpers/serverStore.js:
--------------------------------------------------------------------------------
1 | import { createStore, compose, applyMiddleware } from 'redux'
2 | import thunk from 'redux-thunk'
3 | import { persistStore, autoRehydrate } from 'redux-persist'
4 |
5 | import reducers from '../reducers'
6 |
7 | export default req => {
8 | const store = createStore(reducers, {}, compose(applyMiddleware(thunk)))
9 |
10 | return store
11 | }
12 |
13 | // autoRehydrate() into compose if you want to save store
14 |
15 | /* Lägg till whitelist: ['someReducer'] i options objektet nedan, om vi ska spara nått specifikt i localstorage/Asyncstorage */
16 | // persistStore(store, { storage: AsyncStorage }) // chain on '.purge()' to clear async
17 |
--------------------------------------------------------------------------------
/src/images/Soundize-logo2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Alexloof/Soundize/bee397de65c439f884fd40dab587508520d9c2ed/src/images/Soundize-logo2.PNG
--------------------------------------------------------------------------------
/src/images/devices.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Alexloof/Soundize/bee397de65c439f884fd40dab587508520d9c2ed/src/images/devices.png
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom'
3 |
4 | import {
5 | BrowserRouter,
6 | HashRouter,
7 | Switch,
8 | Route,
9 | Redirect
10 | } from 'react-router-dom'
11 | import { Provider } from 'react-redux'
12 |
13 | import './stylesheets/main.scss'
14 | import store from './store'
15 | import Routes from './routes'
16 | import { renderRoutes } from 'react-router-config'
17 |
18 | if (process.env.NODE_ENV !== 'production') {
19 | console.log('Looks like we are in development mode!')
20 | }
21 |
22 | if (module.hot) {
23 | module.hot.accept()
24 | }
25 |
26 | const Root = () => {
27 | return (
28 |
29 |
30 | {renderRoutes(Routes)}
31 |
32 |
33 | )
34 | }
35 |
36 | ReactDOM.hydrate(
, document.querySelector('#root'))
37 |
--------------------------------------------------------------------------------
/src/reducers/album_reducer.js:
--------------------------------------------------------------------------------
1 | import { SET_ALBUM } from '../actions/album_actions'
2 |
3 | let INITIAL_STATE = {
4 | album: {}
5 | }
6 |
7 | export default (state = INITIAL_STATE, action) => {
8 | switch (action.type) {
9 | case SET_ALBUM:
10 | return { ...state, album: action.payload }
11 |
12 | default:
13 | return state
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/reducers/artist_reducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | SET_ARTIST,
3 | SET_ARTIST_ALBUMS,
4 | SET_ARTIST_TOP_TRACKS,
5 | SET_ARTIST_RELATED_ARTISTS
6 | } from '../actions/artist_actions'
7 |
8 | let INITIAL_STATE = {
9 | artist: {},
10 | albums: [],
11 | topTracks: [],
12 | relatedArtists: []
13 | }
14 |
15 | export default (state = INITIAL_STATE, action) => {
16 | switch (action.type) {
17 | case SET_ARTIST:
18 | return { ...state, artist: action.payload }
19 |
20 | case SET_ARTIST_ALBUMS:
21 | return { ...state, albums: action.payload }
22 |
23 | case SET_ARTIST_TOP_TRACKS:
24 | return { ...state, topTracks: action.payload }
25 |
26 | case SET_ARTIST_RELATED_ARTISTS:
27 | return { ...state, relatedArtists: action.payload }
28 |
29 | default:
30 | return state
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/reducers/category_reducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | SET_CATEGORIES,
3 | SET_ACTIVE_CATEGORY_PLAYLISTS
4 | } from '../actions/category_actions'
5 |
6 | let INITIAL_STATE = {
7 | categories: [],
8 | activeCategoryPlaylists: []
9 | }
10 |
11 | export default (state = INITIAL_STATE, action) => {
12 | switch (action.type) {
13 | case SET_CATEGORIES:
14 | return { ...state, categories: action.payload }
15 |
16 | case SET_ACTIVE_CATEGORY_PLAYLISTS:
17 | return { ...state, activeCategoryPlaylists: action.payload }
18 |
19 | default:
20 | return state
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/reducers/index.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux'
2 |
3 | import playlist from './playlist_reducer'
4 | import track from './track_reducer'
5 | import user from './user_reducer'
6 | import player from './player_reducer'
7 | import categories from './category_reducer'
8 | import search from './search_reducer'
9 | import album from './album_reducer'
10 | import artist from './artist_reducer'
11 |
12 | export default combineReducers({
13 | playlist,
14 | track,
15 | user,
16 | player,
17 | categories,
18 | search,
19 | album,
20 | artist
21 | })
22 |
--------------------------------------------------------------------------------
/src/reducers/player_reducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | PLAY_ACTIVE_TRACK,
3 | PAUSE_ACTIVE_TRACK,
4 | TOGGLE_ACTIVE_TRACK,
5 | SHOW_MUSICBAR,
6 | SET_PLAYED_TIME,
7 | START_SEEK,
8 | STOP_SEEK,
9 | CHANGE_SEEK,
10 | ZERO_PLAYED_TIME,
11 | TOGGLE_SHUFFLE
12 | } from '../actions/player_actions'
13 |
14 | const INITIAL_STATE = {
15 | isPlaying: false,
16 | playedTime: 0,
17 | isSeeking: false,
18 | showMusicbar: false,
19 | isShuffling: false
20 | }
21 |
22 | export default function(state = INITIAL_STATE, action) {
23 | switch (action.type) {
24 | case PLAY_ACTIVE_TRACK:
25 | return { ...state, isPlaying: true }
26 |
27 | case PAUSE_ACTIVE_TRACK:
28 | return { ...state, isPlaying: false }
29 |
30 | case TOGGLE_ACTIVE_TRACK:
31 | return { ...state, isPlaying: !state.isPlaying }
32 |
33 | case SHOW_MUSICBAR:
34 | return { ...state, showMusicbar: true }
35 |
36 | case SET_PLAYED_TIME:
37 | return { ...state, playedTime: action.payload }
38 |
39 | case START_SEEK:
40 | return { ...state, isSeeking: true }
41 |
42 | case STOP_SEEK:
43 | return { ...state, isSeeking: false }
44 |
45 | case CHANGE_SEEK:
46 | return { ...state, playedTime: action.payload }
47 |
48 | case ZERO_PLAYED_TIME:
49 | return { ...state, playedTime: 0 }
50 |
51 | case TOGGLE_SHUFFLE:
52 | return { ...state, isShuffling: !state.isShuffling }
53 | default:
54 | return state
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/reducers/playlist_reducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | SET_PLAYLISTS,
3 | SET_PRIVATE_PLAYLISTS,
4 | SET_FEATURED_PLAYLISTS,
5 | SET_ACTIVE_PLAYLIST,
6 | SET_NEW_RELEASES
7 | } from '../actions/playlist_actions'
8 |
9 | const INITIAL_STATE = {
10 | playlists: [],
11 | privatePlaylists: [],
12 | featuredPlaylists: [],
13 | activePlaylistId: null,
14 | playingPlaylist: null,
15 | newReleases: []
16 | }
17 |
18 | export default function(state = INITIAL_STATE, action) {
19 | switch (action.type) {
20 | case SET_PLAYLISTS:
21 | return { ...state, playlists: action.payload }
22 |
23 | case SET_PRIVATE_PLAYLISTS:
24 | return { ...state, privatePlaylists: action.payload }
25 |
26 | case SET_FEATURED_PLAYLISTS:
27 | return { ...state, featuredPlaylists: action.payload }
28 |
29 | case SET_ACTIVE_PLAYLIST:
30 | return { ...state, activePlaylistId: action.payload }
31 |
32 | case SET_NEW_RELEASES:
33 | return { ...state, newReleases: action.payload }
34 | default:
35 | return state
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/reducers/search_reducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | SET_SEARCHED_ARTISTS,
3 | SET_SEARCHED_TRACKS,
4 | SET_SEARCHED_PLAYLISTS
5 | } from '../actions/search_actions'
6 |
7 | let INITIAL_STATE = {
8 | searchedArtists: [],
9 | searchedPlaylists: [],
10 | searchedTracks: []
11 | }
12 |
13 | export default (state = INITIAL_STATE, action) => {
14 | switch (action.type) {
15 | case SET_SEARCHED_ARTISTS:
16 | return { ...state, searchedArtists: action.payload }
17 |
18 | case SET_SEARCHED_TRACKS:
19 | return { ...state, searchedTracks: action.payload }
20 |
21 | case SET_SEARCHED_PLAYLISTS:
22 | return { ...state, searchedPlaylists: action.payload }
23 |
24 | default:
25 | return state
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/reducers/track_reducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | SET_ACTIVE_TRACKLIST,
3 | SET_PLAYING_TRACKLIST,
4 | ADD_TRACK_TO_QUEUED_LIST,
5 | REMOVE_TRACK_FROM_QUEUED_LIST,
6 | ADD_TRACK_TO_LATEST_PLAYED,
7 | SET_ACTIVE_TRACK,
8 | SET_ACTIVE_TRACKINDEX,
9 | SET_TRACK_DETAIL
10 | } from '../actions/track_actions'
11 |
12 | const INITIAL_STATE = {
13 | trackDetail: {
14 | album: {
15 | images: null
16 | }
17 | },
18 | activeTracklist: null,
19 | playingTracklist: {
20 | id: ''
21 | },
22 | loadingTracklist: false,
23 | activeTrack: {
24 | id: null,
25 | images: null,
26 | artists: [],
27 | name: null
28 | },
29 | activeTrackIndex: 0,
30 | latestPlayedTracks: [],
31 | queuedTracks: []
32 | }
33 |
34 | export default function(state = INITIAL_STATE, action) {
35 | switch (action.type) {
36 | case SET_TRACK_DETAIL:
37 | return { ...state, trackDetail: action.payload }
38 |
39 | case SET_ACTIVE_TRACKLIST:
40 | return { ...state, activeTracklist: action.payload }
41 |
42 | case SET_PLAYING_TRACKLIST:
43 | return { ...state, playingTracklist: action.payload }
44 |
45 | case ADD_TRACK_TO_QUEUED_LIST:
46 | if (state.queuedTracks) {
47 | return {
48 | ...state,
49 | queuedTracks: [...state.queuedTracks, action.payload]
50 | }
51 | } else {
52 | return { ...state, queuedTracks: [action.payload] }
53 | }
54 |
55 | case REMOVE_TRACK_FROM_QUEUED_LIST:
56 | let newQueuedTracks = state.queuedTracks.filter((track, index) => {
57 | return index !== action.payload
58 | })
59 | return { ...state, queuedTracks: newQueuedTracks }
60 |
61 | case ADD_TRACK_TO_LATEST_PLAYED:
62 | if (state.latestPlayedTracks.length > 0) {
63 | if (
64 | state.latestPlayedTracks[state.latestPlayedTracks.length - 1].id !==
65 | action.payload.id
66 | ) {
67 | return {
68 | ...state,
69 | latestPlayedTracks: [...state.latestPlayedTracks, action.payload]
70 | }
71 | } else {
72 | return { ...state }
73 | }
74 | } else {
75 | return { ...state, latestPlayedTracks: [action.payload] }
76 | }
77 |
78 | case SET_ACTIVE_TRACK:
79 | return { ...state, activeTrack: action.payload }
80 |
81 | case SET_ACTIVE_TRACKINDEX:
82 | if (!action.payload && action.payload !== 0) {
83 | console.log('Inget track index skickades med vid start')
84 | return { ...state }
85 | } else {
86 | return { ...state, activeTrackIndex: action.payload }
87 | }
88 |
89 | default:
90 | return state
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/reducers/user_reducer.js:
--------------------------------------------------------------------------------
1 | import { SET_USER, FAIL_USER } from '../actions/user_actions'
2 |
3 | let INITIAL_STATE = {
4 | user: 'loading'
5 | }
6 |
7 | export default (state = INITIAL_STATE, action) => {
8 | switch (action.type) {
9 | case SET_USER:
10 | return { ...state, user: action.payload || false }
11 |
12 | case FAIL_USER:
13 | return { ...state, user: null }
14 | default:
15 | return state
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/routes.js:
--------------------------------------------------------------------------------
1 | import App from './components/App'
2 | import Home from './components/Home'
3 | import Login from './components/Login'
4 | import Search from './components/Search'
5 | import Callback from './components/Callback'
6 | import Discover from './components/Discover'
7 | import DiscoverCategory from './components/DiscoverCategory'
8 | import PlaylistDetail from './components/PlaylistDetail'
9 | import NewReleases from './components/NewReleases'
10 | import Toplists from './components/Toplists'
11 | import AlbumDetail from './components/AlbumDetail'
12 | import ArtistDetail from './components/ArtistDetail'
13 | import TrackDetail from './components/TrackDetail'
14 |
15 | import React from 'react'
16 |
17 | import { Redirect } from 'react-router'
18 |
19 | export default [
20 | {
21 | path: '/callback',
22 | component: Callback,
23 | exact: false
24 | },
25 | {
26 | path: '/',
27 | component: Login,
28 | exact: true
29 | },
30 | {
31 | path: '/app',
32 | component: App,
33 | exact: false,
34 | routes: [
35 | {
36 | path: '/app',
37 | component: Home,
38 | exact: true
39 | },
40 | {
41 | path: '/app/discover',
42 | component: Discover,
43 | exact: true
44 | },
45 | {
46 | path: '/app/discover/:category',
47 | component: DiscoverCategory,
48 | exact: true
49 | },
50 | {
51 | path: '/app/new_releases',
52 | component: NewReleases,
53 | exact: true
54 | },
55 | {
56 | path: '/app/toplists',
57 | component: Toplists,
58 | exact: true
59 | },
60 | {
61 | path: '/app/albums/:id',
62 | component: AlbumDetail,
63 | exact: true
64 | },
65 | {
66 | path: '/app/artists/:id',
67 | component: ArtistDetail,
68 | exact: true
69 | },
70 | {
71 | path: '/app/tracks/:id',
72 | component: TrackDetail,
73 | exact: true
74 | },
75 | {
76 | path: '/app/playlists/:user/:id',
77 | component: PlaylistDetail,
78 | exact: true
79 | },
80 | {
81 | path: '/app/search',
82 | component: Search,
83 | exact: false
84 | }
85 | ]
86 | },
87 | {
88 | component: () =>
89 | }
90 | ]
91 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import { createStore, compose, applyMiddleware } from 'redux'
2 | import thunk from 'redux-thunk'
3 | import { persistStore, autoRehydrate } from 'redux-persist'
4 |
5 | import reducers from '../reducers'
6 |
7 | const store = createStore(
8 | reducers,
9 | {},
10 | compose(
11 | applyMiddleware(thunk),
12 | window.devToolsExtension ? window.devToolsExtension() : f => f
13 | )
14 | )
15 |
16 | // autoRehydrate() into compose if you want to save store
17 |
18 | /* Lägg till whitelist: ['someReducer'] i options objektet nedan, om vi ska spara nått specifikt i localstorage/Asyncstorage */
19 | // persistStore(store, { storage: AsyncStorage }) // chain on '.purge()' to clear async
20 |
21 | export default store
22 |
--------------------------------------------------------------------------------
/src/stylesheets/base.scss:
--------------------------------------------------------------------------------
1 | body {
2 | color: $body-default-color;
3 | font-family: $body-default-font-familty;
4 | }
5 |
6 | html {
7 | font-size: 14px;
8 | overflow-y: auto;
9 |
10 | background: linear-gradient(rgba(255, 107, 66, 0.42), rgba(0, 0, 0, 0.9) 75%),
11 | url('https://images.pexels.com/photos/167605/pexels-photo-167605.jpeg?w=1260&h=750&auto=compress&cs=tinysrgb');
12 | background-attachment: fixed;
13 | background-size: cover;
14 | background-position: bottom;
15 | }
16 |
17 | .app {
18 | background: linear-gradient(
19 | transparentize($color: #d1dede, $amount: 0.2),
20 | transparentize($color: #b5bec6, $amount: 0.2) 55%
21 | );
22 | }
23 |
24 | * {
25 | margin: 0;
26 | padding: 0;
27 | box-sizing: border-box;
28 | }
29 | a {
30 | text-decoration: none;
31 | cursor: pointer;
32 | }
33 |
34 | button {
35 | transition: 0.35s all cubic-bezier(0.09, 0.97, 0.34, 0.63) !important;
36 | cursor: pointer;
37 | }
38 |
39 | main,
40 | li {
41 | display: block;
42 | }
43 |
44 | strong {
45 | font-weight: bold;
46 | }
47 |
48 | .linear-gradient {
49 | background: linear-gradient(transparent, $brand-primary);
50 | }
51 |
52 | // alerts
53 | .s-alert-box {
54 | box-shadow: $box-shadow-large;
55 | min-width: 200px;
56 | }
57 | .s-alert-success {
58 | background-color: rgba(71, 150, 94, 0.966);
59 | }
60 |
61 | .hidden {
62 | opacity: 0 !important;
63 | }
64 |
65 | .go-back-button {
66 | position: fixed;
67 | width: 40px;
68 | height: 40px;
69 | z-index: 1000;
70 | border-radius: 50px;
71 | border: 0;
72 | left: 15px;
73 | top: 67px;
74 | background: $gray-lightdark;
75 | color: $gray-light;
76 | box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12),
77 | 0 3px 1px -2px rgba(0, 0, 0, 0.2);
78 | @media screen and (max-width: $break-mobile) {
79 | left: 5px;
80 | top: 5px;
81 | }
82 | }
83 |
84 | .columns {
85 | margin: 0 !important;
86 | }
87 |
88 | //nedan är en klass för att göra scrollbar invisible i webkit-browsers som chrome
89 | .invisible-scrollbar::-webkit-scrollbar {
90 | display: none;
91 | }
92 |
93 | // Remove google chromes yellow autofll
94 | input:-webkit-autofill,
95 | input:-webkit-autofill:hover,
96 | input:-webkit-autofill:focus,
97 | input:-webkit-autofill:active {
98 | -webkit-transition-delay: 9999s !important;
99 | -webkit-transition: color 9999s ease-out, background-color 9999s ease-out !important;
100 | }
101 |
102 | .effect1 {
103 | -webkit-box-shadow: 0 10px 6px -6px rgba(0, 0, 0, 0.233);
104 | -moz-box-shadow: 0 10px 6px -6px rgba(0, 0, 0, 0.233);
105 | box-shadow: 0 10px 6px -6px rgba(0, 0, 0, 0.233);
106 | }
107 |
108 | .effect8 {
109 | position: relative;
110 | -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3),
111 | 0 0 40px rgba(0, 0, 0, 0.1) inset;
112 | -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3),
113 | 0 0 40px rgba(0, 0, 0, 0.1) inset;
114 | box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
115 | }
116 | .effect8:before,
117 | .effect8:after {
118 | content: '';
119 | position: absolute;
120 | z-index: -1;
121 | -webkit-box-shadow: 0 0 14px rgba(0, 0, 0, 0.7);
122 | -moz-box-shadow: 0 0 14px rgba(0, 0, 0, 0.7);
123 | box-shadow: 0 0 14px 0px rgba(0, 0, 0, 0.7);
124 | top: 10px;
125 | bottom: 10px;
126 | left: 0;
127 | right: 0;
128 | -moz-border-radius: 100px / 10px;
129 | border-radius: 100px / 10px;
130 | }
131 | .effect8:after {
132 | right: 10px;
133 | left: auto;
134 | -webkit-transform: skew(8deg) rotate(3deg);
135 | -moz-transform: skew(8deg) rotate(3deg);
136 | -ms-transform: skew(8deg) rotate(3deg);
137 | -o-transform: skew(8deg) rotate(3deg);
138 | transform: skew(8deg) rotate(3deg);
139 | }
140 |
--------------------------------------------------------------------------------
/src/stylesheets/components/albumDetail.scss:
--------------------------------------------------------------------------------
1 | .album-detail-component {
2 | width: 50%;
3 | margin-left: 25%;
4 | background-color: $gray-light;
5 | padding: 0;
6 | box-shadow: 0px 0px 6px 1px rgba(99, 99, 99, 0.12);
7 | padding-bottom: $nav-height;
8 | min-height: calc(100vh - #{$nav-height});
9 | @media screen and (max-width: $break-mobile) {
10 | width: 100%;
11 | margin-left: 0px;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/stylesheets/components/artistDetail.scss:
--------------------------------------------------------------------------------
1 | $artist-dimension: 22vw;
2 |
3 | .artist-detail-component {
4 | max-width: $container-large;
5 | background-color: $gray-light;
6 | min-height: calc(100vh - #{$nav-height});
7 | margin: 0 auto;
8 | display: flex;
9 | flex-direction: row;
10 | box-shadow: 0px 0px 6px 1px rgba(99, 99, 99, 0.12);
11 | padding: 20px;
12 | padding-bottom: 52px;
13 | .artist-info {
14 | width: $artist-dimension;
15 | margin-right: 20px;
16 | .artist-art-wrapper {
17 | position: relative;
18 | display: flex;
19 | justify-content: center;
20 | width: $artist-dimension;
21 | height: $artist-dimension;
22 | box-shadow: $box-shadow-primary;
23 | .artist-art {
24 | width: $artist-dimension;
25 | height: $artist-dimension;
26 | }
27 | .artist-art-fader {
28 | width: $artist-dimension;
29 | height: $artist-dimension;
30 | background: linear-gradient(transparent, rgb(0, 0, 0) 100%);
31 | position: absolute;
32 | top: 0;
33 | }
34 | h1 {
35 | text-align: center;
36 | font-weight: bold;
37 | font-size: 2.5rem;
38 | letter-spacing: 1px;
39 | margin-bottom: 20px;
40 | position: absolute;
41 | bottom: 0;
42 | color: white;
43 | }
44 | }
45 | .artist-info-box {
46 | padding: 10px 0px;
47 | padding: 0px 5px;
48 | .artist-genres {
49 | margin: 10px 0px;
50 | flex-wrap: wrap;
51 | display: flex;
52 | .genre {
53 | background-color: $brand-secondary;
54 | color: white;
55 | padding: 3px 10px;
56 | border-radius: 50px;
57 | margin: 3px;
58 | box-shadow: $box-shadow-small;
59 | letter-spacing: 1px;
60 | font-size: 13px;
61 | white-space: nowrap;
62 | }
63 | }
64 | .artist-followers {
65 | font-size: 14px;
66 | margin-bottom: 10px;
67 | span {
68 | font-size: 17px;
69 | margin-right: 4px;
70 | font-weight: bold;
71 | letter-spacing: 1px;
72 | color: $gray-lightdark;
73 | }
74 | }
75 | .artist-popularity {
76 | font-size: 14px;
77 | span {
78 | font-size: 17px;
79 | margin-right: 4px;
80 | font-weight: bold;
81 | letter-spacing: 1px;
82 | color: $gray-lightdark;
83 | }
84 | }
85 | }
86 | .artist-related {
87 | margin-top: 4rem;
88 | padding: 0px 5px;
89 | h2 {
90 | text-align: center;
91 | font-size: 1.4rem;
92 | margin-bottom: 5px;
93 | }
94 | .related-list {
95 | display: flex;
96 | flex-wrap: wrap;
97 | justify-content: space-between;
98 | .artist-related-solo {
99 | margin-bottom: 10px;
100 | width: 33%;
101 | display: flex;
102 | flex-direction: column;
103 | align-items: center;
104 | img {
105 | height: 50px;
106 | width: 50px;
107 | border-radius: 50%;
108 | margin: 5px;
109 | cursor: pointer;
110 | box-shadow: $box-shadow-primary;
111 | }
112 | p {
113 | text-align: center;
114 | overflow: hidden;
115 | text-overflow: ellipsis;
116 | font-size: 0.8rem;
117 | cursor: pointer;
118 | &:hover {
119 | text-decoration: underline;
120 | }
121 | }
122 | }
123 | }
124 | }
125 | }
126 | .artist-albums {
127 | width: 30%;
128 | h2 {
129 | text-align: center;
130 | font-size: 1.8rem;
131 | }
132 | .album-list {
133 | display: flex;
134 | flex-wrap: wrap;
135 | justify-content: space-around;
136 | .artist-album {
137 | margin-bottom: 20px;
138 | width: 35%;
139 | display: flex;
140 | flex-direction: column;
141 | align-items: center;
142 | img {
143 | height: 70px;
144 | width: 70px;
145 | border-radius: 50%;
146 | margin: 5px;
147 | cursor: pointer;
148 | box-shadow: $box-shadow-primary;
149 | }
150 | p {
151 | text-align: center;
152 | overflow: hidden;
153 | text-overflow: ellipsis;
154 | font-size: 0.8rem;
155 | cursor: pointer;
156 | &:hover {
157 | text-decoration: underline;
158 | }
159 | }
160 | }
161 | }
162 | }
163 | .artist-top-tracks {
164 | width: 40%;
165 | h2 {
166 | text-align: center;
167 | font-size: 1.8rem;
168 | }
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/src/stylesheets/components/discover.scss:
--------------------------------------------------------------------------------
1 | .discover-component {
2 | max-width: $container-large;
3 | background-color: $gray-light;
4 | min-height: 90vh;
5 | margin: 0 auto;
6 | display: flex;
7 | flex-direction: column;
8 | box-shadow: 0px 0px 6px 1px rgba(99, 99, 99, 0.12);
9 | padding: 20px;
10 | padding-bottom: 52px;
11 | @media screen and (max-width: $break-mobile) {
12 | padding: 5px;
13 | }
14 | h1 {
15 | text-align: center;
16 | font-size: 2rem;
17 | margin-bottom: 20px;
18 | }
19 | .discover-list {
20 | display: flex;
21 | flex-wrap: wrap;
22 | justify-content: space-around;
23 | width: 100%;
24 | .discover-item {
25 | position: relative;
26 | display: flex;
27 | justify-content: center;
28 | margin-bottom: 20px;
29 | cursor: pointer;
30 |
31 | img {
32 | width: 225px;
33 | height: 225px;
34 | transition: 0.3s all ease;
35 | box-shadow: $box-shadow-primary;
36 | }
37 | h2 {
38 | position: absolute;
39 | top: 80%;
40 | color: $gray-light;
41 | cursor: pointer;
42 | transition: 0.35s all ease;
43 | letter-spacing: 1px;
44 | font-size: 0.9rem;
45 | white-space: nowrap;
46 | overflow: hidden;
47 | width: 100%;
48 | text-align: center;
49 | }
50 | &:hover h2 {
51 | text-decoration: underline;
52 | color: $brand-secondary;
53 | }
54 | &:hover img {
55 | filter: invert(10%);
56 | }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/stylesheets/components/discoverCategory.scss:
--------------------------------------------------------------------------------
1 | .discover-category-component {
2 | max-width: $container-large;
3 | background-color: $gray-light;
4 | min-height: 90vh;
5 | margin: 0 auto;
6 | display: flex;
7 | flex-direction: column;
8 | box-shadow: 0px 0px 6px 1px rgba(99, 99, 99, 0.12);
9 | padding: 20px;
10 | padding-bottom: 52px;
11 | h1 {
12 | text-align: center;
13 | font-size: 2rem;
14 | margin-bottom: 20px;
15 | &:first-letter {
16 | text-transform: capitalize;
17 | }
18 | }
19 | .discover-category-list {
20 | display: flex;
21 | flex-wrap: wrap;
22 | justify-content: space-around;
23 | width: 100%;
24 | .discover-category-item {
25 | position: relative;
26 | display: flex;
27 | justify-content: center;
28 | margin-bottom: 20px;
29 | cursor: pointer;
30 |
31 | img {
32 | width: 225px;
33 | height: 225px;
34 | transition: 0.3s all ease;
35 | box-shadow: $box-shadow-primary;
36 | }
37 |
38 | &:hover img {
39 | filter: invert(15%);
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/stylesheets/components/extraInfolist.scss:
--------------------------------------------------------------------------------
1 | $max-list-height: 250px;
2 |
3 | .extra-infolist {
4 | position: fixed;
5 | top: $nav-height;
6 | right: 0;
7 | background-color: $gray-light;
8 | box-shadow: -2px -2px 4px 0px rgba(78, 78, 78, 0.1);
9 | padding-right: 0;
10 | width: 250px !important;
11 | padding-top: 1.5%;
12 | padding-bottom: 0;
13 | height: 100%;
14 | @media screen and (max-width: $break-mobile) {
15 | display: none;
16 | }
17 | .menu {
18 | .top-label {
19 | display: flex;
20 | justify-content: space-between;
21 | align-content: center;
22 | margin-bottom: 10px;
23 | }
24 | p.menu-label {
25 | font-size: 0.9em;
26 | color: #484848;
27 | letter-spacing: 0.2em;
28 | padding-left: 1rem;
29 | font-weight: bold;
30 | margin-left: 30px;
31 | }
32 | .latest-played {
33 | max-height: $max-list-height;
34 | overflow-y: hidden;
35 | .flip-move {
36 | display: flex;
37 | flex-direction: column-reverse;
38 | }
39 | li {
40 | display: flex;
41 | flex-direction: row;
42 | align-items: center;
43 | justify-content: space-between;
44 | margin-bottom: 10px;
45 | padding: 3px 0px;
46 | .left-grp {
47 | display: flex;
48 | flex-direction: row;
49 | align-items: center;
50 | max-width: 82%;
51 | img {
52 | height: 35px;
53 | width: 35px;
54 | border-radius: 50px;
55 | box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.363);
56 | }
57 | .track-info {
58 | margin-left: 10px;
59 | white-space: nowrap;
60 | overflow: hidden;
61 | text-overflow: ellipsis;
62 | line-height: 16px;
63 | .artist-label {
64 | font-size: 10px;
65 | overflow: hidden;
66 | text-overflow: ellipsis;
67 | }
68 | .title-label {
69 | font-size: 11px;
70 | overflow: hidden;
71 | text-overflow: ellipsis;
72 | }
73 | }
74 | }
75 | .right-grp {
76 | margin-right: 10px;
77 |
78 | button {
79 | border-radius: 50px;
80 | box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.08);
81 | &:focus {
82 | border-color: #dbdbdb;
83 | }
84 | .fa {
85 | font-size: 12px;
86 | }
87 | }
88 | }
89 | }
90 | }
91 | .queued-tracks {
92 | max-height: $max-list-height;
93 | overflow-y: hidden;
94 | li {
95 | display: flex;
96 | flex-direction: row;
97 | align-items: center;
98 | justify-content: space-between;
99 | margin-bottom: 10px;
100 | padding: 3px 0px;
101 | .left-grp {
102 | display: flex;
103 | flex-direction: row;
104 | align-items: center;
105 | max-width: 82%;
106 | img {
107 | height: 35px;
108 | width: 35px;
109 | border-radius: 50px;
110 | box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.363);
111 | }
112 | .track-info {
113 | margin-left: 10px;
114 | white-space: nowrap;
115 | overflow: hidden;
116 | text-overflow: ellipsis;
117 | line-height: 16px;
118 | .artist-label {
119 | font-size: 10px;
120 | overflow: hidden;
121 | text-overflow: ellipsis;
122 | }
123 | .title-label {
124 | font-size: 11px;
125 | overflow: hidden;
126 | text-overflow: ellipsis;
127 | }
128 | }
129 | }
130 | .right-grp {
131 | margin-right: 10px;
132 | .fa-remove {
133 | cursor: pointer;
134 | font-size: 18px;
135 | }
136 | button {
137 | border-radius: 50px;
138 | &:focus {
139 | border-color: #dbdbdb;
140 | }
141 | .fa {
142 | font-size: 12px;
143 | }
144 | }
145 | }
146 | }
147 | }
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/src/stylesheets/components/login.scss:
--------------------------------------------------------------------------------
1 | .login-wrapper {
2 | .banner-button {
3 | color: white;
4 | background: $brand-secondary;
5 | display: inline-block;
6 | width: 220px;
7 | height: 52px;
8 | border-radius: 30px;
9 | margin-top: 3%;
10 | padding-top: 15px;
11 | letter-spacing: 4px;
12 | transition: all 300ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
13 | @media screen and (max-width: $break-mobile) {
14 | margin-top: 10%;
15 | }
16 | }
17 |
18 | .fa {
19 | font-size: 26px;
20 | padding: 15px;
21 | border: 1px solid white;
22 | border-radius: 200%;
23 | transition: all 200ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
24 | cursor: pointer;
25 | }
26 |
27 | #scrollToTop {
28 | padding: 10px;
29 | font-size: 50px;
30 | border: none;
31 | color: $brand-secondary;
32 | transition: 0.3s;
33 | cursor: pointer;
34 | position: fixed;
35 | bottom: 20px;
36 | right: 20px;
37 | z-index: 99;
38 | }
39 |
40 | .banner-info {
41 | text-align: center;
42 | position: relative;
43 | margin-top: 15%;
44 | @media screen and (max-width: $break-mobile) {
45 | margin-top: 25%;
46 | }
47 | }
48 | .banner-info h1 {
49 | font-size: 65px;
50 | margin: 10px;
51 | color: white;
52 | font-weight: bold;
53 | letter-spacing: 5px;
54 | text-shadow: 2px 2px 20px rgba(0, 0, 0, 0.62);
55 | @media screen and (max-width: $break-mobile) {
56 | font-size: 35px;
57 | }
58 | }
59 | .banner-info #mini-info {
60 | display: inline-block;
61 | text-transform: uppercase;
62 | margin-top: 10%;
63 | color: white;
64 | font-size: 14px;
65 | letter-spacing: 3px;
66 | padding-bottom: 4px;
67 | border-bottom: 1px solid $brand-secondary;
68 | margin-bottom: 10px;
69 | transition: all 300ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
70 | }
71 | .banner-info .fa {
72 | padding: 15px;
73 | color: white;
74 | background: rgba(0, 0, 0, 0.1);
75 | }
76 |
77 | .banner-two {
78 | margin-top: 95px;
79 | background: #232323;
80 | width: 100%;
81 | height: 750px;
82 | position: relative;
83 | color: white;
84 | }
85 | .banner-two img {
86 | max-width: 50%;
87 | margin-top: 9%;
88 | margin-left: 5%;
89 | @media screen and (max-width: $break-mobile) {
90 | display: none;
91 | }
92 | }
93 | .banner-two .banner-two-info {
94 | float: right;
95 | width: 40%;
96 | color: $brand-secondary;
97 | position: relative;
98 | margin-top: 8%;
99 | padding-right: 5%;
100 | @media screen and (max-width: $break-mobile) {
101 | width: 100%;
102 | padding-left: 5%;
103 | }
104 | }
105 | .banner-two .banner-two-info h1 {
106 | font-size: 46px;
107 | padding-bottom: 5%;
108 | font-weight: bold;
109 | @media screen and (max-width: $break-mobile) {
110 | font-size: 30px;
111 | }
112 | }
113 | .banner-two .banner-two-info h2 {
114 | font-size: 35px;
115 | @media screen and (max-width: $break-mobile) {
116 | font-size: 25px;
117 | }
118 | }
119 | .banner-two .banner-two-info p {
120 | color: rgb(218, 218, 218);
121 | padding-bottom: 25px;
122 | line-height: 30px;
123 | }
124 |
125 | .banner-three {
126 | width: 100%;
127 | height: 650px;
128 | background-color: white;
129 | }
130 | .banner-three .fa {
131 | padding: 15px;
132 | color: white;
133 | border: none;
134 | background: $brand-secondary;
135 | text-align: center;
136 | position: relative;
137 | margin-left: 48.5%;
138 | top: -28px;
139 | }
140 | .banner-three a {
141 | margin: 20px;
142 | width: 30%;
143 | margin-top: 80px;
144 | border: 1px solid white;
145 | @media screen and (max-width: $break-mobile) {
146 | width: 80%;
147 | margin: 30px;
148 | height: 70px;
149 | }
150 | }
151 | .banner-three h1 {
152 | font-size: 60px;
153 | margin-top: 10%;
154 | margin-bottom: 2%;
155 | font-weight: bold;
156 | @media screen and (max-width: $break-mobile) {
157 | font-size: 35px;
158 | }
159 | }
160 | .banner-three div {
161 | text-align: center;
162 | }
163 |
164 | .banner-four {
165 | height: 730px;
166 | background: #f1b265;
167 | background: -moz-linear-gradient(
168 | -45deg,
169 | #f1b265 0%,
170 | #f1b265 4%,
171 | $brand-secondary 100%
172 | );
173 | background: -webkit-gradient(
174 | left top,
175 | right bottom,
176 | color-stop(0%, #f1b265),
177 | color-stop(4%, #f1b265),
178 | color-stop(100%, $brand-secondary)
179 | );
180 | background: -webkit-linear-gradient(
181 | -45deg,
182 | #f1b265 0%,
183 | #f1b265 4%,
184 | $brand-secondary 100%
185 | );
186 | background: -o-linear-gradient(
187 | -45deg,
188 | #f1b265 0%,
189 | #f1b265 4%,
190 | $brand-secondary 100%
191 | );
192 | background: -ms-linear-gradient(
193 | -45deg,
194 | #f1b265 0%,
195 | #f1b265 4%,
196 | $brand-secondary 100%
197 | );
198 | background: linear-gradient(
199 | 135deg,
200 | #f1b265 0%,
201 | #f1b265 4%,
202 | $brand-secondary 100%
203 | );
204 | filter: progid:DXImageTransform.Microsoft.gradient(
205 | startColorstr='#f1b265',
206 | endColorstr='#ff5724',
207 | GradientType=1
208 | );
209 | text-align: center;
210 | padding-top: 100px;
211 | }
212 | .banner-four h1 {
213 | font-size: 60px;
214 | color: white;
215 | font-weight: bold;
216 | @media screen and (max-width: $break-mobile) {
217 | font-size: 35px;
218 | }
219 | }
220 | .banner-four .services {
221 | display: flex;
222 | flex-wrap: wrap;
223 | justify-content: center;
224 | position: relative;
225 | }
226 | .banner-four .services .service-one,
227 | .banner-four .services .service-two,
228 | .banner-four .services .service-three {
229 | width: 50%;
230 | padding-left: 3%;
231 | padding-right: 3%;
232 | padding-top: 5%;
233 | p {
234 | color: rgb(43, 43, 43);
235 | }
236 | }
237 | .banner-four .services .service-one h2,
238 | .banner-four .services .service-two h2,
239 | .banner-four .services .service-three h2 {
240 | font-size: 40px;
241 | color: white;
242 | @media screen and (max-width: $break-mobile) {
243 | font-size: 25px;
244 | }
245 | }
246 | .scroll-down-three {
247 | padding: 15px;
248 | color: white;
249 | border: none;
250 | background: $brand-secondary;
251 | text-align: center;
252 | position: relative;
253 | margin-left: 0%;
254 | top: -130px;
255 | }
256 | footer {
257 | clear: both;
258 | background-color: #232323;
259 | text-align: center;
260 | height: 300px;
261 | color: #dee6f2;
262 | }
263 | footer .fa {
264 | margin-top: 50px;
265 | margin-left: 10px;
266 | margin-right: 10px;
267 | }
268 | footer h2 {
269 | padding-top: 50px;
270 | font-size: 1.1rem;
271 | }
272 | }
273 |
--------------------------------------------------------------------------------
/src/stylesheets/components/musicbar.scss:
--------------------------------------------------------------------------------
1 | .music-bar {
2 | position: fixed;
3 | left: 0;
4 | right: 0;
5 | bottom: -52px;
6 | width: 100vw;
7 | height: $nav-height;
8 | background-color: $brand-primary;
9 | box-shadow: 0px 1px 6px 0px rgba(72, 72, 72, 0.43);
10 | color: $gray-light;
11 | transition: 0.5s all ease;
12 | z-index: 9;
13 | .my-container {
14 | padding: 0 3%;
15 | display: flex;
16 | flex-direction: row;
17 | align-items: center;
18 | height: 100%;
19 | .dropdown {
20 | .track-open-mini-meny {
21 | margin-right: 15px;
22 | margin-left: 0;
23 | i {
24 | padding: 1.2px;
25 | }
26 | }
27 | .dropdown-menu {
28 | top: -80px;
29 | left: 20px;
30 | .mini-meny-playlists {
31 | bottom: 0;
32 | top: auto;
33 | }
34 | }
35 | @media screen and (max-width: $break-mobile) {
36 | display: none;
37 | }
38 | }
39 | .img-info {
40 | display: flex;
41 | flex-direction: row;
42 | align-items: center;
43 | margin-right: 2%;
44 | min-width: 20%;
45 | max-width: 20%;
46 | @media screen and (max-width: $break-mobile) {
47 | width: 40%;
48 | max-width: none;
49 | min-width: 40%;
50 | }
51 | img {
52 | width: $nav-height - 10px;
53 | height: $nav-height - 10px;
54 | margin-right: 3%;
55 | }
56 | .track-info {
57 | overflow-x: hidden;
58 | white-space: nowrap;
59 | .artist-label {
60 | font-size: 11px;
61 | overflow: hidden;
62 | text-overflow: ellipsis;
63 | span {
64 | cursor: pointer;
65 | &:hover {
66 | text-decoration: underline;
67 | }
68 | }
69 | }
70 | .track-title {
71 | font-size: 12px;
72 | overflow: hidden;
73 | text-overflow: ellipsis;
74 | cursor: pointer;
75 | &:hover {
76 | text-decoration: underline;
77 | }
78 | }
79 | }
80 | }
81 | .track-running-wrapper {
82 | display: flex;
83 | flex-direction: row;
84 | align-items: center;
85 | width: 40%;
86 | margin-right: 3%;
87 | @media screen and (max-width: $break-mobile) {
88 | display: none;
89 | }
90 | .time-counter {
91 | font-size: 11px;
92 | margin-right: 5px;
93 | }
94 | .time-duration {
95 | font-size: 11px;
96 | margin-left: 5px;
97 | }
98 | .running-track {
99 | width: 100%;
100 | position: relative;
101 | }
102 | .played-color {
103 | height: 3px;
104 | background: $brand-secondary;
105 | position: absolute;
106 | z-index: 10;
107 | }
108 | .track-color {
109 | height: 3px;
110 | background: $gray-medium;
111 | position: absolute;
112 | width: 100%;
113 | }
114 | }
115 | .sound-options {
116 | display: flex;
117 | flex-direction: row;
118 | align-items: center;
119 | @media screen and (max-width: $break-mobile) {
120 | display: none;
121 | }
122 | .fa {
123 | font-size: 18px;
124 | cursor: pointer;
125 | margin-right: 10px;
126 | }
127 | .volume-wrapper {
128 | width: 50px;
129 | position: relative;
130 | .volume-amount-color {
131 | height: 2px;
132 | background-color: $brand-secondary;
133 | position: absolute;
134 | z-index: 10;
135 | }
136 | .volume-color {
137 | height: 2px;
138 | background-color: $gray-medium;
139 | position: absolute;
140 | width: 100%;
141 | }
142 | }
143 | input[type='range'] {
144 | width: 100%;
145 | background-color: transparent;
146 | position: relative;
147 | z-index: 10;
148 | }
149 | input[type='range']::-webkit-slider-thumb {
150 | //box-shadow: 0px 0px 0.9px #000000, 0px 0px 0px #0d0d0d;
151 | border: 0px solid #00001e;
152 | height: 10px;
153 | width: 10px;
154 | border-radius: 50px;
155 | background: $gray-light;
156 | cursor: pointer;
157 | -webkit-appearance: none;
158 | margin-top: -3.85px;
159 | }
160 | input[type='range']::-webkit-slider-runnable-track {
161 | width: 100%;
162 | height: 2px;
163 | cursor: pointer; //box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
164 | background: transparent;
165 | border-radius: 50px;
166 | border: 0px solid #000101;
167 | }
168 | input[type='range']::-moz-range-thumb {
169 | //box-shadow: 0px 0px 0.9px #000000, 0px 0px 0px #0d0d0d;
170 | border: 0px solid #00001e;
171 | height: 10px;
172 | width: 10px;
173 | border-radius: 50px;
174 | background: $gray-light;
175 | cursor: pointer;
176 | }
177 | input[type='range']::-ms-thumb {
178 | //box-shadow: 0px 0px 0.9px #000000, 0px 0px 0px #0d0d0d;
179 | border: 0px solid #00001e;
180 | height: 10px;
181 | width: 10px;
182 | border-radius: 50px;
183 | background: $gray-light;
184 | cursor: pointer;
185 | height: 3px;
186 | }
187 | }
188 | .fullscreen {
189 | margin-right: 2%;
190 | .fa {
191 | font-size: 18px;
192 | cursor: pointer;
193 | }
194 | @media screen and (max-width: $break-mobile) {
195 | display: none;
196 | }
197 | }
198 | #analyzer {
199 | margin-left: 2%;
200 | width: 22%;
201 | height: 65px;
202 | @media screen and (max-width: $break-mobile) {
203 | display: none;
204 | }
205 | }
206 | input[type='range'] {
207 | -webkit-appearance: none;
208 | width: 100%;
209 | background-color: transparent;
210 | position: relative;
211 | z-index: 10;
212 | }
213 | input[type='range']:focus {
214 | outline: none;
215 | }
216 | input[type='range']::-webkit-slider-runnable-track {
217 | width: 100%;
218 | height: 3px;
219 | cursor: pointer; //box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
220 | background: transparent;
221 | border-radius: 50px;
222 | border: 0px solid #000101;
223 | }
224 | input[type='range']::-webkit-slider-thumb {
225 | //box-shadow: 0px 0px 0.9px #000000, 0px 0px 0px #0d0d0d;
226 | border: 0px solid #00001e;
227 | height: 15px;
228 | width: 15px;
229 | border-radius: 50px;
230 | background: $gray-light;
231 | cursor: pointer;
232 | -webkit-appearance: none;
233 | margin-top: -5.85px;
234 | z-index: 10;
235 | }
236 | input[type='range']:focus::-webkit-slider-runnable-track {
237 | background: transparent;
238 | }
239 | input[type='range']::-moz-range-track {
240 | width: 100%;
241 | height: 3px;
242 | cursor: pointer; //box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
243 | background: transparent;
244 | border-radius: 50px;
245 | border: 0px solid #000101;
246 | }
247 | input[type='range']::-moz-range-thumb {
248 | //box-shadow: 0px 0px 0.9px #000000, 0px 0px 0px #0d0d0d;
249 | border: 0px solid #00001e;
250 | height: 15px;
251 | width: 15px;
252 | border-radius: 50px;
253 | background: $gray-light;
254 | cursor: pointer;
255 | }
256 | input[type='range']::-ms-track {
257 | width: 100%;
258 | height: 3px;
259 | cursor: pointer;
260 | background: transparent;
261 | border-color: transparent;
262 | color: transparent;
263 | }
264 | input[type='range']::-ms-fill-lower {
265 | background: transparent;
266 | border: 0px solid #000101;
267 | border-radius: 50px; //box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
268 | }
269 | input[type='range']::-ms-fill-upper {
270 | background: transparent;
271 | border: 0px solid #000101;
272 | border-radius: 50px; //box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
273 | }
274 | input[type='range']::-ms-thumb {
275 | //box-shadow: 0px 0px 0.9px #000000, 0px 0px 0px #0d0d0d;
276 | border: 0px solid #00001e;
277 | height: 15px;
278 | width: 15px;
279 | border-radius: 50px;
280 | background: $gray-light;
281 | cursor: pointer;
282 | height: 3px;
283 | }
284 | input[type='range']:focus::-ms-fill-lower {
285 | background: transparent;
286 | }
287 | input[type='range']:focus::-ms-fill-upper {
288 | background: transparent;
289 | }
290 | }
291 | }
292 | .music-bar.display-music-bar {
293 | bottom: 0;
294 | }
295 |
--------------------------------------------------------------------------------
/src/stylesheets/components/musicbarActions.scss:
--------------------------------------------------------------------------------
1 | .musicbar-actions {
2 | display: flex;
3 | flex-direction: row;
4 | align-items: center;
5 | margin-right: 2%;
6 | .step-change-btn {
7 | height: 30px;
8 | width: 30px;
9 | border-radius: 50%;
10 | background-color: transparent;
11 | border: none;
12 | color: $gray-light;
13 | .icon {
14 | height: 1.4em;
15 | width: 1.4em;
16 | }
17 | &:focus,
18 | &:active {
19 | border: none;
20 | }
21 | .fa {
22 | font-size: 15px;
23 | }
24 | .fa.active {
25 | color: #52de72;
26 | }
27 | }
28 | .play-btn {
29 | height: 35px;
30 | width: 35px;
31 | border-radius: 50%;
32 | margin: 0 0.7rem;
33 | .icon {
34 | height: 1.2em;
35 | width: 1.2em;
36 | }
37 | &:focus {
38 | border-color: #dbdbdb;
39 | }
40 | .fa {
41 | font-size: 14px;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/stylesheets/components/nav.scss:
--------------------------------------------------------------------------------
1 | $menu-items: 4;
2 | $background-color: $brand-primary;
3 | $indicator-color: $brand-secondary;
4 | $transition-speed: 0.4s;
5 | $width: (100/$menu-items) * 1%;
6 | $menu-items-loop-offset: $menu-items - 1;
7 |
8 | .navbar {
9 | background-color: $nav-background-color;
10 | height: $nav-height;
11 | position: fixed;
12 | left: 0;
13 | right: 0;
14 | top: 0;
15 | z-index: 30;
16 | display: flex;
17 | flex-direction: row;
18 | align-items: center;
19 | @media screen and (max-width: $break-mobile) {
20 | display: flex;
21 | justify-content: center;
22 | }
23 | .navbar-brand {
24 | position: absolute;
25 | a.navbar-item {
26 | font-weight: bold;
27 | letter-spacing: 4px;
28 | font-size: 19px;
29 | @media screen and (max-width: $break-mobile) {
30 | font-size: 1.1rem;
31 | letter-spacing: 1px;
32 | }
33 | img {
34 | max-height: none;
35 | @media screen and (max-width: $break-mobile) {
36 | height: 2rem;
37 | }
38 | }
39 | &:hover {
40 | border-color: transparent;
41 | background-color: transparent;
42 | }
43 | }
44 | }
45 | .burge-menu {
46 | display: none;
47 | cursor: pointer;
48 | .fa {
49 | font-size: 1.5rem;
50 | color: #bdbdbd;
51 | }
52 | @media screen and (max-width: $break-mobile) {
53 | display: block;
54 | position: absolute;
55 | right: 25px;
56 | color: white;
57 | }
58 | }
59 | .mobile-links-menu {
60 | background: rgba(0, 27, 35, 0.98);
61 | width: 100vw;
62 | height: 100vh;
63 | top: -100vh;
64 | transition: 0.3s opacity ease;
65 | position: absolute;
66 | display: flex;
67 | flex-direction: column;
68 | justify-content: flex-start;
69 | align-items: center;
70 | opacity: 0;
71 | a {
72 | color: white;
73 | font-size: 1.2rem;
74 | border-bottom: 1px solid white;
75 | width: 80%;
76 | margin-bottom: 20px;
77 | text-align: center;
78 | }
79 | @media screen and (max-width: $break-mobile) {
80 | &.active {
81 | opacity: 1;
82 | top: $nav-height;
83 | }
84 | }
85 | }
86 | .navbar-menu {
87 | height: $nav-height;
88 | .navbar-start {
89 | margin-left: 24.7%;
90 | list-style: none;
91 | max-width: 720px;
92 | padding: 0;
93 | width: 500px;
94 | max-width: 650px;
95 | .navbar-item {
96 | display: block;
97 | float: left;
98 | margin: 0;
99 | padding: 0;
100 | width: $width;
101 | text-align: center;
102 | position: static;
103 | font-weight: 500;
104 | font-size: 13px;
105 | letter-spacing: 1.5px;
106 | &:first-child {
107 | border-radius: 3px 0 0 3px;
108 | }
109 | &:last-child {
110 | border-radius: 0 3px 3px 0;
111 | }
112 | &.active span {
113 | color: $brand-secondary;
114 | }
115 | &:hover {
116 | background-color: transparent;
117 | }
118 | span {
119 | color: $nav-font-color;
120 | display: block;
121 | padding-top: 18px;
122 | padding-bottom: 20px;
123 | text-decoration: none;
124 | }
125 | }
126 | &.with-indicator {
127 | position: relative;
128 | z-index: 0;
129 | .navbar-item {
130 | &:last-child {
131 | //&:before,
132 | &:after {
133 | content: '';
134 | display: block;
135 | position: absolute;
136 | pointer-events: none;
137 | transition: all #{$transition-speed} ease; //cubic-bezier(0.55, 0.72, 0.35, 1.22);
138 | }
139 | // &:before {
140 | // border: 6px solid transparent;
141 | // border-top-color: $indicator-color;
142 | // width: 0;
143 | // height: 0;
144 | // top: 0;
145 | // left: ($width/2);
146 | // margin-left: -3px;
147 | // }
148 | &:after {
149 | background: $indicator-color;
150 | bottom: 0px;
151 | left: 0;
152 | height: 3px;
153 | width: $width;
154 | z-index: -1;
155 | }
156 | }
157 | }
158 | @for $i from 1 through $menu-items-loop-offset {
159 | .navbar-item:nth-child(#{$i}).active ~ .navbar-item:last-child:after {
160 | left: ($width*$i)-$width;
161 | }
162 | .navbar-item:nth-child(#{$i}).active
163 | ~ .navbar-item:last-child:before {
164 | left: ($width*$i)+($width/2)-$width;
165 | }
166 | }
167 |
168 | @for $i from 1 through $menu-items-loop-offset {
169 | .navbar-item:nth-child(#{$i}):hover ~ .navbar-item:last-child:after {
170 | left: ($width*$i)-$width !important;
171 | }
172 | .navbar-item:nth-child(#{$i}):hover ~ .navbar-item:last-child:before {
173 | left: ($width*$i)+($width/2)-$width !important;
174 | }
175 | }
176 | .navbar-item {
177 | &:last-child {
178 | &:hover,
179 | &.active {
180 | &:before {
181 | left: (100%-$width)+($width/2) !important;
182 | }
183 | &:after {
184 | left: 100%-$width !important;
185 | }
186 | }
187 | }
188 | }
189 | }
190 | }
191 | }
192 | input[type='text'] {
193 | align-self: center;
194 | width: 200px;
195 | border-radius: 1px;
196 | transition: 0.3s all ease-in-out;
197 | height: 2.2rem;
198 | &:focus {
199 | width: 250px;
200 | border-color: transparent;
201 | }
202 | }
203 | .navbar-end {
204 | form {
205 | margin-right: 5%;
206 | align-self: center;
207 | .icon.is-right {
208 | height: 2em;
209 | cursor: pointer;
210 | top: 2px;
211 | }
212 | }
213 | .login-btn {
214 | color: white;
215 | font-size: 16px;
216 | letter-spacing: 2px;
217 | align-self: center;
218 | padding-right: 30px;
219 | }
220 | img {
221 | max-height: 30px;
222 | border-radius: 50%;
223 | cursor: pointer;
224 | }
225 | .user-nav-link {
226 | color: $nav-font-color;
227 | transition: 0.3s all ease-in-out;
228 | letter-spacing: 1px;
229 | font-size: 13px;
230 | background-color: transparent !important;
231 | &:hover {
232 | background-color: transparent !important;
233 | }
234 | &:after {
235 | border-color: white;
236 | margin-top: -0.55em;
237 | height: 0.7em;
238 | width: 0.7em;
239 | right: 0.725em;
240 | }
241 | @media only screen and (max-width: 1216px) {
242 | display: none;
243 | }
244 | }
245 | .user-nav-dropdown {
246 | padding-bottom: 10px;
247 | padding-top: 10px;
248 | }
249 | .navbar-dropdown {
250 | background-color: $brand-primary;
251 | font-size: 0.8rem;
252 | border: none;
253 | border-radius: 0px;
254 | margin-top: -1px;
255 | box-shadow: $box-shadow-primary;
256 | min-width: 150px;
257 | right: 0;
258 | left: auto;
259 | &:hover {
260 | background-color: $brand-primary;
261 | display: block;
262 | }
263 | .navbar-item {
264 | border-bottom: none;
265 | color: white;
266 | &:hover {
267 | border-bottom: none;
268 | background-color: transparent;
269 | text-decoration: underline;
270 | }
271 | }
272 | }
273 | }
274 | }
275 |
--------------------------------------------------------------------------------
/src/stylesheets/components/newReleases.scss:
--------------------------------------------------------------------------------
1 | .new-releases-component {
2 | max-width: $container-large;
3 | background-color: $gray-light;
4 | min-height: 90vh;
5 | margin: 0 auto;
6 | display: flex;
7 | flex-direction: column;
8 | box-shadow: 0px 0px 6px 1px rgba(99, 99, 99, 0.12);
9 | padding: 20px;
10 | padding-bottom: 52px;
11 | h1 {
12 | text-align: center;
13 | font-size: 2rem;
14 | margin-bottom: 20px;
15 | }
16 | .new-releases-list {
17 | display: flex;
18 | flex-wrap: wrap;
19 | justify-content: space-around;
20 | width: 100%;
21 | .new-releases-item {
22 | position: relative;
23 | display: flex;
24 | justify-content: center;
25 | margin-bottom: 20px;
26 | cursor: pointer;
27 | img {
28 | width: 378px;
29 | height: 378px;
30 | transition: 0.3s all ease;
31 | box-shadow: $box-shadow-primary;
32 | }
33 | &:hover img {
34 | filter: invert(15%);
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/stylesheets/components/playlists.scss:
--------------------------------------------------------------------------------
1 | .playlists-menu {
2 | position: fixed;
3 | top: $nav-height;
4 | background-color: $gray-light;
5 | box-shadow: 2px 2px 4px 0px rgba(78, 78, 78, 0.1);
6 | padding-right: 0;
7 | width: 250px !important;
8 | padding-top: 1.5%;
9 | padding-bottom: 0;
10 | height: 100%;
11 | transition: 0.25s all ease;
12 | @media screen and (max-width: $break-mobile) {
13 | transform: translateX(-250px);
14 | z-index: 10;
15 | padding-top: 15px;
16 | &.active {
17 | transform: translateX(0px);
18 | }
19 | }
20 | .menu {
21 | .top-label {
22 | display: flex;
23 | justify-content: space-between;
24 | align-content: center;
25 | margin-bottom: 10px;
26 | i {
27 | margin-right: 1.5rem;
28 | color: #484848;
29 | font-size: 1.2rem;
30 | cursor: pointer;
31 | }
32 | }
33 | p.menu-label {
34 | font-size: 0.9em;
35 | color: #484848;
36 | letter-spacing: 0.2em;
37 | padding-left: 1rem;
38 | font-weight: bold;
39 | }
40 | .my-playlists {
41 | max-height: 52%;
42 | }
43 | .featured-playlists {
44 | height: 200px;
45 | }
46 | .menu-list {
47 | overflow-y: auto;
48 | overflow-x: hidden;
49 | li {
50 | height: 36px;
51 | border-left: 3px solid transparent;
52 | transition: all 0.2s ease-in-out;
53 | position: relative;
54 | cursor: pointer;
55 |
56 | .tooltiptext {
57 | visibility: hidden;
58 | position: absolute;
59 | top: 5px;
60 | right: 0px;
61 | background-color: rgba(40, 40, 40, 0.7);
62 | border-radius: 5px;
63 | color: white;
64 | padding: 5px;
65 | box-shadow: 1px 1px 2px 2px rgba(4, 4, 4, 0.1);
66 | z-index: 10;
67 | }
68 | .tooltiptext::after {
69 | content: ' ';
70 | position: absolute;
71 | top: 50%;
72 | right: 100%; /* To the left of the tooltip */
73 | margin-top: -5px;
74 | border-width: 5px;
75 | border-style: solid;
76 | border-color: transparent rgba($gray-dark, 0.7) transparent
77 | transparent;
78 | }
79 | &:hover {
80 | border-left: 3px solid #494949;
81 | background: #e9e9e9;
82 | }
83 | &:hover .tooltiptext {
84 | visibility: visible;
85 | }
86 | }
87 | .tooltip.active {
88 | border-left: 3px solid $brand-secondary;
89 | background-color: #e6e6e6;
90 | a {
91 | color: $brand-secondary;
92 | img {
93 | filter: grayscale(0%);
94 | }
95 | }
96 | }
97 | li a {
98 | height: 36px;
99 | overflow: hidden;
100 | padding: 0.6em 0.75em;
101 | border-radius: 0px;
102 | text-overflow: ellipsis;
103 | white-space: nowrap;
104 | letter-spacing: 0.5;
105 | font-size: 13px;
106 | width: 225px;
107 | display: flex;
108 | align-items: center;
109 | img {
110 | width: 25px;
111 | height: 25px;
112 | border-radius: 50px;
113 | margin-right: 10px;
114 | filter: grayscale(75%);
115 | box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.24);
116 | }
117 | .playlist-name {
118 | text-overflow: ellipsis;
119 | overflow: hidden;
120 | }
121 | .fa {
122 | position: absolute;
123 | left: 90%;
124 | font-size: 15px;
125 | }
126 | &:hover {
127 | background: transparent;
128 | }
129 | }
130 | }
131 | }
132 | }
133 |
134 | .burger-menu-playlist {
135 | display: none;
136 | @media screen and (max-width: $break-mobile) {
137 | display: block;
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/src/stylesheets/components/search.scss:
--------------------------------------------------------------------------------
1 | .search-component {
2 | margin-bottom: 52px;
3 | width: $container-large;
4 | background-color: $gray-light;
5 | min-height: calc(100vh - #{$nav-height});
6 | margin: 0 auto;
7 | box-shadow: 0px 0px 6px 1px rgba(99, 99, 99, 0.12);
8 | padding-bottom: $nav-height;
9 | .search-banner {
10 | display: flex;
11 | flex-direction: row;
12 | align-items: center;
13 | justify-content: center;
14 | padding: 20px;
15 | .title {
16 | margin-bottom: 0 !important;
17 | margin-right: 10px;
18 | font-size: 1.6rem;
19 | }
20 | .subtitle {
21 | margin-top: 0 !important;
22 | font-size: 1.4rem;
23 | &:first-letter {
24 | text-transform: capitalize;
25 | }
26 | }
27 | }
28 | .search-data-wrapper {
29 | display: flex;
30 |
31 | flex-direction: row;
32 | h2 {
33 | text-align: center;
34 | font-size: 1.6rem;
35 | font-weight: bold;
36 | padding-bottom: 15px;
37 | padding-top: 10px;
38 | }
39 | .searched-artists {
40 | width: 28.3%;
41 | padding: 10px;
42 | .artist-list {
43 | display: flex;
44 | flex-wrap: wrap;
45 | justify-content: space-around;
46 | .artist-result {
47 | margin-bottom: 15px;
48 | width: 45%;
49 | display: flex;
50 | flex-direction: column;
51 | align-items: center;
52 | img {
53 | height: 100px;
54 | width: 100px;
55 | border-radius: 50%;
56 | margin: 5px;
57 | cursor: pointer;
58 | box-shadow: $box-shadow-primary;
59 | }
60 | p {
61 | text-align: center;
62 | overflow: hidden;
63 | text-overflow: ellipsis;
64 | font-size: 0.9rem;
65 | cursor: pointer;
66 | &:hover {
67 | text-decoration: underline;
68 | }
69 | }
70 | }
71 | }
72 | }
73 | .searched-tracks {
74 | width: 43.3%;
75 | padding-top: 10px;
76 | .track-list {
77 | border-right: 1px solid #cfcfcf;
78 | border-left: 1px solid #cfcfcf;
79 | padding-left: 10px;
80 | padding-right: 10px;
81 | }
82 | }
83 | .searched-playlists {
84 | width: 28.3%;
85 | padding: 10px;
86 | .playlist-list {
87 | display: flex;
88 | flex-wrap: wrap;
89 | justify-content: space-around;
90 | .playlist-result {
91 | margin-bottom: 15px;
92 | width: 33%;
93 | display: flex;
94 | flex-direction: column;
95 | align-items: center;
96 | img {
97 | height: 50px;
98 | width: 50px;
99 | border-radius: 50%;
100 | margin: 5px;
101 | cursor: pointer;
102 | box-shadow: $box-shadow-primary;
103 | }
104 | p {
105 | text-align: center;
106 | overflow: hidden;
107 | text-overflow: ellipsis;
108 | font-size: 0.9rem;
109 | cursor: pointer;
110 | &:hover {
111 | text-decoration: underline;
112 | }
113 | }
114 | }
115 | }
116 | }
117 | }
118 | .time-counter {
119 | left: 50px !important;
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/stylesheets/components/toplists.scss:
--------------------------------------------------------------------------------
1 | .toplists-component {
2 | max-width: $container-large;
3 | background-color: $gray-light;
4 | min-height: 90vh;
5 | margin: 0 auto;
6 | display: flex;
7 | flex-direction: column;
8 | box-shadow: 0px 0px 6px 1px rgba(99, 99, 99, 0.12);
9 | padding: 20px;
10 | padding-bottom: 52px;
11 | h1 {
12 | text-align: center;
13 | font-size: 2rem;
14 | margin-bottom: 20px;
15 | }
16 | .toplists-list {
17 | display: flex;
18 | flex-wrap: wrap;
19 | justify-content: space-around;
20 | width: 100%;
21 | .toplists-item {
22 | position: relative;
23 | display: flex;
24 | justify-content: center;
25 | margin-bottom: 20px;
26 | cursor: pointer;
27 | img {
28 | width: 225px;
29 | height: 225px;
30 | transition: 0.3s all ease;
31 | box-shadow: $box-shadow-primary;
32 | }
33 | &:hover img {
34 | filter: invert(15%);
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/stylesheets/components/track.scss:
--------------------------------------------------------------------------------
1 | .track {
2 | display: flex;
3 | flex-direction: row;
4 | padding-top: 10px;
5 | padding-bottom: 10px;
6 | border-bottom: 1px solid #e0e0e0;
7 | width: 100%;
8 | border-left: 3px solid rgba(255, 107, 66, 0);
9 | padding-left: 3%;
10 | padding-right: 3%;
11 | @media screen and (max-width: $break-mobile) {
12 | padding-bottom: 0px;
13 | }
14 | .img-wrapper {
15 | min-width: 100px;
16 | box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.363);
17 | @media screen and (max-width: $break-mobile) {
18 | width: 60px;
19 | height: 60px;
20 | min-width: 60px;
21 | }
22 | img {
23 | height: 100px;
24 | @media screen and (max-width: $break-mobile) {
25 | height: 60px;
26 | }
27 | }
28 | .img-click-play {
29 | height: 100px;
30 | width: 100px;
31 | position: absolute;
32 | background-color: rgba(0, 0, 0, 0.61);
33 | display: flex;
34 | justify-content: center;
35 | align-items: center;
36 | opacity: 0;
37 | transition: 0.3s all ease;
38 | @media screen and (max-width: $break-mobile) {
39 | height: 60px;
40 | width: 60px;
41 | }
42 | .button {
43 | border-radius: 50px;
44 | height: 40px;
45 | width: 40px;
46 | border: 1px solid white;
47 | background-color: rgba(0, 0, 0, 0.23);
48 | .fa {
49 | color: white;
50 | }
51 | }
52 | }
53 | &:hover .img-click-play {
54 | opacity: 1;
55 | }
56 | }
57 | .track-info {
58 | padding-left: 10px;
59 | letter-spacing: 0.3px;
60 | display: flex;
61 | flex-direction: column;
62 | justify-content: space-between;
63 | width: 100%;
64 | .track-section-higher {
65 | display: flex;
66 | flex-direction: row;
67 | justify-content: space-between;
68 | .track-details {
69 | display: flex;
70 | flex-direction: column;
71 |
72 | .artist-label {
73 | font-size: 11px;
74 | color: $gray-medium;
75 | span {
76 | cursor: pointer;
77 | &:hover {
78 | text-decoration: underline;
79 | }
80 | }
81 | }
82 | .title-label {
83 | font-size: 14px;
84 | cursor: pointer;
85 | &:hover {
86 | text-decoration: underline;
87 | }
88 | }
89 | }
90 | .track-section-higher-right-grp {
91 | display: flex;
92 | flex-direction: row;
93 | align-items: center;
94 | .popularity {
95 | position: relative;
96 | .bg-pop-wrapper {
97 | display: flex;
98 | .bg-pop {
99 | border-right: 2px solid #949494;
100 | height: 10px;
101 | padding-right: 1px;
102 | }
103 | .color-pop {
104 | height: 10px;
105 | padding-right: 1px;
106 | border-right: 2px solid #3f3f3f;
107 | top: 10px;
108 | z-index: 7;
109 | }
110 | }
111 | }
112 | }
113 | }
114 |
115 | .play-btn {
116 | height: 40px;
117 | width: 40px;
118 | border-radius: 50%;
119 | margin-bottom: 15px;
120 | margin-right: 2%;
121 | box-shadow: 0px 3px 1px 0px rgba(0, 0, 0, 0.21);
122 | transition: 0.15s all ease-out;
123 | &:focus {
124 | border-color: #dbdbdb;
125 | }
126 | .fa {
127 | font-size: 14px;
128 | }
129 | }
130 | .track-section-lower {
131 | display: flex;
132 | justify-content: space-around;
133 | position: relative;
134 | .time-counter {
135 | font-size: 11px;
136 | position: absolute;
137 | top: 26px;
138 | left: 50;
139 | }
140 | .time-duration {
141 | font-size: 11px;
142 | position: absolute;
143 | top: 26px;
144 | right: 5;
145 | }
146 | .running-track {
147 | width: 90%;
148 | display: flex;
149 | position: relative;
150 | .played-color {
151 | height: 3px;
152 | background: $brand-secondary;
153 | position: absolute;
154 | z-index: 8;
155 | bottom: 33.5;
156 | }
157 | .track-color {
158 | height: 3px;
159 | background: $gray-medium;
160 | position: absolute;
161 | width: 100%;
162 | bottom: 33.5;
163 | }
164 | }
165 | }
166 | }
167 | input[type='range'] {
168 | -webkit-appearance: none;
169 | width: 100%;
170 | margin-bottom: 15px;
171 | background-color: transparent;
172 | z-index: 8;
173 | }
174 | input[type='range']:focus {
175 | outline: none;
176 | }
177 | input[type='range']::-webkit-slider-runnable-track {
178 | width: 100%;
179 | height: 3px;
180 | cursor: pointer;
181 | //box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
182 | background: transparent;
183 | border-radius: 50px;
184 | border: 0px solid #000101;
185 | }
186 | input[type='range']::-webkit-slider-thumb {
187 | //box-shadow: 0px 0px 0.9px #000000, 0px 0px 0px #0d0d0d;
188 | border: 0px solid #00001e;
189 | height: 15px;
190 | width: 15px;
191 | border-radius: 50px;
192 | background: $gray-lightdark;
193 | cursor: pointer;
194 | -webkit-appearance: none;
195 | margin-top: -5.85px;
196 | }
197 | input[type='range']:focus::-webkit-slider-runnable-track {
198 | background: transparent;
199 | }
200 | input[type='range']::-moz-range-track {
201 | width: 100%;
202 | height: 3px;
203 | cursor: pointer;
204 | //box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
205 | background: transparent;
206 | border-radius: 50px;
207 | border: 0px solid #000101;
208 | }
209 | input[type='range']::-moz-range-thumb {
210 | //box-shadow: 0px 0px 0.9px #000000, 0px 0px 0px #0d0d0d;
211 | border: 0px solid #00001e;
212 | height: 15px;
213 | width: 15px;
214 | border-radius: 50px;
215 | background: $gray-lightdark;
216 | cursor: pointer;
217 | }
218 | input[type='range']::-ms-track {
219 | width: 100%;
220 | height: 3px;
221 | cursor: pointer;
222 | background: transparent;
223 | border-color: transparent;
224 | color: transparent;
225 | }
226 | input[type='range']::-ms-fill-lower {
227 | background: transparent;
228 | border: 0px solid #000101;
229 | border-radius: 50px;
230 | //box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
231 | }
232 | input[type='range']::-ms-fill-upper {
233 | background: transparent;
234 | border: 0px solid #000101;
235 | border-radius: 50px;
236 | //box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
237 | }
238 | input[type='range']::-ms-thumb {
239 | //box-shadow: 0px 0px 0.9px #000000, 0px 0px 0px #0d0d0d;
240 | border: 0px solid #00001e;
241 | height: 15px;
242 | width: 15px;
243 | border-radius: 50px;
244 | background: $gray-lightdark;
245 | cursor: pointer;
246 | height: 3px;
247 | }
248 | input[type='range']:focus::-ms-fill-lower {
249 | background: transparent;
250 | }
251 | input[type='range']:focus::-ms-fill-upper {
252 | background: transparent;
253 | }
254 | }
255 | .track.active-track {
256 | border-left: 3px solid #ff6b42 !important;
257 | }
258 |
--------------------------------------------------------------------------------
/src/stylesheets/components/trackDetail.scss:
--------------------------------------------------------------------------------
1 | $artist-dimension-desktop: 36vh;
2 | $artist-dimension-mobile: 15vh;
3 | .track-detail-component {
4 | max-width: $container-large;
5 | background-color: $gray-light;
6 | min-height: calc(100vh - #{$nav-height});
7 | margin: 0 auto;
8 | display: flex;
9 | flex-direction: column;
10 | box-shadow: 0px 0px 6px 1px rgba(99, 99, 99, 0.12);
11 | padding: 20px 0px;
12 | padding-bottom: 52px;
13 | @media screen and (max-width: $break-mobile) {
14 | font-size: 0.9rem;
15 | padding-top: 0px;
16 | }
17 | .track-header {
18 | width: 100%;
19 | height: 40vh;
20 | display: flex;
21 | flex-direction: row;
22 | background: $brand-primary;
23 | margin-bottom: 5%;
24 | @media screen and (max-width: $break-mobile) {
25 | position: relative;
26 | height: 45vh;
27 | }
28 | .track-art-wrapper {
29 | display: flex;
30 | justify-content: center;
31 | align-self: center;
32 | margin-left: 2vh;
33 | width: $artist-dimension-desktop;
34 | height: $artist-dimension-desktop;
35 | box-shadow: $box-shadow-primary;
36 | @media screen and (max-width: $break-mobile) {
37 | width: $artist-dimension-mobile;
38 | height: $artist-dimension-mobile;
39 | align-self: flex-start;
40 | margin-top: 15px;
41 | }
42 | .track-art {
43 | width: $artist-dimension-desktop;
44 | height: $artist-dimension-desktop;
45 | @media screen and (max-width: $break-mobile) {
46 | width: $artist-dimension-mobile;
47 | height: $artist-dimension-mobile;
48 | }
49 | }
50 | }
51 | .track-info-details {
52 | width: calc(100% - #{$artist-dimension-desktop});
53 | padding-left: 30px;
54 | display: flex;
55 | flex-direction: column;
56 | justify-content: space-around;
57 | @media screen and (max-width: $break-mobile) {
58 | width: calc(100% - #{$artist-dimension-mobile});
59 | justify-content: flex-start;
60 | padding-left: 15px;
61 | }
62 | .track-names {
63 | display: flex;
64 | flex-direction: column;
65 | h1 {
66 | font-size: 2.2rem;
67 | letter-spacing: 1px;
68 | color: white;
69 | @media screen and (max-width: $break-mobile) {
70 | font-size: 1.4rem;
71 | padding-bottom: 10px;
72 | }
73 | }
74 | .track-artists {
75 | margin-top: 10px;
76 | display: flex;
77 | h2 {
78 | font-size: 1.2rem;
79 | letter-spacing: 1px;
80 | color: $gray-medium-light;
81 | line-height: 15px;
82 | margin-left: 10px;
83 | cursor: pointer;
84 | &:first-child {
85 | margin-left: 0px;
86 | }
87 | &:hover {
88 | text-decoration: underline;
89 | }
90 | @media screen and (max-width: $break-mobile) {
91 | font-size: 1rem;
92 | }
93 | }
94 | }
95 | }
96 | .track-character {
97 | margin-bottom: 20px;
98 | p {
99 | font-size: 1.2rem;
100 | color: $gray-medium-light;
101 | @media screen and (max-width: $break-mobile) {
102 | font-size: 1rem;
103 | }
104 | &:first-child {
105 | margin-bottom: 10px;
106 | }
107 | span {
108 | background-color: $brand-secondary;
109 | color: white;
110 | padding: 1px 10px;
111 | border-radius: 50px;
112 | margin: 3px;
113 | box-shadow: $box-shadow-small;
114 | letter-spacing: 1px;
115 | font-size: 1.1rem;
116 | white-space: nowrap;
117 | @media screen and (max-width: $break-mobile) {
118 | font-size: 0.9rem;
119 | }
120 | }
121 | }
122 | }
123 | .track-measurements {
124 | display: flex;
125 | flex-direction: row;
126 | justify-content: space-between;
127 | align-items: center;
128 | padding-right: 20%;
129 | margin-bottom: 20px;
130 | @media screen and (max-width: $break-mobile) {
131 | padding-right: 0;
132 | margin-bottom: 5px;
133 | position: absolute;
134 | bottom: 0;
135 | left: 0;
136 | width: 100%;
137 | overflow-x: hidden;
138 | }
139 | div {
140 | display: flex;
141 | flex-direction: column;
142 | justify-content: center;
143 | align-items: center;
144 | p {
145 | margin-bottom: 10px;
146 | font-size: 0.8rem;
147 | text-transform: uppercase;
148 | color: $gray-medium-light;
149 | @media screen and (max-width: $break-mobile) {
150 | font-size: 0.6rem;
151 | margin-bottom: 0px;
152 | }
153 | }
154 | .pieChart {
155 | .innerText {
156 | text {
157 | font-size: 3.5rem;
158 | }
159 | }
160 | @media screen and (max-width: $break-mobile) {
161 | width: 50px;
162 | }
163 | }
164 | #graph {
165 | stroke-dasharray: 630px;
166 | stroke-dashoffset: 630px;
167 | -webkit-transform-origin: 50% 50%;
168 | transform-origin: 50% 50%;
169 | -webkit-transform: rotate(-90deg);
170 | transform: rotate(-90deg);
171 | }
172 | }
173 | }
174 | }
175 | }
176 | .track-player-view {
177 | .track-player-options {
178 | margin: 0 auto;
179 | display: flex;
180 | flex-direction: row;
181 | width: 45%;
182 | justify-content: space-between;
183 | margin-bottom: 3%;
184 | @media screen and (max-width: $break-mobile) {
185 | width: 100%;
186 | }
187 | .button {
188 | width: 150px;
189 | height: 40px;
190 | font-size: 0.8rem;
191 | background-color: transparent;
192 | text-transform: uppercase;
193 | border: 1px solid black;
194 | letter-spacing: 2px;
195 | border-radius: 0px;
196 | &:hover {
197 | background-color: $gray-light;
198 | color: $gray-lightdark;
199 | }
200 | }
201 | }
202 | }
203 | }
204 |
--------------------------------------------------------------------------------
/src/stylesheets/components/trackMenu.scss:
--------------------------------------------------------------------------------
1 | .track-open-mini-meny {
2 | margin-left: 15px;
3 | display: flex;
4 | cursor: pointer;
5 | padding: 3px;
6 |
7 | i {
8 | font-size: 5px;
9 | padding: 0.5px;
10 | }
11 | }
12 | .track-mini-meny {
13 | width: 140px;
14 | min-width: 0px;
15 | @media screen and (max-width: $break-mobile) {
16 | right: 0;
17 | left: auto;
18 | }
19 | .dropdown-content {
20 | padding: 0px;
21 | position: relative;
22 | border-radius: 0px;
23 | :last-child {
24 | border-bottom: none;
25 | }
26 | .dropdown-item {
27 | cursor: pointer;
28 | padding: 8px;
29 | font-size: 12px;
30 | border-bottom: 1px solid $gray-light;
31 | &:hover {
32 | text-decoration: underline;
33 | }
34 | }
35 | .open-add-track {
36 | cursor: default;
37 | display: flex;
38 | justify-content: space-between;
39 | align-items: center;
40 | &:hover {
41 | text-decoration: none;
42 | }
43 | i.fa {
44 | font-size: 21px;
45 | }
46 | .mini-meny-playlists {
47 | visibility: hidden;
48 | position: absolute;
49 | background: white;
50 | left: 100%;
51 | top: 0;
52 | -webkit-box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1),
53 | 0 0 0 1px rgba(10, 10, 10, 0.1);
54 | box-shadow: 0 2px 3px rgba(10, 10, 10, 0.1),
55 | 0 0 0 1px rgba(10, 10, 10, 0.1);
56 | max-height: 300px;
57 | overflow-y: auto;
58 | @media screen and (max-width: $break-mobile) {
59 | right: 100%;
60 | left: auto;
61 | }
62 | .menu-list {
63 | border-left: 0;
64 | margin: 0;
65 | padding: 0;
66 | width: 110px;
67 | overflow: hidden;
68 | white-space: nowrap;
69 | a {
70 | padding: 8px;
71 | font-size: 12px;
72 | text-overflow: ellipsis;
73 | overflow: hidden;
74 | &:hover {
75 | text-decoration: underline;
76 | background-color: transparent;
77 | }
78 | }
79 | }
80 | }
81 | &:hover .mini-meny-playlists {
82 | visibility: visible;
83 | }
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/stylesheets/components/tracklist.scss:
--------------------------------------------------------------------------------
1 | .tracklist {
2 | margin-left: 25%;
3 | background-color: $gray-light;
4 | padding: 0;
5 | box-shadow: 0px 0px 6px 1px rgba(99, 99, 99, 0.12);
6 | padding-bottom: $nav-height;
7 | min-height: calc(100vh - #{$nav-height});
8 | @media screen and (max-width: $break-mobile) {
9 | margin-left: 0px;
10 | }
11 | .tracklist-tracks {
12 | margin-top: 1.5%;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/stylesheets/components/tracklistBanner.scss:
--------------------------------------------------------------------------------
1 | .tracklist-banner {
2 | display: flex;
3 | justify-content: space-between;
4 | margin-top: 15px;
5 | background-color: $brand-primary;
6 | color: $gray-light;
7 | padding: 1rem;
8 | box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.4);
9 | position: relative;
10 | width: 52vw;
11 | right: 1vw;
12 | transition: 0.3s all;
13 | @media screen and (max-width: $break-mobile) {
14 | width: 100%;
15 | right: 0;
16 | }
17 | .tracklist-banner-info {
18 | display: flex;
19 | flex-direction: column;
20 | justify-content: space-between;
21 | padding: 0.5rem;
22 | width: 100%;
23 | .menu-label {
24 | color: #9a9a9a;
25 | }
26 | .tracklist-name {
27 | font-size: 2.5rem;
28 | color: $gray-light;
29 | @media screen and (max-width: $break-mobile) {
30 | font-size: 1.7rem;
31 | }
32 | }
33 | .tracklist-banner-info-lower {
34 | display: flex;
35 | justify-content: space-between;
36 | align-items: flex-end;
37 | .tracklist-banner-btn-group {
38 | display: flex;
39 | width: 220px;
40 | justify-content: space-between;
41 | margin-right: 5%;
42 | @media screen and (max-width: $break-mobile) {
43 | width: 10%;
44 | }
45 | button {
46 | border: 1px solid $gray-light;
47 | background-color: $brand-primary;
48 | color: $gray-light;
49 | text-transform: uppercase;
50 | font-size: 11px;
51 | width: 100px;
52 | letter-spacing: 2px;
53 | height: 30px;
54 | border-radius: 0px;
55 | @media screen and (max-width: $break-mobile) {
56 | display: none;
57 | }
58 |
59 | &:hover {
60 | background-color: $gray-light;
61 | color: $gray-lightdark;
62 | }
63 | }
64 | }
65 | }
66 | }
67 | .tracklist-img {
68 | height: 200px;
69 | min-width: 200px !important;
70 | width: 200px;
71 | @media screen and (max-width: $break-mobile) {
72 | width: 100px;
73 | height: 100px;
74 | min-width: 100px !important;
75 | }
76 | img {
77 | object-fit: cover;
78 | height: 200px;
79 | box-shadow: 0px 0px 20px 0px rgba(255, 255, 255, 0.14);
80 | @media screen and (max-width: $break-mobile) {
81 | height: 100px;
82 | }
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/stylesheets/components/tracklistBannerScroll.scss:
--------------------------------------------------------------------------------
1 | $top-distance: $nav-height;
2 |
3 | .tracklist-scroll-banner {
4 | height: $nav-height;
5 | position: fixed;
6 | width: 40.2vw;
7 | background-color: rgba(0, 27, 35, 0.95);
8 | z-index: 25;
9 | top: 0px;
10 | display: flex;
11 | flex-direction: row;
12 | align-items: center;
13 | justify-content: space-between;
14 | padding: 5px;
15 | white-space: nowrap;
16 | box-shadow: 0px 0px 6px 1px rgba(0, 0, 0, 0.4);
17 | transition: 0.3s all ease;
18 | @media screen and (max-width: $break-mobile) {
19 | width: 100vw;
20 | }
21 | .tracklist-name {
22 | text-overflow: ellipsis;
23 | overflow: hidden;
24 | font-size: 1.3rem;
25 | color: $gray-light;
26 | margin-bottom: 0;
27 | max-width: 72%;
28 | padding: 1%;
29 | letter-spacing: 1px;
30 | display: flex;
31 | align-items: center;
32 | @media screen and (max-width: $break-mobile) {
33 | font-size: 1.1rem;
34 | max-width: 50%;
35 | }
36 |
37 | div {
38 | cursor: pointer;
39 | }
40 | span {
41 | font-size: 0.7rem;
42 | letter-spacing: 1px;
43 | color: #dddbdb;
44 | padding-left: 5px;
45 | margin-top: 4px;
46 | }
47 | }
48 | .tracklist-scroll-banner-right-grp {
49 | display: flex;
50 | flex-direction: row;
51 | justify-content: space-between;
52 | align-items: center;
53 | width: 200px;
54 | .tracklist-scroll-btn-grp {
55 | display: flex;
56 | flex-direction: row;
57 | justify-content: space-between;
58 | width: 55%;
59 | .button {
60 | border: 1px solid $gray-light;
61 | background-color: transparent;
62 | color: $gray-light;
63 | text-transform: uppercase;
64 | font-size: 11px;
65 | width: 40px;
66 | letter-spacing: 2px;
67 | height: 30px;
68 | border-radius: 50px;
69 | i.fa {
70 | font-size: 11px;
71 | }
72 | i.fa-remove {
73 | font-size: 15px;
74 | padding-bottom: 2px;
75 | padding-left: 1px;
76 | }
77 | &:hover {
78 | background-color: $gray-light;
79 | color: $gray-lightdark;
80 | }
81 | }
82 | }
83 | .tracklist-scroll-img {
84 | img {
85 | height: 40px;
86 | width: 40px;
87 | }
88 | }
89 | }
90 | }
91 | .tracklist-scroll-banner.banner-show {
92 | top: $top-distance;
93 | width: 50.2vw;
94 | transform: translateX(0vw);
95 | @media screen and (max-width: $break-mobile) {
96 | width: 100vw;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/stylesheets/main.scss:
--------------------------------------------------------------------------------
1 | @import 'variables.scss';
2 | @import 'base.scss';
3 | @import 'modals.scss';
4 |
5 | // Components
6 | @import './components/nav';
7 | @import './components/playlists';
8 | @import './components/tracklist';
9 | @import './components/tracklistBanner';
10 | @import './components/tracklistBannerScroll';
11 | @import './components/track';
12 | @import './components/musicbar';
13 | @import './components/extraInfolist';
14 | @import './components/login';
15 | @import './components/search';
16 | @import './components/discover';
17 | @import './components/discoverCategory';
18 | @import './components/musicbarActions';
19 | @import './components/newReleases';
20 | @import './components/toplists';
21 | @import './components/trackMenu';
22 | @import './components/trackDetail';
23 | @import './components/artistDetail';
24 | @import './components/albumDetail';
25 | @import './components/alert';
26 |
--------------------------------------------------------------------------------
/src/stylesheets/modals.scss:
--------------------------------------------------------------------------------
1 | .modal {
2 | .modal-background {
3 | background-color: rgba(10, 10, 10, 0.73);
4 | }
5 | .modal-content {
6 | background-color: $gray-light;
7 | padding: 10px 30px;
8 | width: 440px;
9 | max-height: 400px;
10 | box-shadow: 0px 0px 12px 3px rgba(0, 0, 0, 0.17);
11 | @media screen and (max-width: $break-mobile) {
12 | width: 100vw;
13 | padding: 5px;
14 | }
15 | .title {
16 | text-align: center;
17 | margin-bottom: 10px;
18 | }
19 | ul {
20 | li {
21 | display: block;
22 | border-bottom: 1px solid #d2d2d2;
23 | padding: 10px 0px;
24 | letter-spacing: 1px;
25 | font-size: 0.9rem;
26 | display: flex;
27 | flex-direction: row;
28 | justify-content: space-between;
29 | align-items: center;
30 | &:last-child {
31 | border-bottom: 0;
32 | }
33 | }
34 | }
35 | .field {
36 | margin-bottom: 10px;
37 | input {
38 | border-radius: 0px;
39 | box-shadow: none;
40 | height: 2.7em;
41 | background-color: #fbfbfb;
42 | &:active {
43 | border-color: $brand-secondary;
44 | }
45 | &:focus {
46 | border-color: $brand-secondary;
47 | }
48 | }
49 | textarea {
50 | border-radius: 0px;
51 | box-shadow: none;
52 | background-color: #fbfbfb;
53 | &:active {
54 | border-color: $brand-secondary;
55 | }
56 | &:focus {
57 | border-color: $brand-secondary;
58 | }
59 | }
60 | .button {
61 | border: 1px solid $gray-lightdark;
62 | background-color: white;
63 | color: $gray-lightdark;
64 | text-transform: uppercase;
65 | font-size: 11px;
66 | width: 100px;
67 | letter-spacing: 2px;
68 | height: 30px;
69 | border-radius: 0px;
70 | }
71 | .button.is-primary {
72 | background-color: $brand-secondary;
73 | color: $gray-light;
74 | border: 1px solid transparent;
75 | &:hover {
76 | border: 1px solid $gray-lightdark;
77 | }
78 | }
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/stylesheets/variables.scss:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Open+Sans:300');
2 |
3 | //Colors
4 | $brand-primary: #001b23; //#270000; //#313131;
5 | $brand-secondary: #ff6b42; //#ff4d1c;
6 | $brand-third: #982f2f;
7 |
8 | //Gray scale
9 | $gray-light: #efefef;
10 | $gray-medium-light: #afafaf;
11 | $gray-medium: #676767;
12 | $gray-lightdark: #404040;
13 | $gray-dark: #282828;
14 |
15 | //Body
16 | $body-background-color: rgba(0, 27, 35, 0.149); //#dee4e1;
17 | $body-default-color: #333333;
18 | $body-default-font-familty: 'Open Sans', sans-serif;
19 |
20 | //Nav
21 | $nav-background-color: $brand-primary;
22 | $nav-font-color: #ffffff;
23 | $nav-height: 52px;
24 |
25 | // Containers
26 | $container-large: 1300px;
27 |
28 | // Box shadows
29 | $box-shadow-primary: 0px 2px 6px 0px rgba(0, 0, 0, 0.363);
30 | $box-shadow-large: 0px 2px 20px 0px rgba(0, 0, 0, 0.645);
31 | $box-shadow-small: 0px 2px 4px 0px rgba(0, 0, 0, 0.23);
32 |
33 | // Media queries
34 | $break-mobile: 850px;
35 |
--------------------------------------------------------------------------------
/webpack.common.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const path = require('path')
3 |
4 | const autoprefixer = require('autoprefixer')
5 |
6 | module.exports = {
7 | module: {
8 | rules: [
9 | {
10 | loader: 'babel-loader',
11 | test: /\.js$/,
12 | exclude: /node_modules/
13 | },
14 | {
15 | test: /\.scss$/,
16 | use: [
17 | {
18 | loader: 'style-loader' // creates style nodes from JS strings
19 | },
20 | {
21 | loader: 'css-loader' // translates CSS into CommonJS
22 | },
23 | {
24 | loader: 'postcss-loader',
25 | options: {
26 | plugins: function() {
27 | return [autoprefixer]
28 | }
29 | }
30 | },
31 | {
32 | loader: 'sass-loader' // compiles Sass to CSS
33 | }
34 | ]
35 | },
36 | {
37 | test: /\.css$/,
38 | exclude: /(s-alert-default.css|s-alert-css-effects|normalize.css)/,
39 | loader:
40 | 'style-loader!css-loader?sourceMap&modules&importLoaders=1&localIdentName=[name]__[local]__[hash:base64:5]'
41 | },
42 | {
43 | test: /\.css$/,
44 | include: /(s-alert-default.css|s-alert-css-effects|normalize.css)/,
45 | loader: 'style-loader!css-loader?sourceMap'
46 | },
47 | {
48 | test: /\.(jpg|png|svg)$/,
49 | use: {
50 | loader: 'url-loader',
51 | options: {
52 | limit: 25000
53 | }
54 | }
55 | },
56 | {
57 | test: /\.(woff|woff2|eot|ttf|otf)$/,
58 | use: ['file-loader']
59 | },
60 | {
61 | test: /\.json$/,
62 | loader: 'json-loader'
63 | }
64 | ]
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/webpack.dev.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const path = require('path')
3 |
4 | const merge = require('webpack-merge')
5 | const common = require('./webpack.common.js')
6 |
7 | module.exports = merge(common, {
8 | entry: ['babel-polyfill', './src/index.js'],
9 | output: {
10 | path: path.join(__dirname, 'dist'),
11 | filename: 'client.js',
12 | publicPath: '/'
13 | },
14 | resolve: {
15 | extensions: ['.jsx', '.json', '.js']
16 | },
17 | devtool: 'inline-source-map'
18 | })
19 |
--------------------------------------------------------------------------------
/webpack.devserver.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const path = require('path')
3 | const webpackNodeExternals = require('webpack-node-externals')
4 |
5 | const merge = require('webpack-merge')
6 | const common = require('./webpack.common.js')
7 |
8 | module.exports = merge(common, {
9 | target: 'node',
10 | entry: ['babel-polyfill', './server.js'],
11 | output: {
12 | path: path.join(__dirname, 'dist'),
13 | filename: 'server.js',
14 | publicPath: '/'
15 | },
16 | externals: [webpackNodeExternals()],
17 | resolve: {
18 | extensions: ['.jsx', '.json', '.js']
19 | }
20 | })
21 |
--------------------------------------------------------------------------------
/webpack.prod.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const path = require('path')
3 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
4 |
5 | const merge = require('webpack-merge')
6 | const common = require('./webpack.common.js')
7 |
8 | module.exports = merge(common, {
9 | entry: ['babel-polyfill', './src/index.js'],
10 | output: {
11 | path: path.join(__dirname, 'dist'),
12 | filename: 'client.js',
13 | publicPath: '/'
14 | },
15 | resolve: {
16 | extensions: ['.jsx', '.json', '.js']
17 | },
18 | plugins: [
19 | new UglifyJSPlugin(),
20 | new webpack.DefinePlugin({
21 | 'process.env.NODE_ENV': JSON.stringify('production')
22 | })
23 | ]
24 | })
25 |
--------------------------------------------------------------------------------
/webpack.prodserver.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const path = require('path')
3 | const webpackNodeExternals = require('webpack-node-externals')
4 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
5 |
6 | const merge = require('webpack-merge')
7 | const common = require('./webpack.common.js')
8 |
9 | module.exports = merge(common, {
10 | target: 'node',
11 | entry: ['babel-polyfill', './server.js'],
12 | output: {
13 | path: path.join(__dirname, 'dist'),
14 | filename: 'server.js',
15 | publicPath: '/'
16 | },
17 | externals: [webpackNodeExternals()],
18 | resolve: {
19 | extensions: ['.jsx', '.json', '.js']
20 | },
21 | plugins: [
22 | new UglifyJSPlugin(),
23 | new webpack.DefinePlugin({
24 | 'process.env.NODE_ENV': JSON.stringify('production')
25 | })
26 | ]
27 | })
28 |
--------------------------------------------------------------------------------