Commit bbc82aee authored by Genar Trias Ortiz's avatar Genar Trias Ortiz 🎉

several changes

parent b5bac6bf
Pipeline #57148056 passed with stages
in 6 minutes and 8 seconds
......@@ -13,6 +13,29 @@ import * as types from '../../constants/ActionTypes'
const PLAYER_RETRIES = 5
const getBuffered = (audioRef): number => {
const { current } = audioRef
if (!current) {
return 0
}
const { duration, buffered } = current
let result = 0
for (let i = 0; i < current.buffered.length; i++) {
if (duration > 0) {
result = (
buffered.end(
buffered.length - 1 - i
) / duration
) * 100
}
}
return result
}
type Props = {
queue: any,
player: {
......@@ -127,14 +150,16 @@ class Player extends React.Component<Props, State> {
// Getting desired volume
const volume = this.state.volume ? this.state.volume : this.props.player.volume
const duration = this.playerRef.current ? this.playerRef.current.duration : 0
return (
<div className='player-container'>
<ProgressBar
dispatch={this.props.dispatch}
total={this.playerRef.current ? this.playerRef.current.duration : 0}
total={duration}
current={this.state.currentTime}
onChange={this.setCurrentTime}
buffered={getBuffered(this.playerRef)}
/>
<div className='player-contents'>
<div className='media-thumb'>
......
import * as React from 'react'
import { Dispatch } from 'redux'
import Slider from 'rc-slider'
import Range from 'rc-slider'
import 'rc-slider/assets/index.css';
import { getDurationStr } from '../../utils/timeFormatter'
......@@ -9,20 +9,23 @@ type Props = {
total: number,
dispatch: Dispatch,
onChange: (value: string) => any,
current: number
current: number,
buffered: number
}
const ProgressBar = (props: Props) => {
const step = 100 / props.total
return (
<div
className='progress'
>
<Slider
<Range
className='bar'
min={0}
max={props.total}
step={ 100 / props.total }
type='range'
step={step}
count={1}
value={ props.current }
onChange={ props.onChange }
/>
......
......@@ -8,6 +8,11 @@ type Props = {
field: any
}
export const TYPES = {
title: 'title',
checkbox: 'checkbox'
}
const FormikToggle = ({
field,
form: {touched, errors},
......@@ -27,7 +32,7 @@ const FormikToggle = ({
const FormField = (props: Props) => {
const { field } = props
if (field.type === 'checkbox') {
if (field.type === TYPES.checkbox) {
return (
<div className='toggle-control'>
<Field
......@@ -40,7 +45,7 @@ const FormField = (props: Props) => {
return (
<Field
className={`${ field.type === 'checkbox' ? 'form-check': 'form-control'}`}
className={`${ field.type === TYPES.checkbox ? 'form-check': 'form-control'}`}
name={field.name}
type={field.type}
/>
......
......@@ -21,6 +21,10 @@ class Settings extends React.Component<Props, State> {
this.props.dispatch({type: types.DELETE_SETTINGS})
}
addProvider = (form: any): any => {
this.props.dispatch({type: types.ADD_PROVIDER})
}
render() {
const settingsForm = this.props.settings.settingsForm
......@@ -32,6 +36,9 @@ class Settings extends React.Component<Props, State> {
dispatch={this.props.dispatch}
/>
<div className='btn-group'>
<button className='with-bg' onClick={this.addProvider}>
<Translate value="buttons.addProvider" />
</button>
<button className='with-bg btn btn-danger' onClick={this.deleteCollection}>
<Translate value="labels.deleteCollection" />
</button>
......
......@@ -3,8 +3,8 @@ import { Formik, Form } from 'formik'
import { Dispatch } from 'redux'
import { Translate } from 'react-redux-i18n'
import FormField from './FormField'
import { SAVE_SETTINGS } from '../../constants/ActionTypes'
import FormField, { TYPES } from './FormField'
import * as types from '../../constants/ActionTypes'
type Props = {
settings: any,
......@@ -14,17 +14,20 @@ type Props = {
const SettingsForm = (props: Props) => {
const saveSettings = (form: any): any => {
props.dispatch({type: SAVE_SETTINGS, settingsPayload: form})
props.dispatch({type: types.SAVE_SETTINGS, settingsPayload: form})
}
// Convert schema object to form elements
const populateFromSchema = (schema) => {
console.log(props.schema)
const { fields } = props.schema
const populatedFields = fields.map((field, index) => {
if (field.type === 'title') {
if (field.type === TYPES.title) {
return <h2 key={index}><Translate value={field.title} /></h2>
}
return (
<div
key={field.name}
......
......@@ -64,6 +64,7 @@ export const RECEIVE_SETTINGS_FINISHED = 'RECEIVE_SETTINGS_FINISHED'
export const GET_SETTINGS_REJECTED = 'GET_SETTINGS_REJECTED'
export const REMOVE_FROM_SETTINGS_REJECTED = 'REMOVE_FROM_SETTINGS_REJECTED'
export const DELETE_SETTINGS = 'DELETE_SETTINGS'
export const ADD_PROVIDER = 'ADD_PROVIDER'
// Notifications
export const SEND_NOTIFICATION = 'SEND_NOTIFICATION'
......
......@@ -28,5 +28,8 @@
"search": {
"finished": "Search finished!"
}
},
"buttons": {
"addProvider": "Set up new provider"
}
}
import reducer from './settings'
import {
RECEIVE_SETTINGS,
SETTINGS_SAVED_SUCCESSFULLY
} from '../constants/ActionTypes'
import * as types from '../constants/ActionTypes'
import { defaultState } from './settings'
......@@ -19,7 +16,7 @@ describe('settings reducer', () => {
baseUrl: 'http://localhost'
}
}
expect(reducer(undefined, {type: RECEIVE_SETTINGS, settings}))
expect(reducer(undefined, {type: types.RECEIVE_SETTINGS, settings}))
.toEqual(
{
...defaultState,
......@@ -48,7 +45,7 @@ describe('settings reducer', () => {
}
}
}
expect(reducer(undefined, {type: SETTINGS_SAVED_SUCCESSFULLY, settings}))
expect(reducer(undefined, {type: types.SETTINGS_SAVED_SUCCESSFULLY, settings}))
.toEqual(
{
...defaultState,
......@@ -58,4 +55,13 @@ describe('settings reducer', () => {
}
)
})
it('should handle ADD_PROVIDER', () => {
expect(reducer(undefined, {type: types.ADD_PROVIDER}))
.toEqual(
{
...defaultState
}
)
})
})
import {
RECEIVE_SETTINGS,
SETTINGS_SAVED_SUCCESSFULLY
} from '../constants/ActionTypes'
import * as types from '../constants/ActionTypes'
import { ISettings } from '../interfaces/ISettings'
import SettingsBuilder from '../services/settings/SettingsBuilder'
......@@ -19,21 +16,24 @@ export const defaultState = {
saving: false,
settingsForm: settingsBuilder.getFormSchema(),
settings: {
providers: {
itunes: {
providers: [
{
key: 'itunes',
enabled: false
},
mstream: {
{
key: 'mstream',
enabled: false,
baseUrl: '',
},
subsonic: {
{
key: 'subsonic',
enabled: false,
baseUrl: '',
user: '',
password: ''
}
},
],
app: {
spectrum: {
enabled: true
......@@ -44,8 +44,8 @@ export const defaultState = {
export default (state: State = defaultState, action: any = {}) => {
switch (action.type) {
case RECEIVE_SETTINGS:
case SETTINGS_SAVED_SUCCESSFULLY: {
case types.RECEIVE_SETTINGS:
case types.SETTINGS_SAVED_SUCCESSFULLY: {
return {...state, settings: action.settings}
}
......
import SettingsBuilder from './SettingsBuilder'
describe('SettingsBuilder', () => {
it('should generate schema', () => {
const settingsBuilder = new SettingsBuilder()
expect(settingsBuilder.getFormSchema()).toBeDefined()
})
})
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment