This commit is contained in:
Artem Anufrij
2023-02-08 12:37:55 +01:00
commit 3af8005786
152 changed files with 37333 additions and 0 deletions

91
src/store/actions.js Normal file
View File

@@ -0,0 +1,91 @@
import axios from 'axios'
export default {
checkIfInstanceIsNew(context) {
return new Promise((resolve) => {
axios.get(context.rootGetters.server + "/api/system/setup").then((res) => {
if (res.status == 200) {
resolve(true);
} else {
resolve(false);
}
});
});
},
loadClientConfigs(context) {
return new Promise((resolve) => {
axios.get("./config.json").then((res) => {
context.state.clientConfig.server = res.data.backend;
context.state.clientConfig.isElectron = navigator.userAgent.toLowerCase().includes("electron");
if (window.location.hostname.includes("localhost") && !context.getters.isElectron) {
context.state.clientConfig.server = res.data.backend_dev;
}
resolve();
});
});
},
loadSystemDomains(context) {
return new Promise((resolve) => {
axios.get(context.rootGetters.server + "/api/system/domains", context.rootGetters.headers).then((res) => {
context.commit("setSystemConfigDomains", res.data);
resolve(res.data);
});
})
},
loadSystemSettings(context) {
axios.get(context.rootGetters.server + "/api/system").then((res) => {
context.commit("setSystemSettings", res.data);
});
},
loadServerInfo(context) {
axios.get(context.rootGetters.server + "/api/info").then((res) => {
context.commit("setServerInfo", res.data);
});
},
resetViewMenu(context) {
context.commit("resetViewMenu");
},
setNewBackend(context, backend) {
axios.post("/settings", { backend: backend }).then(() => {
context.commit("setServer", backend);
});
},
setViewMenu(context, menuItems) {
context.commit("setViewMenu", menuItems);
},
startScanningMusic(context) {
if (!context.state.serverStatus.scanning_music) {
axios.post(context.rootGetters.server + "/api/scan/music", {}, context.rootGetters.headers).then(() => {
context.state.serverStatus.scanning_music = true;
});
}
},
startScanningVideos(context) {
if (!context.state.serverStatus.scanning_video) {
axios.post(context.rootGetters.server + "/api/scan/video", {}, context.rootGetters.headers).then(() => {
context.state.serverStatus.scanning_video = true;
});
}
},
saveSystemAllows(context, allows) {
axios
.post(context.rootGetters.server + "/api/system", allows, context.rootGetters.headers)
.then((res) => {
if (res.status == 200) {
context.commit("setServerConfigAllows", allows);
}
});
},
saveSystemDomains(context, domains) {
axios
.post(context.rootGetters.server + "/api/system/domains", domains.dynamic, context.rootGetters.headers)
.then((res) => {
if (res.status == 200) {
context.commit("setSystemConfigDomains", domains);
}
});
},
resetRedisCache(context) {
axios.post(context.rootGetters.server + "/api/system/reset/redis", {}, context.rootGetters.headers);
}
}

31
src/store/getters.js Normal file
View File

@@ -0,0 +1,31 @@
import router from '../router'
export default {
headers(state, getters) {
return { headers: { authorization: getters["user/token"] } };
},
server(state) {
return state.clientConfig.server;
},
isElectron(state) {
return state.clientConfig.isElectron;
},
isDialogOpen(state, getters) {
return getters["albums/selectedAlbum"]._id || getters["artists/selectedArtist"]._id || getters["boxes/selectedBox"]._id
},
viewMenu(state, getters) {
return state.viewMenu.filter(item => { return item.roles && getters["user/roles"].find(role => { return item.roles.indexOf(role) > -1 }) });
},
routerPath() {
return router.currentRoute._value.path;
},
routerQuery() {
return router.currentRoute._value.query;
},
serverInfo(state) {
return state.serverInfo;
},
serverConfig(state) {
return state.serverConfig;
}
}

36
src/store/index.js Normal file
View File

@@ -0,0 +1,36 @@
import { createStore } from 'vuex'
import state from './state'
import getters from './getters'
import mutations from './mutations'
import actions from "./actions"
import albums from "./modules/albums/"
import artists from "./modules/artists/"
import boxes from "./modules/boxes/"
import radios from "./modules/radios/"
import tracks from "./modules/tracks/"
import player from "./modules/player"
import user from "./modules/user"
import videos from "./modules/videos"
import system from "./modules/system"
import search from "./modules/search"
export default createStore({
state,
getters,
mutations,
actions,
modules: {
albums,
artists,
boxes,
radios,
player,
tracks,
user,
videos,
system,
search
}
})

View File

