Merge branch 'fullydeleable' into 'master'
Fully Deletable Videos Closes #74 See merge request lukas/openmediacenter!52
This commit is contained in:
commit
2a098527bd
@ -15,7 +15,8 @@ func readVideosFromResultset(rows *sql.Rows) []types.VideoUnloadedType {
|
|||||||
var vid types.VideoUnloadedType
|
var vid types.VideoUnloadedType
|
||||||
err := rows.Scan(&vid.MovieId, &vid.MovieName)
|
err := rows.Scan(&vid.MovieId, &vid.MovieName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err.Error()) // proper error handling instead of panic in your app
|
fmt.Println(err.Error())
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
result = append(result, vid)
|
result = append(result, vid)
|
||||||
}
|
}
|
||||||
|
@ -67,12 +67,13 @@ func getSettingsFromDB() {
|
|||||||
sett := settings.LoadSettings()
|
sett := settings.LoadSettings()
|
||||||
|
|
||||||
type InitialDataTypeResponse struct {
|
type InitialDataTypeResponse struct {
|
||||||
DarkMode bool
|
DarkMode bool
|
||||||
Pasword bool
|
Pasword bool
|
||||||
MediacenterName string
|
MediacenterName string
|
||||||
VideoPath string
|
VideoPath string
|
||||||
TVShowPath string
|
TVShowPath string
|
||||||
TVShowEnabled bool
|
TVShowEnabled bool
|
||||||
|
FullDeleteEnabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
regexMatchUrl := regexp.MustCompile("^http(|s)://([0-9]){1,3}\\.([0-9]){1,3}\\.([0-9]){1,3}\\.([0-9]){1,3}:[0-9]{1,5}")
|
regexMatchUrl := regexp.MustCompile("^http(|s)://([0-9]){1,3}\\.([0-9]){1,3}\\.([0-9]){1,3}\\.([0-9]){1,3}:[0-9]{1,5}")
|
||||||
@ -82,12 +83,13 @@ func getSettingsFromDB() {
|
|||||||
serverTVShowPath := strings.TrimPrefix(sett.TVShowPath, tvshowurl)
|
serverTVShowPath := strings.TrimPrefix(sett.TVShowPath, tvshowurl)
|
||||||
|
|
||||||
res := InitialDataTypeResponse{
|
res := InitialDataTypeResponse{
|
||||||
DarkMode: sett.DarkMode,
|
DarkMode: sett.DarkMode,
|
||||||
Pasword: sett.Pasword != "-1",
|
Pasword: sett.Pasword != "-1",
|
||||||
MediacenterName: sett.MediacenterName,
|
MediacenterName: sett.MediacenterName,
|
||||||
VideoPath: serverVideoPath,
|
VideoPath: serverVideoPath,
|
||||||
TVShowPath: serverTVShowPath,
|
TVShowPath: serverTVShowPath,
|
||||||
TVShowEnabled: settings.TVShowsEnabled(),
|
TVShowEnabled: settings.TVShowsEnabled(),
|
||||||
|
FullDeleteEnabled: settings.VideosDeletable(),
|
||||||
}
|
}
|
||||||
|
|
||||||
str, _ := json.Marshal(res)
|
str, _ := json.Marshal(res)
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"openmediacenter/apiGo/api/types"
|
"openmediacenter/apiGo/api/types"
|
||||||
"openmediacenter/apiGo/database"
|
"openmediacenter/apiGo/database"
|
||||||
|
"openmediacenter/apiGo/database/settings"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -418,12 +420,14 @@ func addToVideoHandlers() {
|
|||||||
* @apiGroup video
|
* @apiGroup video
|
||||||
*
|
*
|
||||||
* @apiParam {int} MovieId ID of video
|
* @apiParam {int} MovieId ID of video
|
||||||
|
* @apiParam {bool} FullyDelete Delete video from disk?
|
||||||
*
|
*
|
||||||
* @apiSuccess {string} result 'success' if successfully or error message if not
|
* @apiSuccess {string} result 'success' if successfully or error message if not
|
||||||
*/
|
*/
|
||||||
AddHandler("deleteVideo", VideoNode, func(info *HandlerInfo) []byte {
|
AddHandler("deleteVideo", VideoNode, func(info *HandlerInfo) []byte {
|
||||||
var args struct {
|
var args struct {
|
||||||
MovieId int
|
MovieId int
|
||||||
|
FullyDelete bool
|
||||||
}
|
}
|
||||||
if err := FillStruct(&args, info.Data); err != nil {
|
if err := FillStruct(&args, info.Data); err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
@ -443,6 +447,26 @@ func addToVideoHandlers() {
|
|||||||
return database.ManualSuccessResponse(err)
|
return database.ManualSuccessResponse(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only allow deletion of video if cli flag is set, independent of passed api arg
|
||||||
|
if settings.VideosDeletable() && args.FullyDelete {
|
||||||
|
// get physical path of video to delete
|
||||||
|
query = fmt.Sprintf("SELECT movie_url FROM videos WHERE movie_id=%d", args.MovieId)
|
||||||
|
var vidpath string
|
||||||
|
err := database.QueryRow(query).Scan(&vidpath)
|
||||||
|
if err != nil {
|
||||||
|
return database.ManualSuccessResponse(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assembledPath := database.SettingsVideoPrefix + "/" + vidpath
|
||||||
|
|
||||||
|
err = os.Remove(assembledPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("unable to delete file: %s -- %s\n", assembledPath, err.Error())
|
||||||
|
return database.ManualSuccessResponse(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete video row from db
|
||||||
query = fmt.Sprintf("DELETE FROM videos WHERE movie_id=%d", args.MovieId)
|
query = fmt.Sprintf("DELETE FROM videos WHERE movie_id=%d", args.MovieId)
|
||||||
return database.SuccessQuery(query)
|
return database.SuccessQuery(query)
|
||||||
})
|
})
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package settings
|
package settings
|
||||||
|
|
||||||
var tvShowEnabled bool
|
var tvShowEnabled bool
|
||||||
|
var videosDeletable bool
|
||||||
|
|
||||||
func TVShowsEnabled() bool {
|
func TVShowsEnabled() bool {
|
||||||
return tvShowEnabled
|
return tvShowEnabled
|
||||||
@ -9,3 +10,11 @@ func TVShowsEnabled() bool {
|
|||||||
func SetTVShowEnabled(enabled bool) {
|
func SetTVShowEnabled(enabled bool) {
|
||||||
tvShowEnabled = enabled
|
tvShowEnabled = enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func VideosDeletable() bool {
|
||||||
|
return videosDeletable
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetVideosDeletable(deletable bool) {
|
||||||
|
videosDeletable = deletable
|
||||||
|
}
|
||||||
|
@ -57,10 +57,12 @@ func handleCommandLineArguments() (*database.DatabaseConfig, bool, *string) {
|
|||||||
pathPrefix := flag.String("ReindexPrefix", "/var/www/openmediacenter", "Prefix path for videos to reindex")
|
pathPrefix := flag.String("ReindexPrefix", "/var/www/openmediacenter", "Prefix path for videos to reindex")
|
||||||
|
|
||||||
disableTVShowSupport := flag.Bool("DisableTVSupport", false, "Disable the TVShow support and pages")
|
disableTVShowSupport := flag.Bool("DisableTVSupport", false, "Disable the TVShow support and pages")
|
||||||
|
videosFullyDeletable := flag.Bool("FullyDeletableVideos", false, "Allow deletion from harddisk")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
settings2.SetTVShowEnabled(!*disableTVShowSupport)
|
settings2.SetTVShowEnabled(!*disableTVShowSupport)
|
||||||
|
settings2.SetVideosDeletable(*videosFullyDeletable)
|
||||||
|
|
||||||
return &database.DatabaseConfig{
|
return &database.DatabaseConfig{
|
||||||
DBHost: *dbhostPtr,
|
DBHost: *dbhostPtr,
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
"build": "CI=false react-scripts build",
|
"build": "CI=false react-scripts build",
|
||||||
"test": "CI=true react-scripts test --reporters=jest-junit --verbose --silent --coverage --reporters=default",
|
"test": "CI=true react-scripts test --reporters=jest-junit --verbose --silent --coverage --reporters=default",
|
||||||
"lint": "eslint --format gitlab src/",
|
"lint": "eslint --format gitlab src/",
|
||||||
"apidoc": "apidoc -i apiGo/ -o doc/"
|
"apidoc": "apidoc --single -i apiGo/ -o doc/"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"collectCoverageFrom": [
|
"collectCoverageFrom": [
|
||||||
|
@ -87,6 +87,7 @@ class App extends React.Component<{}, state> {
|
|||||||
GlobalInfos.setVideoPaths(result.VideoPath, result.TVShowPath);
|
GlobalInfos.setVideoPaths(result.VideoPath, result.TVShowPath);
|
||||||
|
|
||||||
GlobalInfos.setTVShowsEnabled(result.TVShowEnabled);
|
GlobalInfos.setTVShowsEnabled(result.TVShowEnabled);
|
||||||
|
GlobalInfos.setFullDeleteEnabled(result.FullDeleteEnabled);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
mediacentername: result.MediacenterName
|
mediacentername: result.MediacenterName
|
||||||
|
51
src/elements/Popups/ButtonPopup/ButtonPopup.test.js
Normal file
51
src/elements/Popups/ButtonPopup/ButtonPopup.test.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import {shallow} from 'enzyme';
|
||||||
|
import React from 'react';
|
||||||
|
import {ButtonPopup} from './ButtonPopup';
|
||||||
|
import exp from "constants";
|
||||||
|
|
||||||
|
describe('<ButtonPopup/>', function () {
|
||||||
|
it('renders without crashing ', function () {
|
||||||
|
const wrapper = shallow(<ButtonPopup/>);
|
||||||
|
wrapper.unmount();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders two buttons', function () {
|
||||||
|
const wrapper = shallow(<ButtonPopup/>);
|
||||||
|
expect(wrapper.find('Button')).toHaveLength(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders three buttons if alternative defined', function () {
|
||||||
|
const wrapper = shallow(<ButtonPopup AlternativeButtonTitle='alt'/>);
|
||||||
|
expect(wrapper.find('Button')).toHaveLength(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('test click handlings', function () {
|
||||||
|
const althandler = jest.fn();
|
||||||
|
const denyhandler = jest.fn();
|
||||||
|
const submithandler = jest.fn();
|
||||||
|
|
||||||
|
const wrapper = shallow(<ButtonPopup DenyButtonTitle='deny' onDeny={denyhandler} SubmitButtonTitle='submit'
|
||||||
|
onSubmit={submithandler} AlternativeButtonTitle='alt'
|
||||||
|
onAlternativeButton={althandler}/>);
|
||||||
|
wrapper.find('Button').findWhere(e => e.props().title === "deny").simulate('click');
|
||||||
|
expect(denyhandler).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
wrapper.find('Button').findWhere(e => e.props().title === "alt").simulate('click');
|
||||||
|
expect(althandler).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
wrapper.find('Button').findWhere(e => e.props().title === "submit").simulate('click');
|
||||||
|
expect(submithandler).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('test Parentsubmit and parenthide callbacks', function () {
|
||||||
|
const ondeny = jest.fn();
|
||||||
|
const onsubmit = jest.fn();
|
||||||
|
|
||||||
|
const wrapper = shallow(<ButtonPopup DenyButtonTitle='deny' SubmitButtonTitle='submit' onDeny={ondeny} onSubmit={onsubmit} AlternativeButtonTitle='alt'/>);
|
||||||
|
wrapper.find('PopupBase').props().onHide();
|
||||||
|
expect(ondeny).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
wrapper.find('PopupBase').props().ParentSubmit();
|
||||||
|
expect(onsubmit).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
58
src/elements/Popups/ButtonPopup/ButtonPopup.tsx
Normal file
58
src/elements/Popups/ButtonPopup/ButtonPopup.tsx
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PopupBase from '../PopupBase';
|
||||||
|
import {Button} from '../../GPElements/Button';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete Video popup
|
||||||
|
* can only be rendered once!
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
export const ButtonPopup = (props: {
|
||||||
|
onSubmit: () => void;
|
||||||
|
onDeny: () => void;
|
||||||
|
onAlternativeButton?: () => void;
|
||||||
|
SubmitButtonTitle: string;
|
||||||
|
DenyButtonTitle: string;
|
||||||
|
AlternativeButtonTitle?: string;
|
||||||
|
Title: string;
|
||||||
|
}): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PopupBase
|
||||||
|
title={props.Title}
|
||||||
|
onHide={(): void => props.onDeny()}
|
||||||
|
height='200px'
|
||||||
|
width='400px'
|
||||||
|
ParentSubmit={(): void => {
|
||||||
|
props.onSubmit();
|
||||||
|
}}>
|
||||||
|
<Button
|
||||||
|
onClick={(): void => {
|
||||||
|
props.onSubmit();
|
||||||
|
}}
|
||||||
|
title={props.SubmitButtonTitle}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{props.AlternativeButtonTitle ? (
|
||||||
|
<Button
|
||||||
|
color={{backgroundColor: 'darkorange'}}
|
||||||
|
onClick={(): void => {
|
||||||
|
props.onAlternativeButton ? props.onAlternativeButton() : null;
|
||||||
|
}}
|
||||||
|
title={props.AlternativeButtonTitle}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Button
|
||||||
|
color={{backgroundColor: 'red'}}
|
||||||
|
onClick={(): void => {
|
||||||
|
props.onDeny();
|
||||||
|
}}
|
||||||
|
title={props.DenyButtonTitle}
|
||||||
|
/>
|
||||||
|
</PopupBase>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -2,6 +2,7 @@ import {shallow} from 'enzyme';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Player} from './Player';
|
import {Player} from './Player';
|
||||||
import {callAPI} from '../../utils/Api';
|
import {callAPI} from '../../utils/Api';
|
||||||
|
import GlobalInfos from "../../utils/GlobalInfos";
|
||||||
|
|
||||||
describe('<Player/>', function () {
|
describe('<Player/>', function () {
|
||||||
|
|
||||||
@ -84,23 +85,54 @@ describe('<Player/>', function () {
|
|||||||
expect(wrapper.find('AddTagPopup')).toHaveLength(1);
|
expect(wrapper.find('AddTagPopup')).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('test delete button', done => {
|
it('test fully delete popup rendering', function () {
|
||||||
const wrapper = instance();
|
const wrapper = instance();
|
||||||
|
|
||||||
|
// allow videos to be fully deletable
|
||||||
|
GlobalInfos.setFullDeleteEnabled(true);
|
||||||
|
|
||||||
wrapper.setProps({history: {goBack: jest.fn()}});
|
wrapper.setState({deletepopupvisible: true});
|
||||||
|
|
||||||
global.fetch = prepareFetchApi({result: 'success'});
|
expect(wrapper.find('ButtonPopup')).toHaveLength(1)
|
||||||
|
});
|
||||||
|
|
||||||
|
it('test delete popup rendering', function () {
|
||||||
|
const wrapper = instance();
|
||||||
|
|
||||||
|
GlobalInfos.setFullDeleteEnabled(false);
|
||||||
|
wrapper.setState({deletepopupvisible: true});
|
||||||
|
|
||||||
|
expect(wrapper.find('ButtonPopup')).toHaveLength(1)
|
||||||
|
});
|
||||||
|
|
||||||
|
it('test delete button', () => {
|
||||||
|
const wrapper = instance();
|
||||||
|
const callback = jest.fn();
|
||||||
|
|
||||||
|
wrapper.setProps({history: {goBack: callback}});
|
||||||
|
|
||||||
|
callAPIMock({result: 'success'})
|
||||||
|
GlobalInfos.setFullDeleteEnabled(false);
|
||||||
|
|
||||||
|
// request the popup to pop
|
||||||
wrapper.find('.videoactions').find('Button').at(2).simulate('click');
|
wrapper.find('.videoactions').find('Button').at(2).simulate('click');
|
||||||
|
|
||||||
process.nextTick(() => {
|
// click the first submit button
|
||||||
// refetch is called so fetch called 3 times
|
wrapper.find('ButtonPopup').dive().find('Button').at(0).simulate('click')
|
||||||
expect(global.fetch).toHaveBeenCalledTimes(1);
|
|
||||||
expect(wrapper.instance().props.history.goBack).toHaveBeenCalledTimes(1);
|
|
||||||
|
|
||||||
global.fetch.mockClear();
|
// refetch is called so fetch called 3 times
|
||||||
done();
|
expect(callAPI).toHaveBeenCalledTimes(1);
|
||||||
|
expect(callback).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
|
// now lets test if this works also with the fullydeletepopup
|
||||||
|
GlobalInfos.setFullDeleteEnabled(true);
|
||||||
|
// request the popup to pop
|
||||||
|
wrapper.setState({deletepopupvisible: true}, () => {
|
||||||
|
// click the first submit button
|
||||||
|
wrapper.find('ButtonPopup').dive().find('Button').at(0).simulate('click')
|
||||||
|
|
||||||
|
expect(callAPI).toHaveBeenCalledTimes(2);
|
||||||
|
expect(callback).toHaveBeenCalledTimes(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -152,16 +184,14 @@ describe('<Player/>', function () {
|
|||||||
it('test click of quickadd tag btn', done => {
|
it('test click of quickadd tag btn', done => {
|
||||||
const wrapper = generatetag();
|
const wrapper = generatetag();
|
||||||
|
|
||||||
global.fetch = prepareFetchApi({result: 'success'});
|
callAPIMock({result: 'success'})
|
||||||
|
|
||||||
// render tag subcomponent
|
// render tag subcomponent
|
||||||
const tag = wrapper.find('Tag').first().dive();
|
const tag = wrapper.find('Tag').first().dive();
|
||||||
tag.simulate('click');
|
tag.simulate('click');
|
||||||
|
|
||||||
process.nextTick(() => {
|
process.nextTick(() => {
|
||||||
expect(global.fetch).toHaveBeenCalledTimes(1);
|
expect(callAPI).toHaveBeenCalledTimes(1);
|
||||||
|
|
||||||
global.fetch.mockClear();
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -169,7 +199,7 @@ describe('<Player/>', function () {
|
|||||||
it('test failing quickadd', done => {
|
it('test failing quickadd', done => {
|
||||||
const wrapper = generatetag();
|
const wrapper = generatetag();
|
||||||
|
|
||||||
global.fetch = prepareFetchApi({result: 'nonsuccess'});
|
callAPIMock({result: 'nonsuccess'});
|
||||||
global.console.error = jest.fn();
|
global.console.error = jest.fn();
|
||||||
|
|
||||||
// render tag subcomponent
|
// render tag subcomponent
|
||||||
@ -178,8 +208,6 @@ describe('<Player/>', function () {
|
|||||||
|
|
||||||
process.nextTick(() => {
|
process.nextTick(() => {
|
||||||
expect(global.console.error).toHaveBeenCalledTimes(2);
|
expect(global.console.error).toHaveBeenCalledTimes(2);
|
||||||
|
|
||||||
global.fetch.mockClear();
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -21,6 +21,7 @@ import PlyrJS from 'plyr';
|
|||||||
import {Button} from '../../elements/GPElements/Button';
|
import {Button} from '../../elements/GPElements/Button';
|
||||||
import {VideoTypes} from '../../types/ApiTypes';
|
import {VideoTypes} from '../../types/ApiTypes';
|
||||||
import GlobalInfos from '../../utils/GlobalInfos';
|
import GlobalInfos from '../../utils/GlobalInfos';
|
||||||
|
import {ButtonPopup} from '../../elements/Popups/ButtonPopup/ButtonPopup';
|
||||||
|
|
||||||
interface Props extends RouteComponentProps<{id: string}> {}
|
interface Props extends RouteComponentProps<{id: string}> {}
|
||||||
|
|
||||||
@ -35,6 +36,7 @@ interface mystate {
|
|||||||
suggesttag: TagType[];
|
suggesttag: TagType[];
|
||||||
popupvisible: boolean;
|
popupvisible: boolean;
|
||||||
actorpopupvisible: boolean;
|
actorpopupvisible: boolean;
|
||||||
|
deletepopupvisible: boolean;
|
||||||
actors: ActorType[];
|
actors: ActorType[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +58,7 @@ export class Player extends React.Component<Props, mystate> {
|
|||||||
suggesttag: [],
|
suggesttag: [],
|
||||||
popupvisible: false,
|
popupvisible: false,
|
||||||
actorpopupvisible: false,
|
actorpopupvisible: false,
|
||||||
|
deletepopupvisible: false,
|
||||||
actors: []
|
actors: []
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -91,7 +94,7 @@ export class Player extends React.Component<Props, mystate> {
|
|||||||
<Button
|
<Button
|
||||||
title='Delete Video'
|
title='Delete Video'
|
||||||
onClick={(): void => {
|
onClick={(): void => {
|
||||||
this.deleteVideo();
|
this.setState({deletepopupvisible: true});
|
||||||
}}
|
}}
|
||||||
color={{backgroundColor: 'red'}}
|
color={{backgroundColor: 'red'}}
|
||||||
/>
|
/>
|
||||||
@ -196,10 +199,46 @@ export class Player extends React.Component<Props, mystate> {
|
|||||||
movieId={this.state.movieId}
|
movieId={this.state.movieId}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
{this.state.deletepopupvisible ? this.renderDeletePopup() : null}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderDeletePopup(): JSX.Element {
|
||||||
|
if (GlobalInfos.isVideoFulldeleteable()) {
|
||||||
|
return (
|
||||||
|
<ButtonPopup
|
||||||
|
onDeny={(): void => this.setState({deletepopupvisible: false})}
|
||||||
|
onSubmit={(): void => {
|
||||||
|
this.setState({deletepopupvisible: false});
|
||||||
|
this.deleteVideo(true);
|
||||||
|
}}
|
||||||
|
onAlternativeButton={(): void => {
|
||||||
|
this.setState({deletepopupvisible: false});
|
||||||
|
this.deleteVideo(false);
|
||||||
|
}}
|
||||||
|
DenyButtonTitle='Cancel'
|
||||||
|
SubmitButtonTitle='Fully Delete!'
|
||||||
|
Title='Fully Delete Video?'
|
||||||
|
AlternativeButtonTitle='Reference Only'
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<ButtonPopup
|
||||||
|
onDeny={(): void => this.setState({deletepopupvisible: false})}
|
||||||
|
onSubmit={(): void => {
|
||||||
|
this.setState({deletepopupvisible: false});
|
||||||
|
this.deleteVideo(false);
|
||||||
|
}}
|
||||||
|
DenyButtonTitle='Cancel'
|
||||||
|
SubmitButtonTitle='Delete Video Reference!'
|
||||||
|
Title='Delete Video?'
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* quick add callback to add tag to db and change gui correctly
|
* quick add callback to add tag to db and change gui correctly
|
||||||
* @param tagId id of tag to add
|
* @param tagId id of tag to add
|
||||||
@ -325,17 +364,16 @@ export class Player extends React.Component<Props, mystate> {
|
|||||||
/**
|
/**
|
||||||
* delete the current video and return to last page
|
* delete the current video and return to last page
|
||||||
*/
|
*/
|
||||||
deleteVideo(): void {
|
deleteVideo(fullyDelete: boolean): void {
|
||||||
callAPI(
|
callAPI(
|
||||||
APINode.Video,
|
APINode.Video,
|
||||||
{action: 'deleteVideo', MovieId: parseInt(this.props.match.params.id, 10)},
|
{action: 'deleteVideo', MovieId: parseInt(this.props.match.params.id, 10), FullyDelete: fullyDelete},
|
||||||
(result: GeneralSuccess) => {
|
(result: GeneralSuccess) => {
|
||||||
if (result.result === 'success') {
|
if (result.result === 'success') {
|
||||||
// return to last element if successful
|
// return to last element if successful
|
||||||
this.props.history.goBack();
|
this.props.history.goBack();
|
||||||
} else {
|
} else {
|
||||||
console.error('an error occured while liking');
|
console.error('an error occured while deleting the video: ' + JSON.stringify(result));
|
||||||
console.error(result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -37,6 +37,7 @@ export namespace SettingsTypes {
|
|||||||
VideoPath: string;
|
VideoPath: string;
|
||||||
TVShowPath: string;
|
TVShowPath: string;
|
||||||
TVShowEnabled: boolean;
|
TVShowEnabled: boolean;
|
||||||
|
FullDeleteEnabled: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SettingsType {
|
export interface SettingsType {
|
||||||
|
@ -10,6 +10,7 @@ class StaticInfos {
|
|||||||
private videopath: string = '';
|
private videopath: string = '';
|
||||||
private tvshowpath: string = '';
|
private tvshowpath: string = '';
|
||||||
private TVShowsEnabled: boolean = false;
|
private TVShowsEnabled: boolean = false;
|
||||||
|
private fullDeleteable: boolean = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if the current theme is the dark theme
|
* check if the current theme is the dark theme
|
||||||
@ -80,6 +81,14 @@ class StaticInfos {
|
|||||||
isTVShowEnabled(): boolean {
|
isTVShowEnabled(): boolean {
|
||||||
return this.TVShowsEnabled;
|
return this.TVShowsEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setFullDeleteEnabled(FullDeleteEnabled: boolean): void {
|
||||||
|
this.fullDeleteable = FullDeleteEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
isVideoFulldeleteable(): boolean {
|
||||||
|
return this.fullDeleteable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new StaticInfos();
|
export default new StaticInfos();
|
||||||
|
Loading…
Reference in New Issue
Block a user