implement full load of videos and startdata

modify api where necessary
This commit is contained in:
2021-02-23 16:01:29 +00:00
parent 2967aee16d
commit f2b5fb6587
69 changed files with 14016 additions and 21001 deletions

View File

@ -38,7 +38,7 @@ class ActorOverviewPage extends React.Component<props, state> {
<Button title='Add Actor' onClick={(): void => this.setState({NActorPopupVisible: true})}/>
</SideBar>
<div className={style.container}>
{this.state.actors.map((el) => (<ActorTile key={el.actor_id} actor={el}/>))}
{this.state.actors.map((el) => (<ActorTile key={el.ActorId} actor={el}/>))}
</div>
{this.state.NActorPopupVisible ?
<NewActorPopup onHide={(): void => {

View File

@ -10,13 +10,13 @@ describe('<ActorPage/>', function () {
it('fetch infos', function () {
callAPIMock({
videos: [{
movie_id: 0,
movie_name: 'test'
}], info: {
thumbnail: '',
name: '',
actor_id: 0
Videos: [{
MovieId: 0,
MovieName: 'test'
}], Info: {
Thumbnail: '',
Name: '',
ActorId: 0
}
});

View File

@ -31,13 +31,13 @@ export class ActorPage extends React.Component<props, state> {
constructor(props: props) {
super(props);
this.state = {data: [], actor: {actor_id: 0, name: '', thumbnail: ''}};
this.state = {data: [], actor: {ActorId: 0, Name: '', Thumbnail: ''}};
}
render(): JSX.Element {
return (
<>
<PageTitle title={this.state.actor.name} subtitle={this.state.data ? this.state.data.length + ' videos' : null}>
<PageTitle title={this.state.actor.Name} subtitle={this.state.data ? this.state.data.length + ' videos' : null}>
<span className={style.overviewbutton}>
<Link to='/actors'>
<Button onClick={(): void => {}} title='Go to Actor overview'/>
@ -68,11 +68,11 @@ export class ActorPage extends React.Component<props, state> {
getActorInfo(): void {
callAPI(APINode.Actor, {
action: 'getActorInfo',
actorid: this.props.match.params.id
ActorId: parseInt(this.props.match.params.id)
}, (result: ActorTypes.videofetchresult) => {
this.setState({
data: result.videos ? result.videos : [],
actor: result.info
data: result.Videos ? result.Videos : [],
actor: result.Info
});
});
}

View File

@ -103,8 +103,8 @@ export class CategoryView extends React.Component<CategoryViewProps, CategoryVie
private deleteTag(force: boolean): void {
callAPI<GeneralSuccess>(APINode.Tags, {
action: 'deleteTag',
tagId: parseInt(this.props.match.params.id),
force: force
TagId: parseInt(this.props.match.params.id),
Force: force
}, result => {
console.log(result.result);
if (result.result === 'success') {

View File

@ -54,8 +54,8 @@ class TagView extends React.Component<props, TagViewState> {
<div className={videocontainerstyle.maincontent}>
{this.state.loadedtags ?
this.state.loadedtags.map((m) => (
<Link to={'/categories/' + m.tag_id} key={m.tag_id}>
<TagPreview name={m.tag_name}/></Link>
<Link to={'/categories/' + m.TagId} key={m.TagId}>
<TagPreview name={m.TagName}/></Link>
)) :
'loading'}
</div>

View File

@ -10,17 +10,12 @@ import {Route, Switch, withRouter} from 'react-router-dom';
import {RouteComponentProps} from 'react-router';
import SearchHandling from './SearchHandling';
import {VideoTypes} from '../../types/ApiTypes';
import {DefaultTags} from "../../types/GeneralTypes";
interface props extends RouteComponentProps {}
interface state {
sideinfo: {
videonr: number,
fullhdvideonr: number,
hdvideonr: number,
sdvideonr: number,
tagnr: number
},
sideinfo: VideoTypes.startDataType
subtitle: string,
data: VideoTypes.VideoUnloadedType[],
selectionnr: number
@ -38,11 +33,12 @@ export class HomePage extends React.Component<props, state> {
this.state = {
sideinfo: {
videonr: 0,
fullhdvideonr: 0,
hdvideonr: 0,
sdvideonr: 0,
tagnr: 0
VideoNr: 0,
FullHdNr: 0,
HDNr: 0,
SDNr: 0,
DifferentTags: 0,
Tagged: 0,
},
subtitle: 'All Videos',
data: [],
@ -52,7 +48,7 @@ export class HomePage extends React.Component<props, state> {
componentDidMount(): void {
// initial get of all videos
this.fetchVideoData('All');
this.fetchVideoData(DefaultTags.all.TagId);
this.fetchStartData();
}
@ -62,7 +58,7 @@ export class HomePage extends React.Component<props, state> {
*
* @param tag tag to fetch videos
*/
fetchVideoData(tag: string): void {
fetchVideoData(tag: number): void {
callAPI(APINode.Video, {action: 'getMovies', tag: tag}, (result: VideoTypes.VideoUnloadedType[]) => {
this.setState({
data: []
@ -70,7 +66,6 @@ export class HomePage extends React.Component<props, state> {
this.setState({
data: result,
selectionnr: result.length,
subtitle: `${tag} Videos`
});
});
}
@ -80,15 +75,7 @@ export class HomePage extends React.Component<props, state> {
*/
fetchStartData(): void {
callAPI(APINode.Video, {action: 'getStartData'}, (result: VideoTypes.startDataType) => {
this.setState({
sideinfo: {
videonr: result['total'],
fullhdvideonr: result['fullhd'],
hdvideonr: result['hd'],
sdvideonr: result['sd'],
tagnr: result['tags']
}
});
this.setState({sideinfo: result});
});
}
@ -119,17 +106,30 @@ export class HomePage extends React.Component<props, state> {
<SideBar>
<SideBarTitle>Infos:</SideBarTitle>
<Line/>
<SideBarItem><b>{this.state.sideinfo.videonr}</b> Videos Total!</SideBarItem>
<SideBarItem><b>{this.state.sideinfo.fullhdvideonr}</b> FULL-HD Videos!</SideBarItem>
<SideBarItem><b>{this.state.sideinfo.hdvideonr}</b> HD Videos!</SideBarItem>
<SideBarItem><b>{this.state.sideinfo.sdvideonr}</b> SD Videos!</SideBarItem>
<SideBarItem><b>{this.state.sideinfo.tagnr}</b> different Tags!</SideBarItem>
<SideBarItem><b>{this.state.sideinfo.VideoNr}</b> Videos Total!</SideBarItem>
<SideBarItem><b>{this.state.sideinfo.FullHdNr}</b> FULL-HD Videos!</SideBarItem>
<SideBarItem><b>{this.state.sideinfo.HDNr}</b> HD Videos!</SideBarItem>
<SideBarItem><b>{this.state.sideinfo.SDNr}</b> SD Videos!</SideBarItem>
<SideBarItem><b>{this.state.sideinfo.DifferentTags}</b> different Tags!</SideBarItem>
<Line/>
<SideBarTitle>Default Tags:</SideBarTitle>
<Tag tagInfo={{tag_name: 'All', tag_id: -1}} onclick={(): void => this.fetchVideoData('All')}/>
<Tag tagInfo={{tag_name: 'FullHd', tag_id: -1}} onclick={(): void => this.fetchVideoData('FullHd')}/>
<Tag tagInfo={{tag_name: 'LowQuality', tag_id: -1}} onclick={(): void => this.fetchVideoData('LowQuality')}/>
<Tag tagInfo={{tag_name: 'HD', tag_id: -1}} onclick={(): void => this.fetchVideoData('HD')}/>
<Tag tagInfo={{TagName: 'All', TagId: DefaultTags.all.TagId}} onclick={(): void => {
this.fetchVideoData(DefaultTags.all.TagId);
this.setState({subtitle: `All Videos`});
}}/>
<Tag tagInfo={{TagName: 'Full Hd', TagId: DefaultTags.fullhd.TagId}} onclick={(): void => {
this.fetchVideoData(DefaultTags.fullhd.TagId);
this.setState({subtitle: `Full Hd Videos`});
}}/>
<Tag tagInfo={{TagName: 'Low Quality', TagId: DefaultTags.lowq.TagId}}
onclick={(): void => {
this.fetchVideoData(DefaultTags.lowq.TagId);
this.setState({subtitle: `Low Quality Videos`});
}}/>
<Tag tagInfo={{TagName: 'HD', TagId: DefaultTags.hd.TagId}} onclick={(): void => {
this.fetchVideoData(DefaultTags.hd.TagId);
this.setState({subtitle: `HD Videos`});
}}/>
</SideBar>
{this.state.data.length !== 0 ?
<VideoContainer

View File

@ -190,15 +190,15 @@ describe('<Player/>', function () {
const wrapper = instance();
global.callAPIMock({result: 'success'});
wrapper.setState({suggesttag: [{tag_name: 'test', tag_id: 1}]}, () => {
wrapper.setState({suggesttag: [{TagName: 'test', TagId: 1}]}, () => {
// mock funtion should have not been called
expect(callAPI).toBeCalledTimes(0);
wrapper.find('Tag').findWhere(p => p.props().tagInfo.tag_name === 'test').dive().simulate('click');
wrapper.find('Tag').findWhere(p => p.props().tagInfo.TagName === 'test').dive().simulate('click');
// mock function should have been called once
expect(callAPI).toBeCalledTimes(1);
// expect tag added to video tags
expect(wrapper.state().tags).toMatchObject([{tag_name: 'test'}]);
expect(wrapper.state().tags).toMatchObject([{TagName: 'test'}]);
// expect tag to be removed from tag suggestions
expect(wrapper.state().suggesttag).toHaveLength(0);
});

View File

@ -20,6 +20,7 @@ import {ActorType, TagType} from '../../types/VideoTypes';
import PlyrJS from 'plyr';
import {Button} from '../../elements/GPElements/Button';
import {VideoTypes} from '../../types/ApiTypes';
import GlobalInfos from "../../utils/GlobalInfos";
interface myprops extends RouteComponentProps<{ id: string }> {}
@ -131,16 +132,16 @@ export class Player extends React.Component<myprops, mystate> {
<Line/>
<SideBarTitle>Tags:</SideBarTitle>
{this.state.tags.map((m: TagType) => (
<Tag key={m.tag_id} tagInfo={m}/>
<Tag key={m.TagId} tagInfo={m}/>
))}
<Line/>
<SideBarTitle>Tag Quickadd:</SideBarTitle>
{this.state.suggesttag.map((m: TagType) => (
<Tag
tagInfo={m}
key={m.tag_name}
key={m.TagName}
onclick={(): void => {
this.quickAddTag(m.tag_id, m.tag_name);
this.quickAddTag(m.TagId, m.TagName);
}}/>
))}
</SideBar>
@ -155,7 +156,7 @@ export class Player extends React.Component<myprops, mystate> {
<div className={style.actorcontainer}>
{this.state.actors ?
this.state.actors.map((actr: ActorType) => (
<ActorTile key={actr.actor_id} actor={actr}/>
<ActorTile key={actr.ActorId} actor={actr}/>
)) : <></>
}
<div className={style.actorAddTile} onClick={(): void => {
@ -207,8 +208,8 @@ export class Player extends React.Component<myprops, mystate> {
quickAddTag(tagId: number, tagName: string): void {
callAPI(APINode.Tags, {
action: 'addTag',
id: tagId,
movieid: this.props.match.params.id
TagId: tagId,
MovieId: parseInt(this.props.match.params.id)
}, (result: GeneralSuccess) => {
if (result.result !== 'success') {
console.error('error occured while writing to db -- todo error handling');
@ -216,7 +217,7 @@ export class Player extends React.Component<myprops, mystate> {
} else {
// check if tag has already been added
const tagIndex = this.state.tags.map(function (e: TagType) {
return e.tag_name;
return e.TagName;
}).indexOf(tagName);
// only add tag if it isn't already there
@ -224,7 +225,7 @@ export class Player extends React.Component<myprops, mystate> {
// update tags if successful
let array = [...this.state.suggesttag]; // make a separate copy of the array (because of setState)
const quickaddindex = this.state.suggesttag.map(function (e: TagType) {
return e.tag_id;
return e.TagId;
}).indexOf(tagId);
// check if tag is available in quickadds
@ -232,12 +233,12 @@ export class Player extends React.Component<myprops, mystate> {
array.splice(quickaddindex, 1);
this.setState({
tags: [...this.state.tags, {tag_name: tagName, tag_id: tagId}],
tags: [...this.state.tags, {TagName: tagName, TagId: tagId}],
suggesttag: array
});
} else {
this.setState({
tags: [...this.state.tags, {tag_name: tagName, tag_id: tagId}]
tags: [...this.state.tags, {TagName: tagName, TagId: tagId}]
});
}
}
@ -249,27 +250,28 @@ export class Player extends React.Component<myprops, mystate> {
* fetch all the required infos of a video from backend
*/
fetchMovieData(): void {
callAPI(APINode.Video, {action: 'loadVideo', movieid: this.props.match.params.id}, (result: VideoTypes.loadVideoType) => {
callAPI(APINode.Video, {action: 'loadVideo', MovieId: parseInt(this.props.match.params.id)}, (result: VideoTypes.loadVideoType) => {
console.log(result)
this.setState({
sources: {
type: 'video',
sources: [
{
src: getBackendDomain() + result.movie_url,
src: getBackendDomain() + GlobalInfos.getVideoPath() + result.MovieUrl,
type: 'video/mp4',
size: 1080
}
],
poster: result.thumbnail
poster: result.Poster
},
movie_id: result.movie_id,
movie_name: result.movie_name,
likes: result.likes,
quality: result.quality,
length: result.length,
tags: result.tags,
suggesttag: result.suggesttag,
actors: result.actors
movie_id: result.MovieId,
movie_name: result.MovieName,
likes: result.Likes,
quality: result.Quality,
length: result.Length,
tags: result.Tags,
suggesttag: result.SuggestedTag,
actors: result.Actors
});
});
}
@ -279,7 +281,7 @@ export class Player extends React.Component<myprops, mystate> {
* click handler for the like btn
*/
likebtn(): void {
callAPI(APINode.Video, {action: 'addLike', movieid: this.props.match.params.id}, (result: GeneralSuccess) => {
callAPI(APINode.Video, {action: 'addLike', MovieId: parseInt(this.props.match.params.id)}, (result: GeneralSuccess) => {
if (result.result === 'success') {
// likes +1 --> avoid reload of all data
this.setState({likes: this.state.likes + 1});
@ -302,7 +304,7 @@ export class Player extends React.Component<myprops, mystate> {
* delete the current video and return to last page
*/
deleteVideo(): void {
callAPI(APINode.Video, {action: 'deleteVideo', movieid: this.props.match.params.id}, (result: GeneralSuccess) => {
callAPI(APINode.Video, {action: 'deleteVideo', MovieId: parseInt(this.props.match.params.id)}, (result: GeneralSuccess) => {
if (result.result === 'success') {
// return to last element if successful
this.props.history.goBack();

View File

@ -55,7 +55,7 @@ describe('<RandomPage/>', function () {
shallow(<RandomPage/>);
callAPIMock({rows: [], tags: []});
callAPIMock({Videos: [], Tags: []});
// trigger the keypress event
events.keyup({key: 's'});

View File

@ -15,8 +15,8 @@ interface state {
}
interface GetRandomMoviesType {
rows: VideoTypes.VideoUnloadedType[];
tags: TagType[];
Videos: VideoTypes.VideoUnloadedType[];
Tags: TagType[];
}
/**
@ -53,7 +53,7 @@ class RandomPage extends React.Component<{}, state> {
<SideBar>
<SideBarTitle>Visible Tags:</SideBarTitle>
{this.state.tags.map((m) => (
<Tag key={m.tag_id} tagInfo={m}/>
<Tag key={m.TagId} tagInfo={m}/>
))}
</SideBar>
@ -84,10 +84,11 @@ class RandomPage extends React.Component<{}, state> {
*/
loadShuffledvideos(nr: number): void {
callAPI<GetRandomMoviesType>(APINode.Video, {action: 'getRandomMovies', number: nr}, result => {
console.log(result)
this.setState({videos: []}); // needed to trigger rerender of main videoview
this.setState({
videos: result.rows,
tags: result.tags
videos: result.Videos,
tags: result.Tags
});
});
}

View File

@ -80,48 +80,48 @@ describe('<GeneralSettings/>', function () {
it('test videopath change event', function () {
const wrapper = shallow(<GeneralSettings/>);
expect(wrapper.state().videopath).not.toBe('test');
expect(wrapper.state().generalSettings.VideoPath).not.toBe('test');
const event = {target: {name: 'pollName', value: 'test'}};
wrapper.find('[data-testid=\'videpathform\']').find('FormControl').simulate('change', event);
expect(wrapper.state().videopath).toBe('test');
expect(wrapper.state().generalSettings.VideoPath).toBe('test');
});
it('test tvshowpath change event', function () {
const wrapper = shallow(<GeneralSettings/>);
const event = {target: {name: 'pollName', value: 'test'}};
expect(wrapper.state().tvshowpath).not.toBe('test');
expect(wrapper.state().generalSettings.EpisodePath).not.toBe('test');
wrapper.find('[data-testid=\'tvshowpath\']').find('FormControl').simulate('change', event);
expect(wrapper.state().tvshowpath).toBe('test');
expect(wrapper.state().generalSettings.EpisodePath).toBe('test');
});
it('test mediacentername-form change event', function () {
const wrapper = shallow(<GeneralSettings/>);
const event = {target: {name: 'pollName', value: 'test'}};
expect(wrapper.state().mediacentername).not.toBe('test');
expect(wrapper.state().generalSettings.MediacenterName).not.toBe('test');
wrapper.find('[data-testid=\'nameform\']').find('FormControl').simulate('change', event);
expect(wrapper.state().mediacentername).toBe('test');
expect(wrapper.state().generalSettings.MediacenterName).toBe('test');
});
it('test password-form change event', function () {
const wrapper = shallow(<GeneralSettings/>);
wrapper.setState({passwordsupport: true});
wrapper.setState({generalSettings : {PasswordEnabled: true}});
const event = {target: {name: 'pollName', value: 'test'}};
expect(wrapper.state().password).not.toBe('test');
expect(wrapper.state().generalSettings.Password).not.toBe('test');
wrapper.find('[data-testid=\'passwordfield\']').find('FormControl').simulate('change', event);
expect(wrapper.state().password).toBe('test');
expect(wrapper.state().generalSettings.Password).toBe('test');
});
it('test tmdbsupport change event', function () {
const wrapper = shallow(<GeneralSettings/>);
wrapper.setState({tmdbsupport: true});
wrapper.setState({generalSettings : {TMDBGrabbing: true}});
expect(wrapper.state().tmdbsupport).toBe(true);
expect(wrapper.state().generalSettings.TMDBGrabbing).toBe(true);
wrapper.find('[data-testid=\'tmdb-switch\']').simulate('change');
expect(wrapper.state().tmdbsupport).toBe(false);
expect(wrapper.state().generalSettings.TMDBGrabbing).toBe(false);
});
it('test insertion of 4 infoheaderitems', function () {

View File

@ -11,23 +11,13 @@ import {SettingsTypes} from '../../types/ApiTypes';
import {GeneralSuccess} from '../../types/GeneralTypes';
interface state {
passwordsupport: boolean,
tmdbsupport: boolean,
customapi: boolean,
videopath: string,
tvshowpath: string,
mediacentername: string,
password: string,
apipath: string,
videonr: number,
dbsize: number,
difftagnr: number,
tagsadded: number
customapi: boolean
apipath: string
generalSettings: SettingsTypes.loadGeneralSettingsType
}
interface props {}
interface props {
}
/**
* Component for Generalsettings tag on Settingspage
@ -38,20 +28,21 @@ class GeneralSettings extends React.Component<props, state> {
super(props);
this.state = {
passwordsupport: false,
tmdbsupport: false,
customapi: false,
videopath: '',
tvshowpath: '',
mediacentername: '',
password: '',
apipath: '',
videonr: 0,
dbsize: 0,
difftagnr: 0,
tagsadded: 0
generalSettings: {
DarkMode: true,
DBSize: 0,
DifferentTags: 0,
EpisodePath: "",
MediacenterName: "",
Password: "",
PasswordEnabled: false,
TagsAdded: 0,
TMDBGrabbing: false,
VideoNr: 0,
VideoPath: ""
}
};
}
@ -65,19 +56,19 @@ class GeneralSettings extends React.Component<props, state> {
<>
<div className={style.infoheader}>
<InfoHeaderItem backColor='lightblue'
text={this.state.videonr}
text={this.state.generalSettings.VideoNr}
subtext='Videos in Gravity'
icon={faArchive}/>
<InfoHeaderItem backColor='yellow'
text={this.state.dbsize !== undefined ? this.state.dbsize + ' MB' : ''}
text={this.state.generalSettings.DBSize + ' MB'}
subtext='Database size'
icon={faRulerVertical}/>
<InfoHeaderItem backColor='green'
text={this.state.difftagnr}
text={this.state.generalSettings.DifferentTags}
subtext='different Tags'
icon={faAddressCard}/>
<InfoHeaderItem backColor='orange'
text={this.state.tagsadded}
text={this.state.generalSettings.TagsAdded}
subtext='tags added'
icon={faBalanceScaleLeft}/>
</div>
@ -89,15 +80,26 @@ class GeneralSettings extends React.Component<props, state> {
<Form.Row>
<Form.Group as={Col} data-testid='videpathform'>
<Form.Label>Video Path</Form.Label>
<Form.Control type='text' placeholder='/var/www/html/video' value={this.state.videopath}
onChange={(ee): void => this.setState({videopath: ee.target.value})}/>
<Form.Control type='text' placeholder='/var/www/html/video'
value={this.state.generalSettings.VideoPath}
onChange={(ee): void => this.setState({
generalSettings: {
...this.state.generalSettings,
VideoPath: ee.target.value
}
})}/>
</Form.Group>
<Form.Group as={Col} data-testid='tvshowpath'>
<Form.Label>TV Show Path</Form.Label>
<Form.Control type='text' placeholder='/var/www/html/tvshow'
value={this.state.tvshowpath}
onChange={(e): void => this.setState({tvshowpath: e.target.value})}/>
value={this.state.generalSettings.EpisodePath}
onChange={(e): void => this.setState({
generalSettings: {
...this.state.generalSettings,
EpisodePath: e.target.value
}
})}/>
</Form.Group>
</Form.Row>
@ -131,17 +133,28 @@ class GeneralSettings extends React.Component<props, state> {
id='custom-switch'
data-testid='passwordswitch'
label='Enable Password support'
checked={this.state.passwordsupport}
checked={this.state.generalSettings.PasswordEnabled}
onChange={(): void => {
this.setState({passwordsupport: !this.state.passwordsupport});
this.setState({
generalSettings: {
...this.state.generalSettings,
PasswordEnabled: !this.state.generalSettings.PasswordEnabled
}
});
}}
/>
{this.state.passwordsupport ?
{this.state.generalSettings.PasswordEnabled ?
<Form.Group data-testid='passwordfield'>
<Form.Label>Password</Form.Label>
<Form.Control type='password' placeholder='**********' value={this.state.password}
onChange={(e): void => this.setState({password: e.target.value})}/>
<Form.Control type='password' placeholder='**********'
value={this.state.generalSettings.Password}
onChange={(e): void => this.setState({
generalSettings: {
...this.state.generalSettings,
Password: e.target.value
}
})}/>
</Form.Group> : null
}
@ -150,9 +163,14 @@ class GeneralSettings extends React.Component<props, state> {
id='custom-switch-2'
data-testid='tmdb-switch'
label='Enable TMDB video grabbing support'
checked={this.state.tmdbsupport}
checked={this.state.generalSettings.TMDBGrabbing}
onChange={(): void => {
this.setState({tmdbsupport: !this.state.tmdbsupport});
this.setState({
generalSettings: {
...this.state.generalSettings,
TMDBGrabbing: !this.state.generalSettings.TMDBGrabbing
}
});
}}
/>
@ -171,8 +189,14 @@ class GeneralSettings extends React.Component<props, state> {
<Form.Group className={style.mediacenternameform} data-testid='nameform'>
<Form.Label>The name of the Mediacenter</Form.Label>
<Form.Control type='text' placeholder='Mediacentername' value={this.state.mediacentername}
onChange={(e): void => this.setState({mediacentername: e.target.value})}/>
<Form.Control type='text' placeholder='Mediacentername'
value={this.state.generalSettings.MediacenterName}
onChange={(e): void => this.setState({
generalSettings: {
...this.state.generalSettings,
MediacenterName: e.target.value
}
})}/>
</Form.Group>
<Button variant='primary' type='submit'>
@ -192,19 +216,7 @@ class GeneralSettings extends React.Component<props, state> {
*/
loadSettings(): void {
callAPI(APINode.Settings, {action: 'loadGeneralSettings'}, (result: SettingsTypes.loadGeneralSettingsType) => {
this.setState({
videopath: result.video_path,
tvshowpath: result.episode_path,
mediacentername: result.mediacenter_name,
password: result.password,
passwordsupport: result.passwordEnabled,
tmdbsupport: result.TMDB_grabbing,
videonr: result.videonr,
dbsize: result.dbsize,
difftagnr: result.difftagnr,
tagsadded: result.tagsadded
});
this.setState({generalSettings: result});
});
}
@ -212,14 +224,15 @@ class GeneralSettings extends React.Component<props, state> {
* save the selected and typed settings to the backend
*/
saveSettings(): void {
let settings = this.state.generalSettings;
if(!this.state.generalSettings.PasswordEnabled){
settings.Password = '-1';
}
settings.DarkMode = GlobalInfos.isDarkTheme()
callAPI(APINode.Settings, {
action: 'saveGeneralSettings',
password: this.state.passwordsupport ? this.state.password : '-1',
videopath: this.state.videopath,
tvshowpath: this.state.tvshowpath,
mediacentername: this.state.mediacentername,
tmdbsupport: this.state.tmdbsupport,
darkmodeenabled: GlobalInfos.isDarkTheme().toString()
Settings: settings
}, (result: GeneralSuccess) => {
if (result.result) {
console.log('successfully saved settings');

View File

@ -52,10 +52,9 @@ describe('<MovieSettings/>', function () {
it('content available received and in state', () => {
const wrapper = shallow(<MovieSettings/>);
callAPIMock({
contentAvailable: true,
message: 'firstline\nsecondline'
ContentAvailable: true,
Messages: ['firstline', 'secondline']
})
wrapper.instance().updateStatus();
@ -70,7 +69,8 @@ describe('<MovieSettings/>', function () {
it('test reindex with no content available', () => {
callAPIMock({
contentAvailable: false
Messages: [],
ContentAvailable: false
})
global.clearInterval = jest.fn();
@ -99,12 +99,12 @@ describe('<MovieSettings/>', function () {
expect(wrapper.instance().setState).toBeCalledTimes(1);
});
it('test no textDiv insertion if string is empty', function () {
it('expect insertion before existing ones', function () {
const wrapper = shallow(<MovieSettings/>);
callAPIMock({
contentAvailable: true,
message: 'test'
ContentAvailable: true,
Messages: ['test']
})
wrapper.instance().updateStatus();
@ -115,14 +115,14 @@ describe('<MovieSettings/>', function () {
// expect an untouched state if we try to add an empty string...
callAPIMock({
contentAvailable: true,
message: ''
ContentAvailable: true,
Messages: ['']
})
wrapper.instance().updateStatus();
expect(wrapper.state()).toMatchObject({
text: ['test']
text: ['', 'test']
});
});
});

View File

@ -58,11 +58,7 @@ class MovieSettings extends React.Component<props, state> {
*/
startReindex(): void {
// clear output text before start
this.setState({text: []});
this.setState({startbtnDisabled: true});
console.log('starting');
this.setState({text: [], startbtnDisabled: true});
callAPI(APINode.Settings, {action: 'startReindex'}, (result: GeneralSuccess): void => {
console.log(result);
@ -85,18 +81,12 @@ class MovieSettings extends React.Component<props, state> {
*/
updateStatus = (): void => {
callAPI(APINode.Settings, {action: 'getStatusMessage'}, (result: SettingsTypes.getStatusMessageType) => {
if (result.contentAvailable) {
// ignore if message is empty
console.log(result);
if(result.message === '') return;
// todo 2020-07-4: scroll to bottom of div here
this.setState({
// insert a string for each line
text: [...result.message.split('\n'),
...this.state.text]
});
} else {
this.setState({
// insert a string for each line
text: [...result.Messages, ...this.state.text]
});
// todo 2020-07-4: scroll to bottom of div here
if (!result.ContentAvailable) {
// clear refresh interval if no content available
clearInterval(this.myinterval);