@@ -0,0 +1,157 @@
import axios from 'axios'
import router from '../../../router'
export default {
clear(context) {
context.commit("clear");
},
filter(context, term) {
return new Promise((resolve) => {
axios.get(context.rootGetters.server + "/api/albums/filter/" + term, context.rootGetters.headers).then(res => {
resolve(res.data);
});
})
},
getNextTo(context, album) {
return new Promise(resolve => {
let i = context.getters.collection.indexOf(album);
if (i > -1 && i < context.getters.collection.length - 1) {
resolve(context.getters.collection[++i]);
}
resolve();
});
},
getPrevTo(context, album) {
return new Promise(resolve => {
let i = context.getters.collection.indexOf(album);
if (i > 0) {
resolve(context.getters.collection[--i]);
}
resolve();
})
},
loadAlbums(context, force) {
if ((!context.state.eos || force) && !context.state.loading) {
context.state.loading = true;
axios.get(context.rootGetters.server + "/api/albums/page/" + context.state.page++, context.rootGetters.headers).then((res) => {
context.commit("setAlbums", res.data);
});
}
},
loadFavourites(context) {
axios.get(context.rootGetters.server + "/api/albums/favourites", context.rootGetters.headers).then(res => {
if (res.data.length > 0) {
context.commit("setAlbums", res.data);
}
});
},
loadNewest(context) {
axios.get(context.rootGetters.server + "/api/albums/newest/6", context.rootGetters.headers).then((res) => {
context.commit("setNewest", res.data);
});
},
loadAlbum(context, id) {
context.state.loading = true;
return new Promise((resolve) => {
axios.get(context.rootGetters.server + "/api/albums/" + id, context.rootGetters.headers).then((res) => {
if (res.data != "") {
context.commit("setAlbums", [res.data]);
} else {
context.state.loading = false;
}
resolve(res.data);
})
})
},
resetSelectedAlbum(context) {
context.commit("resetSelectedAlbum");
router.push("/albums");
},
move(context, payload) {
return new Promise((resolve) => {
axios.put(context.rootGetters.server + "/api/albums/" + payload.source + "/move", payload, context.rootGetters.headers).then(res => {
resolve(res.data);
});
})
},
remove(context, id) {
context.commit("remove", id);
},
selectAlbum(context, album) {
if (album.tracks.length == 0) {
context.dispatch("loadAlbum", album._id);
}
context.commit('selectAlbum', album);
if (context.rootGetters.routerQuery.id != album._id) {
let url = "/albums?id=" + album._id;
let track = context.rootGetters["tracks/selectedTrack"];
if (track._id && track.parentType == "album" && track.parent._id == album._id) {
url += "&play=" + track._id
}
router.push(url);
}
context.dispatch("preloads");
},
preloads(context) {
// PRELOAD NEXT AND PREV ALBUM
let next = context.getters.nextAlbum;
if (next._id && next.tracks.length == 0) {
context.dispatch("loadAlbum", next._id);
}
let prev = context.getters.prevAlbum;
if (prev._id && prev.tracks.length == 0) {
context.dispatch("loadAlbum", prev._id);
}
},
selectAlbumById(context, id) {
let album = context.getters.collection.find(item => item._id == id);
if (album) {
context.dispatch("selectAlbum", album);
}
},
gotoPrevAlbum(context) {
let prevAlbum = context.getters.prevAlbum;
if (prevAlbum._id) {
context.dispatch("selectAlbum", prevAlbum);
}
},
gotoNextAlbum(context) {
let nextAlbum = context.getters.nextAlbum;
if (nextAlbum._id) {
context.dispatch("selectAlbum", nextAlbum);
}
},
uploadNewCover(context, album) {
let input = document.createElement('input');
input.type = "file";
input.accept = "image/jpeg, image/png";
input.addEventListener("change", function () {
if (input.value) {
let formData = new FormData();
formData.append("file", input.files[0]);
let h = context.rootGetters.headers;
h.headers["content-type"] = "multipart/form-data";
axios
.put(context.rootGetters.server + "/api/albums/" + album._id + "/cover", formData, context.rootGetters.headers)
.then(res => {
album.covers = res.data;
});
}
});
input.click();
},
resetCover(context, album) {
axios.delete(context.rootGetters.server + "/api/albums/" + album._id + "/cover", context.rootGetters.headers).then(() => {
album.covers = {}
});
},
updateAlbum(context, album) {
let body = {
_id: album._id,
visibility: album.visibility
}
axios.put(context.rootGetters.server + "/api/albums/" + album._id, body, context.rootGetters.headers);
}
}

View File

@@ -0,0 +1,36 @@
export default {
collection(state) {
return state.collection;
},
favourites(state, getters, rootState, rootGetters) {
return state.collection.filter(f => rootGetters["user/favourites"].map(m => m.itemId).indexOf(f._id) > -1);
},
nextAlbum(state) {
let currentIndex = state.collection.indexOf(state.selectedAlbum);
let nextAlbum = {};
if (state.collection.length > currentIndex + 1) {
nextAlbum = state.collection[currentIndex + 1];
}
return nextAlbum;
},
prevAlbum(state) {
let currentIndex = state.collection.indexOf(state.selectedAlbum);
let prevAlbum = {};
if (currentIndex > 0) {
prevAlbum = state.collection[currentIndex - 1];
}
return prevAlbum;
},
selectedAlbum(state) {
return state.selectedAlbum;
},
loading(state) {
return state.loading;
},
eos(state) {
return state.eos;
},
newest(state) {
return state.newest;
}
}

View File

@@ -0,0 +1,12 @@
import state from './state.js';
import getters from './getters.js';
import mutations from './mutations.js';
import actions from './actions.js';
export default {
namespaced: true,
state,
getters,
mutations,
actions
}

View File

@@ -0,0 +1,79 @@
export default {
clear(state) {
state.collection = [];
state.newest = [];
state.loading = false;
state.eos = false;
state.page = 1;
},
remove(state, id) {
let album = state.collection.find(f => f._id == id);
if (album) {
let i = state.collection.indexOf(album);
state.collection.splice(i, 1);
}
},
resetSelectedAlbum(state) {
if (state.selectedAlbum._id)
state.selectedAlbum = { tracks: [], covers: {} };
},
selectAlbum(state, album) {
if (state.selectedAlbum._id != album._id) {
state.selectedAlbum = album;
}
},
setAlbums(state, albums) {
if (albums.length == 0) {
state.eos = true;
state.loading = false;
if (state.page > 1) {
state.page--;
}
return;
}
albums.forEach(album => {
let existsAlbum = state.collection.find(f => f._id == album._id);
if (!existsAlbum) {
let item = state.collection.find((item) => {
if (item.artist_name > album.artist_name
|| item.artist_name == album.artist_name && item.year > album.year
|| item.artist_name == album.artist_name && item.year == album.year && item.title > album.title) {
return item;
}
})
if (!album.covers) {
album.covers = {};
}
if (item) {
let index = state.collection.indexOf(item);
state.collection.splice(index, 0, album);
} else {
state.collection.push(album);
}
album.tracks.forEach((track) => {
track.parent = album;
track.parentType = "album"
});
} else if (existsAlbum && album.tracks.length > 0) {
existsAlbum.covers = album.covers || {};
existsAlbum.tracks = album.tracks;
existsAlbum.tracks.forEach((track) => {
track.parent = existsAlbum;
track.parentType = "album"
});
}
});
state.loading = false;
},
setNewest(state, albums) {
albums.forEach(album => {
if (!album.covers) {
album.covers = {};
}
});
state.newest = albums;
}
}

View File

@@ -0,0 +1,8 @@
export default {
collection: [],
newest: [],
selectedAlbum: { tracks: [], covers: {} },
page: 1,
loading: false,
eos: false
}

View File

@@ -0,0 +1,123 @@
import axios from 'axios'
import router from '../../../router'
export default {
clear(context) {
context.commit("clear");
},
filter(context, term) {
return new Promise((resolve) => {
axios.get(context.rootGetters.server + "/api/artists/filter/" + term, context.rootGetters.headers).then(res => {
resolve(res.data);
});
})
},
loadArtists(context, force) {
if ((!context.state.eos || force) && !context.state.loading) {
context.state.loading = true;
axios.get(context.rootGetters.server + "/api/artists/page/" + context.state.page++, context.rootGetters.headers).then((res) => {
context.commit("setArtists", res.data);
});
}
},
loadArtist(context, id) {
context.state.loading = true;
return new Promise((resolve) => {
axios.get(context.rootGetters.server + "/api/artists/" + id, context.rootGetters.headers).then((res) => {
if (res.data != "") {
context.commit("setArtists", [res.data]);
} else {
context.state.loading = false;
}
resolve(res.data);
});
});
},
loadFavourites(context) {
axios.get(context.rootGetters.server + "/api/artists/favourites", context.rootGetters.headers).then(res => {
if (res.data.length > 0) {
context.commit("setArtists", res.data);
}
});
},
selectArtist(context, artist) {
if (artist.albums.length == 0) {
context.dispatch("loadArtist", artist._id)
}
context.commit('selectArtist', artist);
if (context.rootGetters.routerQuery.id != artist._id) {
let url = "/artists?id=" + artist._id;
let track = context.rootGetters["tracks/selectedTrack"];
if (track._id && track.parentType == "artist" && track.parent.parent._id == artist._id) {
url += "&play=" + track._id
}
router.push(url);
}
// PRELOAD NEXT AND PREV ARTIST
let next = context.getters.nextArtist;
if (next._id && next.albums.length == 0) {
context.dispatch("loadArtist", next._id);
}
let prev = context.getters.prevArtist;
if (prev._id && prev.albums.length == 0) {
context.dispatch("loadArtist", prev._id);
}
},
selectArtistById(context, id) {
let artist = context.getters.collection.find(item => item._id == id);
if (artist && artist._id != context.getters.selectedArtist._id) {
context.dispatch("selectArtist", artist);
}
},
resetSelectedArtist(context) {
context.commit("resetSelectedArtist");
router.push("/artists");
},
move(context, payload) {
return new Promise((resolve) => {
axios.put(context.rootGetters.server + "/api/artists/" + payload.source + "/move", payload, context.rootGetters.headers).then(res => {
resolve(res.data);
});
})
},
remove(context, id) {
context.commit("remove", id);
},
gotoPrevArtist(context) {
let prevArtist = context.getters.prevArtist;
if (prevArtist._id) {
context.dispatch("selectArtist", prevArtist);
}
},
gotoNextArtist(context) {
let nextArtist = context.getters.nextArtist;
if (nextArtist._id) {
context.dispatch("selectArtist", nextArtist);
}
},
uploadNewCover(context, artist) {
let input = document.createElement('input');
input.type = "file";
input.accept = "image/jpeg, image/png";
input.addEventListener("change", function () {
if (input.value) {
let formData = new FormData();
formData.append("file", input.files[0]);
let h = context.rootGetters.headers;
h.headers["content-type"] = "multipart/form-data";
axios
.put(context.rootGetters.server + "/api/artists/" + artist._id + "/cover", formData, context.rootGetters.headers)
.then(res => {
artist.covers = res.data;
});
}
});
input.click();
},
resetCover(context, artist) {
axios.delete(context.rootGetters.server + "/api/artists/" + artist._id + "/cover", context.rootGetters.headers).then(() => {
artist.covers = {};
});
},
}

View File

@@ -0,0 +1,33 @@
export default {
collection(state) {
return state.collection;
},
favourites(state, getters, rootState, rootGetters) {
return state.collection.filter(f => rootGetters["user/favourites"].map(m => m.itemId).indexOf(f._id) > -1);
},
prevArtist(state) {
let currentIndex = state.collection.indexOf(state.selectedArtist);
let prevArtist = {};
if (currentIndex > 0) {
prevArtist = state.collection[currentIndex - 1];
}
return prevArtist;
},
nextArtist(state) {
let currentIndex = state.collection.indexOf(state.selectedArtist);
let nextArtist = {};
if (state.collection.length > currentIndex + 1) {
nextArtist = state.collection[currentIndex + 1];
}
return nextArtist;
},
selectedArtist(state) {
return state.selectedArtist;
},
loading(state) {
return state.loading;
},
eos(state) {
return state.eos;
}
}

View File

@@ -0,0 +1,12 @@
import state from './state.js';
import getters from './getters.js';
import mutations from './mutations.js';
import actions from './actions.js';
export default {
namespaced: true,
state,
getters,
mutations,
actions
}

View File

@@ -0,0 +1,80 @@
export default {
clear(state) {
state.collection = [];
state.loading = false;
state.eos = false;
state.page = 1;
},
remove(state, id) {
let artist = state.collection.find(f => f._id == id);
if (artist) {
let i = state.collection.indexOf(artist);
state.collection.splice(i, 1);
}
},
resetSelectedArtist(state) {
if (state.selectedArtist._id)
state.selectedArtist = { albums: [], tracks: [], covers: {} };
},
setArtists(state, artists) {
if (artists.length == 0) {
state.eos = true;
state.loading = false;
if (state.page > 1) {
state.page--;
}
return;
}
artists.forEach(artist => {
let existsArtist = state.collection.find(f => f._id == artist._id);
if (!existsArtist) {
let item = state.collection.find((item) => {
if (item.name > artist.name) {
return item;
}
})
if (!artist.covers) {
artist.covers = {};
}
if (item) {
let index = state.collection.indexOf(item);
state.collection.splice(index, 0, artist);
} else {
state.collection.push(artist);
}
artist.albums.forEach((album) => {
album.parent = artist;
if (!album.covers) {
album.covers = {};
}
album.tracks.forEach((track) => {
track.parent = album;
track.parentType = "artist"
artist.tracks.push(track);
});
});
} else if (existsArtist && artist.albums.length > 0) {
existsArtist.tracks = [];
existsArtist.covers = artist.covers || {};
existsArtist.albums = artist.albums;
existsArtist.albums.forEach((album) => {
album.parent = existsArtist;
album.tracks.forEach((track) => {
track.parent = album;
track.parentType = "artist"
existsArtist.tracks.push(track);
});
});
}
});
state.loading = false;
},
selectArtist(state, artist) {
if (state.selectedArtist._id != artist._id) {
state.selectedArtist = artist;
}
},
}

View File

@@ -0,0 +1,7 @@
export default {
collection: [],
selectedArtist: { artists: [], tracks: [], covers: {} },
page: 1,
loading: false,
eos: false
}

View File

@@ -0,0 +1,133 @@
import axios from 'axios'
import router from '../../../router'
export default {
clear(context) {
context.commit("clear");
},
filter(context, term) {
return new Promise((resolve) => {
axios.get(context.rootGetters.server + "/api/boxes/filter/" + term, context.rootGetters.headers).then(res => {
resolve(res.data);
});
})
},
loadBoxes(context, force) {
if ((!context.state.eos || force) && !context.state.loading) {
context.state.loading = true;
axios.get(context.rootGetters.server + "/api/boxes/page/" + context.state.page++, context.rootGetters.headers).then((res) => {
context.commit("setBoxes", res.data);
});
}
},
loadFavourites(context) {
axios.get(context.rootGetters.server + "/api/boxes/favourites", context.rootGetters.headers).then(res => {
if (res.data.length > 0) {
context.commit("setBoxes", res.data);
}
});
},
loadNewest(context) {
axios.get(context.rootGetters.server + "/api/boxes/newest/6", context.rootGetters.headers).then((res) => {
context.commit("setNewest", res.data);
});
},
loadBox(context, id) {
context.state.loading = true;
axios.get(context.rootGetters.server + "/api/boxes/" + id, context.rootGetters.headers).then((res) => {
if (res.data != "") {
context.commit("setBoxes", [res.data]);
} else {
context.state.loading = false;
}
});
},
resetSelectedBox(context) {
context.commit("resetSelectedBox");
router.push("/boxes");
},
selectBox(context, box) {
if (box.videos.length == 0) {
context.dispatch("loadBox", box._id)
}
context.commit('selectBox', box);
if (!context.rootGetters.routerQuery || context.rootGetters.routerQuery.id != box._id) {
router.push("/boxes?id=" + box._id);
}
context.dispatch("preload")
},
preload(context) {
// PRELOAD NEXT AND PREV ALBUM
let next = context.getters.nextBox;
if (next._id && next.videos.length == 0) {
context.dispatch("loadBox", next._id);
}
let prev = context.getters.prevBox;
if (prev._id && prev.videos.length == 0) {
context.dispatch("loadBox", prev._id);
}
},
selectBoxById(context, id) {
let box = context.getters.collection.find(item => item._id == id);
if (box) {
context.dispatch("selectBox", box);
}
},
gotoPrevBox(context) {
let prevBox = context.getters.prevBox;
if (prevBox._id) {
context.dispatch("selectBox", prevBox);
}
},
move(context, payload) {
return new Promise((resolve) => {
axios
.put(context.rootGetters.server + "/api/boxes/" + payload.source + "/move", payload, context.rootGetters.headers)
.then(res => {
resolve(res.data);
});
})
},
remove(context, id) {
context.commit("remove", id);
},
gotoNextBox(context) {
let nextBox = context.getters.nextBox;
if (nextBox._id) {
context.dispatch("selectBox", nextBox);
}
},
updateBox(context, box) {
let body = {
_id: box._id,
visibility: box.visibility
}
axios.put(context.rootGetters.server + "/api/boxes/" + box._id, body, context.rootGetters.headers);
},
uploadNewCover(context, box) {
let input = document.createElement('input');
input.type = "file";
input.accept = "image/jpeg, image/png";
input.addEventListener("change", function () {
if (input.value) {
let formData = new FormData();
formData.append("file", input.files[0]);
let h = context.rootGetters.headers;
h.headers["content-type"] = "multipart/form-data";
axios
.put(context.rootGetters.server + "/api/boxes/" + box._id + "/cover", formData, context.rootGetters.headers)
.then(res => {
box.covers = res.data;
});
}
});
input.click();
},
resetCover(context, box) {
axios.delete(context.rootGetters.server + "/api/boxes/" + box._id + "/cover", context.rootGetters.headers).then(() => {
box.covers = {}
});
},
}

View File

@@ -0,0 +1,36 @@
export default {
collection(state) {
return state.collection;
},
favourites(state, getters, rootState, rootGetters) {
return state.collection.filter(f => rootGetters["user/favourites"].map(m => m.itemId).indexOf(f._id) > -1);
},
prevBox(state) {
let currentIndex = state.collection.indexOf(state.selectedBox);
let prevBox = {};
if (currentIndex > 0) {
prevBox = state.collection[currentIndex - 1];
}
return prevBox;
},
nextBox(state) {
let currentIndex = state.collection.indexOf(state.selectedBox);
let nextBox = {};
if (state.collection.length > currentIndex + 1) {
nextBox = state.collection[currentIndex + 1];
}
return nextBox;
},
selectedBox(state) {
return state.selectedBox;
},
loading(state) {
return state.loading;
},
eos(state) {
return state.eos;
},
newest(state) {
return state.newest;
}
}

View File

@@ -0,0 +1,12 @@
import state from './state.js';
import getters from './getters.js';
import mutations from './mutations.js';
import actions from './actions.js';
export default {
namespaced: true,
state,
getters,
mutations,
actions
}

View File

@@ -0,0 +1,74 @@
export default {
clear(state) {
state.collection = [];
state.newest = [];
state.loading = false;
state.eos = false;
state.page = 1;
},
remove(state, id) {
let box = state.collection.find(f => f._id == id);
if (box) {
let i = state.collection.indexOf(box);
state.collection.splice(i, 1);
}
},
resetSelectedBox(state) {
if (state.selectedBox._id)
state.selectedBox = { videos: [], covers: {} };
},
setBoxes(state, boxes) {
if (boxes.length == 0) {
state.eos = true;
state.loading = false;
if (state.page > 1) {
state.page--;
}
return;
}
boxes.forEach(box => {
let existsBox = state.collection.find(f => f._id == box._id);
if (!existsBox) {
let item = state.collection.find((item) => {
if (item.title > box.title) {
return item;
}
})
if (!box.covers) {
box.covers = {}
}
if (item) {
let index = state.collection.indexOf(box);
state.collection.splice(index, 0, box);
} else {
state.collection.push(box);
}
box.videos.forEach((video) => {
video.parent = box;
});
} else if (existsBox && box.videos.length > 0) {
existsBox.covers = box.covers || {};
existsBox.videos = box.videos;
existsBox.videos.forEach((video) => {
video.parent = existsBox;
});
}
});
state.loading = false;
},
selectBox(state, box) {
if (state.selectedBox._id != box._id) {
state.selectedBox = box;
}
},
setNewest(state, boxes) {
boxes.forEach(box => {
if (!box.covers) {
box.covers = {};
}
});
state.newest = boxes;
}
}

View File

@@ -0,0 +1,8 @@
export default {
collection: [],
newest: [],
selectedBox: { videos: [], covers: {} },
page: 1,
loading: false,
eos: false
}

View File

@@ -0,0 +1,33 @@
export default {
switchPlayerRepeatMode(context) {
switch (context.state.repeatType) {
case "all":
context.state.repeatType = "one";
break;
case "one":
context.state.repeatType = "none";
break;
default:
context.state.repeatType = "all";
break;
}
},
setRepeatType(context, type) {
context.state.repeatType = type;
},
setRequestReplayTrack(context) {
context.commit("requestReplayTrack");
},
toggleShuffleMode(context) {
context.commit("toggleShuffleMode");
let container = context.rootGetters["tracks/selectedTrackContainer"];
let currentTrack = context.rootGetters["tracks/selectedTrack"];
if (context.getters.shuffle && currentTrack._id) {
this.dispatch("tracks/shuffle", { container });
}
else if (container.shuffledTracks) {
delete container.shuffledTracks;
}
},
}

View File

@@ -0,0 +1,14 @@
export default {
repeatType(state) {
return state.repeatType;
},
shuffle(state) {
return state.shuffle;
},
isPlaying(state, getters, rootState, rootGetters) {
return rootGetters["tracks/selectedTrack"]._id !== undefined || rootGetters["radios/selectedRadio"]._id !== undefined;
},
requestReplayTrack(state) {
return state.requestReplayTrack;
}
}

View File

@@ -0,0 +1,12 @@
import state from './state.js';
import getters from './getters.js';
import mutations from './mutations.js';
import actions from './actions.js';
export default {
namespaced: true,
state,
getters,
mutations,
actions
}

View File

@@ -0,0 +1,8 @@
export default {
toggleShuffleMode(state) {
state.shuffle = !state.shuffle;
},
requestReplayTrack(state) {
state.requestReplayTrack = !state.requestReplayTrack;
}
}

View File

@@ -0,0 +1,5 @@
export default {
repeatType: "none",
shuffle: false,
requestReplayTrack: false
}

View File

@@ -0,0 +1,56 @@
import axios from 'axios'
import router from '../../../router'
export default {
clear(context) {
context.commit("clear");
},
loadRadios(context, force) {
if (context.state.collection.length == 0 || force) {
axios.get(context.rootGetters.server + "/api/radios", context.rootGetters.headers).then((res) => {
context.commit("setRadios", res.data);
});
}
},
play(context, radio) {
context.commit("selectRadio", radio);
if (!context.rootGetters.routerQuery || context.rootGetters.routerQuery.play != radio._id) {
router.push("/radios?play=" + radio._id);
}
},
resetSelectedRadio(context) {
context.commit("resetSelectedRadio");
router.push("/radios");
},
addRadio(context, radio) {
axios.post(context.rootGetters.server + "/api/radios", radio, context.rootGetters.headers).then(() => {
context.dispatch("loadRadios", true);
});
},
deleteRadio(context, radio) {
axios.delete(context.rootGetters.server + "/api/radios?id=" + radio._id, context.rootGetters.headers).then(() => {
context.dispatch("loadRadios", true);
});
},
updateRadio(context, radio) {
let input = document.createElement('input');
input.type = "file";
input.accept = "image/jpeg, image/png";
input.addEventListener("change", function () {
if (input.value) {
let formData = new FormData();
formData.append("file", input.files[0]);
let h = context.rootGetters.headers;
h.headers["content-type"] = "multipart/form-data";
axios.put(context.rootGetters.server + "/api/radios/" + radio._id + "/cover", formData, h).then((res) => {
radio.cover32 = res.data.cover32;
radio.cover64 = res.data.cover64;
radio.cover128 = res.data.cover128;
context.dispatch("loadRadios", true);
});
}
});
input.click();
}
}

View File

@@ -0,0 +1,8 @@
export default {
collection(state) {
return state.collection;
},
selectedRadio(state) {
return state.selectedRadio;
}
}

View File

@@ -0,0 +1,12 @@
import state from './state.js';
import getters from './getters.js';
import mutations from './mutations.js';
import actions from './actions.js';
export default {
namespaced: true,
state,
getters,
mutations,
actions
}

View File

@@ -0,0 +1,22 @@
export default {
clear(state) {
state.collection = [];
state.loading = false;
state.eos = false;
state.page = 1;
},
resetSelectedRadio(state) {
if (!state.selectedRadio._id) {
return;
}
state.selectedRadio = {};
},
selectRadio(state, radio) {
if (state.selectedRadio._id != radio._id) {
state.selectedRadio = radio;
}
},
setRadios(state, radios) {
state.collection = radios;
},
}

View File

@@ -0,0 +1,4 @@
export default {
collection: [],
selectedRadio: {},
}

View File

@@ -0,0 +1,11 @@
import axios from 'axios'
import router from '../../../router'
export default {
search(context, q) {
axios.get(context.rootGetters.server + "/api/search/" + q, context.rootGetters.headers).then((res) => {
context.commit("setResult", res.data);
});
router.push("/search?q=" + q);
},
}

View File

@@ -0,0 +1,8 @@
export default {
collection(state) {
return state.collection;
},
term(state){
return state.term;
}
}

View File

@@ -0,0 +1,12 @@
import state from './state.js';
import getters from './getters.js';
import mutations from './mutations.js';
import actions from './actions.js';
export default {
namespaced: true,
state,
getters,
mutations,
actions
}

View File

@@ -0,0 +1,16 @@
export default {
setResult(state, result) {
result.forEach(item => {
if (!item.covers) {
item.covers = {}
}
});
state.collection = result || [];
},
setTerm(state, term) {
state.term = term.trim();
if (state.term == "") {
state.collection = [];
}
}
}

View File

@@ -0,0 +1,4 @@
export default {
collection: [],
term: ""
}

View File

@@ -0,0 +1,73 @@
import axios from 'axios'
import router from '../../../router'
export default {
addUser(context, newUser) {
return new Promise((resolve) => {
axios.post(context.rootGetters.server + "/api/user", newUser, context.rootGetters.headers).then(() => {
context.dispatch("loadUsers");
resolve();
});
})
},
addUserIfNotExists(context, newUser) {
return new Promise((resolve) => {
axios.get(context.rootGetters.server + "/api/user/" + newUser.name + "/exists", context.rootGetters.headers).then((res) => {
if (res.data.exists) {
resolve(false);
} else {
context.dispatch("addUser", newUser).then(() => {
resolve(true)
});
}
});
});
},
deleteUser(context, user) {
axios.delete(context.rootGetters.server + "/api/user?id=" + user._id, context.rootGetters.headers).then((res) => {
if (res.data.length > 0) {
context.commit("setUsers", res.data);
} else {
window.location.href = "/system/setup";
}
}).catch(err => {
console.log(err.response.status);
});
},
updateUser(context, user) {
return new Promise((resolve) => {
axios.put(context.rootGetters.server + "/api/user/", user, context.rootGetters.headers).then(() => {
resolve();
});
});
},
loadUsers(context) {
axios.get(context.rootGetters.server + "/api/user", context.rootGetters.headers).then((res) => {
context.commit("setUsers", res.data);
});
},
loadRoles(context) {
return new Promise((resolve) => {
axios.get(context.rootGetters.server + "/api/settings/user/roles", context.rootGetters.headers).then((res) => {
context.commit("setRoles", res.data);
resolve();
});
});
},
loadLists(context) {
axios.get(context.rootGetters.server + "/api/settings/lists", context.rootGetters.headers).then((res) => {
context.state.lists = res.data;
});
},
createInstanceAccess(context, user) {
axios
.post(context.rootGetters.server + "/api/system/setup", user)
.then((res) => {
localStorage.setItem("token", res.data.token);
router.replace("login");
})
.catch((err) => {
console.log(err);
});
}
}

View File

@@ -0,0 +1,8 @@
export default {
users(state) {
return state.users
},
lists(state) {
return state.lists;
}
}

View File

@@ -0,0 +1,12 @@
import state from './state.js';
import getters from './getters.js';
import mutations from './mutations.js';
import actions from './actions.js';
export default {
namespaced: true,
state,
getters,
mutations,
actions
}

View File

@@ -0,0 +1,8 @@
export default {
setUsers(state, users) {
state.users = users;
},
setRoles(state, roles) {
state.roles = roles;
}
}

View File

@@ -0,0 +1,4 @@
export default {
users: [],
lists: {}
}

View File

@@ -0,0 +1,136 @@
import axios from 'axios';
import router from '../../../router'
export default {
convertNextTo(context, payload) {
let next = getNextTrack(context, payload.track);
if (next && next._id != payload.track._id) {
axios.put(context.rootGetters.server + "/api/tracks/" + next._id + "/convert/" + payload.rate, context.rootGetters.headers);
}
},
play(context, track) {
track.skipTo = 0;
track.percent = 0;
context.commit("selectTrack", track);
if (context.rootGetters.routerQuery.id == context.getters.selectedTrackContainer._id && context.rootGetters.routerQuery.play != track._id) {
switch (track.parentType) {
case "album":
router.replace("/albums?id=" + track.parent._id + "&play=" + track._id);
break;
case "artist":
router.replace("/artists?id=" + track.parent.parent._id + "&play=" + track._id);
break;
}
}
if (context.rootGetters["player/shuffle"]) {
let container = context.getters.selectedTrackContainer;
if (!container.shuffledTracks) {
context.dispatch("shuffle", { container, track });
}
}
},
playContainer(context, container) {
if (context.rootGetters["player/shuffle"]) {
context.dispatch("shuffle", { container }).then(() => {
context.dispatch("play", container.shuffledTracks[0]);
});
} else {
context.dispatch("play", container.tracks[0]);
}
},
playNextTo(context, track) {
let next = getNextTrack(context, track);
if (next) {
context.dispatch("play", next);
} else {
context.commit("resetSelectedTrack");
}
},
playPrevTo(context, track) {
let currentTime = track.duration / 100 * track.percent;
if (currentTime > 3) {
this.dispatch("player/setRequestReplayTrack");
} else {
let prev = getPrevTrack(context, track);
if (prev) {
context.dispatch("play", prev);
} else {
context.commit("resetSelectedTrack");
}
}
},
skip(context) {
context.commit("skip");
},
loadMostListened(context) {
axios.get(context.rootGetters.server + "/api/tracks/most_listened", context.rootGetters.headers)
.then((res) => {
context.commit("setMostListened", res.data);
});
},
upload(context, form) {
let h = context.rootGetters.headers;
h.headers["content-type"] = "multipart/form-data";
return new Promise((resolve, reject) => {
axios
.post(context.rootGetters.server + "/api/tracks", form, h)
.then(() => {
resolve();
})
.catch((err) => {
reject(err);
});
});
},
shuffle(context, payload) {
let container = payload.container;
let currentTrack = payload.track
return new Promise((resolve) => {
let shuffledTracks = [...container.tracks];
let j, x, i;
for (i = shuffledTracks.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = shuffledTracks[i];
shuffledTracks[i] = shuffledTracks[j];
shuffledTracks[j] = x;
}
if (currentTrack) {
let currentIndex = shuffledTracks.indexOf(currentTrack);
if (currentIndex > 0) {
let tmp = shuffledTracks[currentIndex];
shuffledTracks[currentIndex] = shuffledTracks[0];
shuffledTracks[0] = tmp;
currentIndex = shuffledTracks.indexOf(currentTrack);
}
}
container.shuffledTracks = shuffledTracks;
resolve();
});
}
}
function getNextTrack(context, track) {
if (context.rootGetters["player/repeatType"] == "one") {
return track;
}
let container = context.getters.selectedTrackContainer
let tracks = container.shuffledTracks || container.tracks;
let currentIndex = tracks.indexOf(track)
if (currentIndex < tracks.length - 1) {
return tracks[currentIndex + 1];
} else if (context.rootGetters["player/repeatType"] == "all") {
return tracks[0];
}
return undefined
}
function getPrevTrack(context, track) {
let container = context.getters.selectedTrackContainer
let tracks = container.shuffledTracks || container.tracks;
let currentIndex = tracks.indexOf(track)
if (currentIndex > 0) {
return tracks[currentIndex - 1];
}
return undefined;
}

View File

@@ -0,0 +1,14 @@
export default {
selectedTrack(state) {
return state.selectedTrack;
},
selectedTrackContainer(state) {
if (state.selectedTrack.parent.parent && state.selectedTrack.parent.parent.tracks) {
return state.selectedTrack.parent.parent
}
return state.selectedTrack.parent;
},
mostListened(state) {
return state.mostListened;
}
}

View File

@@ -0,0 +1,12 @@
import state from './state.js';
import getters from './getters.js';
import mutations from './mutations.js';
import actions from './actions.js';
export default {
namespaced: true,
state,
getters,
mutations,
actions
}

View File

@@ -0,0 +1,17 @@
export default {
selectTrack(state, track) {
state.selectedTrack = track;
},
resetSelectedTrack(state) {
if (!state.selectedTrack._id) {
return;
}
state.selectedTrack = { title: "", parent: { title: "", covers: {} } };
},
skip(state) {
state.selectedTrack.skipTo = state.selectedTrack.percent;
},
setMostListened(state, tracks) {
state.mostListened = tracks;
}
}

View File

@@ -0,0 +1,6 @@
export default {
selectedTrack: {
title: "", parent: { title: "", covers: {} }
},
mostListened: []
}

View File

@@ -0,0 +1,125 @@
import axios from 'axios'
import router from '../../../router'
export default {
cleanHistory(context) {
axios.delete(context.rootGetters.server + "/api/user/history", context.rootGetters.headers).then(() => {
context.getters["user/history"] = [];
});
},
load(context) {
return new Promise((resolve, reject) => {
axios.get(context.rootGetters.server + "/api/user/login", context.rootGetters.headers).then((res) => {
context.commit("load", res.data);
context.rootState["player"].shuffle = res.data.player.shuffle;
context.rootState["player"].repeatType = res.data.player.repeat;
resolve();
}).catch(err => {
context.commit("resetToken");
reject(err);
});
});
},
login(context, user) {
return new Promise((resolve, reject) => {
axios.post(context.rootGetters.server + "/api/user/login", {
username: user.username,
password: user.password,
})
.then((res) => {
context.commit("load", res.data);
context.dispatch("setToken", res.data.token).then(() => {
resolve();
});
})
.catch((err) => {
context.commit("resetToken");
reject(err.response);
});
});
},
logout(context) {
context.commit("resetToken");
localStorage.setItem("token", "");
router.push("/login")
this.dispatch("albums/clear");
this.dispatch("artists/clear");
this.dispatch("boxes/clear");
this.dispatch("radios/clear");
this.commit("tracks/resetSelectedTrack");
this.commit("radios/resetSelectedRadio");
this.commit("videos/resetSelectedVideo");
},
toggleFavourite(context, item) {
let fav = context.state.favourites;
let f = fav.find(f => f.itemId == item.itemId);
if (f == undefined) {
axios.post(context.rootGetters.server + "/api/user/favourites", item, context.rootGetters.headers);
fav.push(item);
} else {
axios.delete(context.rootGetters.server + "/api/user/favourites?itemId=" + item.itemId, context.rootGetters.headers);
fav.splice(fav.indexOf(f), 1);
}
},
setToken(context, token) {
return new Promise((resolve) => {
localStorage.setItem("token", token);
context.commit("setToken", token);
resolve();
});
},
saveHistoryItem(context, item) {
if (context.state._id == -1) {
return;
}
axios
.post(context.rootGetters.server + "/api/user/history", item, context.rootGetters.headers)
.then((res) => {
context.commit("setHistory", res.data);
});
},
savePlayerSettings(context) {
let body = {
repeat: context.rootGetters["player/repeatType"],
shuffle: context.rootGetters["player/shuffle"]
};
axios
.put(context.rootGetters.server + "/api/user/settings", body, context.rootGetters.headers);
},
update(context, user) {
return new Promise((resolve, reject) => {
axios.post(
context.rootGetters.server + "/api/user/update",
{
oldPassword: user.oldPass,
newPassword: user.newPass,
},
context.rootGetters.headers
).then((res) => {
resolve(res);
}).catch((err) => {
reject(err);
});
});
},
updateConfig(context) {
axios.post(context.rootGetters.server + "/api/user/update",
{
mobile_bpm: context.getters["settings"].mobile_bpm,
desktop_bpm: context.getters["settings"].desktop_bpm,
video_lang: context.getters["settings"].video_lang,
video_quality: context.getters["settings"].video_quality,
fullname: context.getters.user.fullname,
},
context.rootGetters.headers
);
},
useGuestAccount(context) {
return new Promise((resolve) => {
context.commit("setGuestAccount");
resolve();
})
}
}

View File

@@ -0,0 +1,29 @@
export default {
favourites(state) {
return state.favourites;
},
history(state) {
return state.history;
},
roles(state) {
return state.roles;
},
settings(state) {
return state.settings;
},
token(state) {
return state.token;
},
user(state) {
return state;
},
isGuest(state) {
return state._id == -1;
},
isAdministrator(state) {
return state.roles.includes("admin");
},
isModerator(state) {
return state.roles.includes("admin") || state.roles.includes("moderator");
},
}

View File

@@ -0,0 +1,12 @@
import state from './state.js';
import getters from './getters.js';
import mutations from './mutations.js';
import actions from './actions.js';
export default {
namespaced: true,
state,
getters,
mutations,
actions
}

View File

@@ -0,0 +1,41 @@
export default {
load(state, user) {
user.history.forEach(item => {
item._id = item.id;
})
state.settings.mobile_bpm = user.mobile_bpm;
state.settings.desktop_bpm = user.desktop_bpm;
state.settings.video_lang = user.video_lang;
state.settings.video_quality = user.video_quality;
state.name = user.name;
state.roles = user.roles;
state.favourites = user.favourites;
state.history = user.history;
state._id = user._id;
},
resetToken(state) {
state.token = "";
},
setToken(state, token) {
state.token = token;
},
setHistory(state, history) {
history.forEach(item => {
item._id = item.id;
});
state.history = history;
},
setSettings(state, settings) {
state.settings = settings;
},
setGuestAccount(state) {
state.settings.mobile_bpm = 64;
state.settings.desktop_bpm = 128;
state.settings.video_lang = "ENG";
state.settings.video_quality = "realtime";
state.name = 'Guest';
state.roles = ['guest'];
state.history = [];
state._id = "-1";
}
}

View File

@@ -0,0 +1,13 @@
export default {
favourites: [],
history: [],
roles: [],
token: "",
name: "",
settings: {
mobile_bpm: 0,
desktop_bpm: 0,
video_lang: "ENG",
video_quality: "480"
}
}

View File

@@ -0,0 +1,59 @@
import axios from 'axios'
import router from '../../../router'
export default {
play(context, video) {
context.commit("selectVideo", video);
if (context.rootGetters.routerQuery.play != video._id) {
router.push("/boxes?id=" + video.parent._id + "&play=" + video._id);
}
},
playContainer(context, container) {
context.dispatch("play", container.videos[0]);
},
playNextTo(context, video) {
context.commit("resetSelectedVideo");
let currentIndex = video.parent.videos.indexOf(video);
if (currentIndex < video.parent.videos.length - 1) {
context.dispatch("play", video.parent.videos[currentIndex + 1]);
}
},
convertNextTo(context, payload) {
let currentIndex = payload.video.parent.videos.indexOf(payload.video);
if (currentIndex < payload.video.parent.videos.length - 1) {
let nextVideo = payload.video.parent.videos[currentIndex + 1]
axios.get(context.rootGetters.server + "/api/videos/" + nextVideo._id + "/convert/" + (context.rootGetters["user/settings"].video_quality || "realtime") + "/" + payload.langIndex).then(() => {
console.log("Pre Convert started for: " + nextVideo.title);
});
}
},
resetSelectedVideo(context) {
if (!context.getters.selectedVideo._id) {
return;
}
let box_id = context.getters.selectedVideo.parent._id;
context.commit("resetSelectedVideo");
if (context.rootGetters.routerQuery.play)
router.push("/boxes?id=" + box_id);
},
upload(context, form) {
let h = context.rootGetters.headers;
h.headers["content-type"] = "multipart/form-data";
return new Promise((resolve, reject) => {
axios
.post(context.rootGetters.server + "/api/videos", form, h)
.then(() => {
resolve();
})
.catch((err) => {
reject(err);
});
});
},
loadMostViewed(context) {
axios.get(context.rootGetters.server + "/api/videos/most_viewed", context.rootGetters.headers)
.then((res) => {
context.commit("setMostViewed", res.data);
});
},
}

View File

@@ -0,0 +1,11 @@
export default {
selectedVideo(state) {
return state.selectedVideo;
},
getStreamUrl(state, getters, rootState, rootGetters) {
return rootGetters.server + "/api/videos/" + state.selectedVideo._id + "/stream/" + (rootGetters["user/settings"].video_quality || "realtime") + "/"
},
mostViewed(state) {
return state.mostViewed;
}
}

View File

@@ -0,0 +1,12 @@
import state from './state.js';
import getters from './getters.js';
import mutations from './mutations.js';
import actions from './actions.js';
export default {
namespaced: true,
state,
getters,
mutations,
actions
}

View File

@@ -0,0 +1,14 @@
export default {
selectVideo(state, video) {
state.selectedVideo = video;
},
resetSelectedVideo(state) {
if (!state.selectedVideo._id) {
return;
}
state.selectedVideo = { tracks: [] };
},
setMostViewed(state, tracks) {
state.mostViewed = tracks;
}
}

View File

@@ -0,0 +1,4 @@
export default {
selectedVideo: { tracks: [] },
mostViewed: []
}

29
src/store/mutations.js Normal file
View File

@@ -0,0 +1,29 @@
export default {
resetViewMenu(state) {
state.viewMenu = [];
},
searchFilter(state, term) {
state.searchFilter = term;
},
setServer(state, server) {
state.server = server;
},
setSystemSettings(state, payload) {
state.serverConfig.allows = payload;
},
setViewMenu(state, menuItems) {
state.viewMenu = menuItems || [];
},
setServerConfig(state, config) {
state.serverConfig = config;
},
setServerConfigAllows(state, allows) {
state.serverConfig.allows = allows;
},
setSystemConfigDomains(state, domains) {
state.serverConfig.domains = domains;
},
setServerInfo(state, info) {
state.serverInfo = info;
}
}

20
src/store/state.js Normal file
View File

@@ -0,0 +1,20 @@
export default {
serverStatus: { scanning_music: false, scanning_video: false },
searchFilter: "",
systemDialog: false,
viewMenu: [],
clientConfig: {
server: "none",
isElectron: false
},
serverConfig: { allows: {}, domains: [] },
serverInfo: {
stats: {
albums: 0,
tracks: 0,
videos: 0,
users: 0
}
}
}