diff --git a/SettingsHelper.js b/SettingsHelper.js
index 8127ca28..aace8042 100644
--- a/SettingsHelper.js
+++ b/SettingsHelper.js
@@ -1,7 +1,6 @@
const args = require('args-parser')(process.argv);
const { coalesce } = require('./src/utils/helpers');
-const { defaultSettings } = require('./src/defaultsettings');
const readSettingsFile = (file) => {
try {
@@ -88,31 +87,31 @@ const fields = [
{
local: 'autoplay',
env: 'AUTOPLAY',
- default: defaultSettings.autoplay,
+ default: true,
type: 'boolean',
},
{
local: 'clientPollInterval',
env: 'CLIENTPOLLINTERVAL',
- default: defaultSettings.clientPollInterval,
+ default: 1000,
type: 'number',
},
{
local: 'syncMode',
env: 'SYNCMODE',
- default: defaultSettings.syncMode,
+ default: 'cleanseek',
type: 'string',
},
{
local: 'syncFlexibility',
env: 'SYNCFLEXIBILITY',
- default: defaultSettings.syncFlexibility,
+ default: 3000,
type: 'number',
},
{
local: 'slPlayerQuality',
env: 'SLPLAYERQUALITY',
- default: defaultSettings.slPlayerQuality,
+ default: null,
type: 'number',
// null is allowed because null quality indicates Original
nullable: true,
@@ -121,13 +120,19 @@ const fields = [
// Valid values are in the range [0, 1]
local: 'slPlayerVolume',
env: 'SLPLAYERVOLUME',
- default: defaultSettings.slPlayerVolume,
+ default: 1,
type: 'number',
},
{
local: 'slPlayerForceTranscode',
env: 'SLPLAYERFORCETRANSCODE',
- default: defaultSettings.slPlayerForceTranscode,
+ default: false,
+ type: 'boolean',
+ },
+ {
+ local: 'fetchConfig',
+ env: 'FETCH_CONFIG',
+ default: false,
type: 'boolean',
},
];
diff --git a/src/App.vue b/src/App.vue
index c94f1986..0959000a 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -102,16 +102,18 @@
fluid
>
- {{ configError }}
+ Failed to fetch config: {{ GET_CONFIGURATION_FETCHED_ERROR }}
{
this.snackbarMsg = msg;
this.snackbar = true;
@@ -433,22 +410,28 @@ export default {
this.appIsFullscreen = isFullscreen;
document.body.classList.toggle('is-fullscreen', isFullscreen);
});
-
- this.loading = false;
},
created() {
- this.configFetchPromise = this.fetchConfig();
+ if (this.GET_CONFIG.fetchConfig) {
+ this.FETCH_CONFIG();
+ }
+
+ if (this.IS_AUTHENTICATED) {
+ // Kick off a bunch of requests that we need for later
+ this.FETCH_PLEX_USER();
+ this.FETCH_PLEX_DEVICES_IF_NEEDED();
+ }
},
methods: {
- ...mapActions('config', ['fetchConfig']),
...mapActions([
'SET_LEFT_SIDEBAR_OPEN',
'SET_RIGHT_SIDEBAR_OPEN',
'TOGGLE_RIGHT_SIDEBAR_OPEN',
'FETCH_PLEX_DEVICES_IF_NEEDED',
'FETCH_PLEX_USER',
+ 'FETCH_CONFIG',
]),
sendNotification() {
diff --git a/src/components/autojoin.vue b/src/components/autojoin.vue
new file mode 100644
index 00000000..00e4a283
--- /dev/null
+++ b/src/components/autojoin.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+ Unable to autojoin
+
+
+
+ Welcome to SyncLounge
+
+
+
+
+
+ Join
+
+
+
+
+
+
+
+
+
diff --git a/src/defaultsettings.js b/src/defaultsettings.js
deleted file mode 100644
index 37e49c49..00000000
--- a/src/defaultsettings.js
+++ /dev/null
@@ -1,11 +0,0 @@
-module.exports = {
- defaultSettings: {
- autoplay: true,
- clientPollInterval: 1000,
- syncMode: 'cleanseek',
- syncFlexibility: 3000,
- slPlayerForceTranscode: false,
- slPlayerQuality: null,
- slPlayerVolume: 1,
- },
-};
diff --git a/src/main.js b/src/main.js
index 70d9585c..d98552e8 100644
--- a/src/main.js
+++ b/src/main.js
@@ -50,24 +50,28 @@ window.EventBus.$on('command', (data) => {
});
router.beforeEach((to, from, next) => {
- // console.log('Route change', to, this, store)
- if (to.matched.some((record) => record.meta.protected)) {
+ if (!store.getters.IS_AUTHENTICATED && to.matched.some((record) => record.meta.requiresAuth)) {
+ if (to.matched.some((record) => record.meta.redirectAfterAuth)) {
+ next({
+ path: '/signin',
+ query: {
+ redirect: to.fullPath,
+ },
+ });
+ } else {
+ next('/signin');
+ }
+ } else if (store.getters.GET_CONFIG.autoJoin
+ && to.matched.some((record) => record.meta.noAutoJoin)) {
+ next('/autojoin');
+ } else if (!store.getters.getRoom && to.matched.some((record) => record.meta.protected)) {
// this route requires us to be in a room with a client selected
// if not, redirect to the needed stage
- if (!store.getters.getRoom) {
- return next({
- path: '/',
- });
- }
- next();
- } else {
- if (!to.meta.protected) {
- return next();
- }
- router.push('/browse');
- }
- return null;
+ next('/');
+ } else {
+ next();
+ }
});
new Vue({
diff --git a/src/router/index.js b/src/router/index.js
index e6edd8bd..d0120b06 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -6,34 +6,12 @@ Vue.use(Router);
// Good guide: https://blog.sqreen.com/authentication-best-practices-vue/
-
-// const ifNotAuthenticated = (to, from, next) => {
-// if (!store.getters.IS_AUTHENTICATED) {
-// next();
-// return;
-// }
-// next('/');
-// };
-
-const ifAuthenticated = (to, from, next) => {
- if (store.getters.IS_AUTHENTICATED) {
+const requireAutoJoinEnabled = (to, from, next) => {
+ if (store.getters.GET_CONFIG.autoJoin) {
next();
return;
}
- next('/signin');
-};
-
-const ifAuthenticatedWithRedirect = (to, from, next) => {
- if (store.getters.IS_AUTHENTICATED) {
- next();
- return;
- }
- next({
- path: '/signin',
- query: {
- redirect: to.fullPath,
- },
- });
+ next('/');
};
// ==================== Router registration ====================
@@ -45,7 +23,10 @@ export default new Router({
path: '/',
component: () => import('../components/createroom.vue'),
name: 'CreateRoom',
- beforeEnter: ifAuthenticated,
+ meta: {
+ requiresAuth: true,
+ noAutoJoin: true,
+ },
},
{
path: '/signin',
@@ -55,132 +36,145 @@ export default new Router({
},
{
path: '/signout',
- meta: {},
component: () => import('../components/signout.vue'),
- beforeEnter: ifAuthenticated,
+ meta: {
+ requiresAuth: true,
+ },
+ },
+ {
+ path: '/autojoin',
+ meta: {
+ requiresAuth: true,
+ redirectAfterAuth: true,
+ },
+ component: () => import('../components/autojoin.vue'),
+ name: 'autojoin',
+ beforeEnter: requireAutoJoinEnabled,
},
{
path: '/join/:server/:room',
meta: {
+ noAutoJoin: true,
+ redirectAfterAuth: true,
},
component: () => import('../components/join.vue'),
props: true,
name: 'join',
- beforeEnter: ifAuthenticatedWithRedirect,
},
{
path: '/clientselect',
- meta: {
- },
component: () => import('../components/application/walkthrough.vue'),
- beforeEnter: ifAuthenticated,
+ meta: {
+ requiresAuth: true,
+ },
},
{
path: '/clientpicker',
- meta: {
- },
name: 'ClientPicker',
component: () => import('../components/clientpicker.vue'),
- beforeEnter: ifAuthenticated,
+ meta: {
+ requiresAuth: true,
+ },
},
{
path: '/joinroom',
- meta: {
- },
component: () => import('../components/application/joinroom.vue'),
- beforeEnter: ifAuthenticated,
+ meta: {
+ requiresAuth: true,
+ noAutoJoin: true,
+ },
},
{
path: '/player',
meta: {
+ requiresAuth: true,
protected: true,
},
component: () => import('../components/application/slplayer.vue'),
- beforeEnter: ifAuthenticated,
},
{
path: '/nowplaying/:machineIdentifier/:ratingKey',
meta: {
+ requiresAuth: true,
protected: true,
},
name: 'nowplaying',
component: () => import('../components/application/plexbrowser/plexcontent.vue'),
- beforeEnter: ifAuthenticated,
},
{
path: '/browse',
meta: {
+ requiresAuth: true,
protected: true,
},
name: 'browse',
component: () => import('../components/application/plexbrowser.vue'),
- beforeEnter: ifAuthenticated,
},
{
path: '/browse/:machineIdentifier',
meta: {
+ requiresAuth: true,
protected: true,
},
name: 'server',
component: () => import('../components/application/plexbrowser/plexserver.vue'),
- beforeEnter: ifAuthenticated,
},
{
path: '/browse/:machineIdentifier/:sectionId',
meta: {
+ requiresAuth: true,
protected: true,
},
name: 'library',
component: () => import('../components/application/plexbrowser/plexlibrary.vue'),
- beforeEnter: ifAuthenticated,
},
{
path: '/browse/:machineIdentifier/:sectionId/:ratingKey',
meta: {
+ requiresAuth: true,
protected: true,
},
name: 'content',
component: () => import('../components/application/plexbrowser/plexcontent.vue'),
- beforeEnter: ifAuthenticated,
},
{
path: '/browse/:machineIdentifier/:sectionId/tv/:ratingKey',
meta: {
+ requiresAuth: true,
protected: true,
},
name: 'series',
component: () => import('../components/application/plexbrowser/plexseries.vue'),
- beforeEnter: ifAuthenticated,
},
{
path: '/browse/:machineIdentifier/:sectionId/tv/:parentKey/:ratingKey',
meta: {
+ requiresAuth: true,
protected: true,
},
name: 'season',
component: () => import('../components/application/plexbrowser/plexseason.vue'),
- beforeEnter: ifAuthenticated,
},
{
path:
'/browse/:machineIdentifier/:sectionId/tv/:grandparentKey/:parentKey/:ratingKey',
meta: {
+ requiresAuth: true,
protected: true,
},
name: 'contentspecific',
component: () => import('../components/application/plexbrowser/plexcontent.vue'),
- beforeEnter: ifAuthenticated,
},
{
path:
'/browse/:machineIdentifier/tv/:grandparentKey/:parentKey/:ratingKey',
meta: {
+ requiresAuth: true,
protected: true,
},
name: 'contentnosection',
component: () => import('../components/application/plexbrowser/plexcontent.vue'),
- beforeEnter: ifAuthenticated,
},
],
});
diff --git a/src/store/actions.js b/src/store/actions.js
index 995ded35..c2485658 100644
--- a/src/store/actions.js
+++ b/src/store/actions.js
@@ -1,5 +1,8 @@
+import axios from 'axios';
+
import delay from '@/utils/delay';
+
function sendNotification(message) {
return window.EventBus.$emit('notification', message);
}
@@ -195,4 +198,16 @@ export default {
commit('SET_BACKGROUND', result);
}
},
+
+ FETCH_CONFIG: async ({ commit }) => {
+ const url = window.location.origin + window.location.pathname.replace(/\/+$/, '');
+ try {
+ const { data } = await axios.get(`${url}/config`);
+ commit('SET_CONFIG', data);
+ } catch (e) {
+ commit('SET_CONFIGURATION_FETCH_ERROR', e);
+ }
+
+ commit('SET_CONFIGURATION_FETCHED', true);
+ },
};
diff --git a/src/store/getters.js b/src/store/getters.js
index aae591b5..500b1a6f 100644
--- a/src/store/getters.js
+++ b/src/store/getters.js
@@ -5,10 +5,6 @@ export default {
getShownChat: (state) => state.shownChat,
getStats: (state) => state.stats,
getBlockAutoPlay: (state) => state.blockAutoPlay,
- getAutoJoin: (state) => state.autoJoin,
- getAutoJoinRoom: (state) => state.autoJoinRoom,
- getAutoJoinPassword: (state) => state.autoJoinPassword,
- getAutoJoinUrl: (state) => state.autoJoinUrl,
// SETTINGS
getExtAvailable: (state) => state.extAvailable,
@@ -32,4 +28,8 @@ export default {
GET_UP_NEXT_TRIGGERED: (state) => state.upNextTriggered,
GET_UP_NEXT_POST_PLAY_DATA: (state) => state.upNextPostPlayData,
GET_PLEX_SERVER_ID: (state) => state.plexServerId,
+ GET_CONFIG: (state) => state.configuration,
+ GET_AUTHENTICATION: (state) => state.configuration.authentication,
+ GET_CONFIGURATION_FETCHED: (state) => state.configurationFectched,
+ GET_CONFIGURATION_FETCHED_ERROR: (state) => state.configurationFetchedError,
};
diff --git a/src/store/index.js b/src/store/index.js
index de4e6f52..e34dc44f 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -8,7 +8,6 @@ import mutations from './mutations';
import getters from './getters';
import synclounge from './modules/synclounge';
-import config from './modules/config/config.store';
import settings from './modules/settings';
import plex from './modules/plex';
import slplayer from './modules/slplayer';
@@ -31,7 +30,6 @@ const store = new Vuex.Store({
modules: {
synclounge,
plex,
- config,
settings,
slplayer,
},
diff --git a/src/store/modules/config/config.store.js b/src/store/modules/config/config.store.js
deleted file mode 100644
index 553eba80..00000000
--- a/src/store/modules/config/config.store.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import axios from 'axios';
-
-const initialState = () => ({
- configuration: {},
-});
-
-const getters = {
- GET_CONFIG: (state) => state.configuration,
- GET_AUTHENTICATION: (state) => state.configuration.authentication,
-};
-
-const mutations = {
- SET_CONFIG: (state, data) => {
- state.configuration = data;
- },
- SET_AUTHENTICATION: (state, auth) => {
- state.configuration.authentication = auth;
- },
-};
-
-const actions = {
- fetchConfig: async ({ commit }) => {
- const url = window.location.origin + window.location.pathname.replace(/\/+$/, '');
- return axios.get(`${url}/config`).then(({ data }) => {
- commit('SET_CONFIG', data);
- });
- },
-};
-
-export default {
- namespaced: true,
- state: initialState,
- mutations,
- actions,
- getters,
-};
diff --git a/src/store/modules/settings/getters.js b/src/store/modules/settings/getters.js
index 8886bca8..27da9ee4 100644
--- a/src/store/modules/settings/getters.js
+++ b/src/store/modules/settings/getters.js
@@ -1,37 +1,44 @@
-const { defaultSettings } = require('@/defaultsettings');
+
const { coalesce } = require('@/utils/helpers');
// Use stored value if not null, othewise fallback to config, then default values
export default {
- GET_AUTOPLAY: (state, getters, rootState, rootGetters) => coalesce(state.autoplay, rootGetters['config/GET_CONFIG'].autoplay, defaultSettings.autoplay),
+ GET_AUTOPLAY: (state, getters, rootState, rootGetters) => coalesce(state.autoplay,
+ rootGetters.GET_CONFIG.autoplay),
+
GET_CLIENTPOLLINTERVAL: (state, getters, rootState, rootGetters) => coalesce(
state.clientPollInterval,
- rootGetters['config/GET_CONFIG'].clientPollInterval,
- defaultSettings.clientPollInterval,
+ rootGetters.GET_CONFIG.clientPollInterval,
+
),
- GET_SYNCMODE: (state, getters, rootState, rootGetters) => coalesce(state.syncMode, rootGetters['config/GET_CONFIG'].syncMode, defaultSettings.syncMode),
+ GET_SYNCMODE: (state, getters, rootState, rootGetters) => coalesce(state.syncMode,
+ rootGetters.GET_CONFIG.syncMode),
+
GET_SYNCFLEXIBILITY: (state, getters, rootState, rootGetters) => coalesce(
state.syncFlexibility,
- rootGetters['config/GET_CONFIG'].syncFlexibility,
- defaultSettings.syncFlexibility,
+ rootGetters.GET_CONFIG.syncFlexibility,
),
- GET_CUSTOMSERVER: (state, getters, rootState, rootGetters) => coalesce(state.customServer, rootGetters['config/GET_CONFIG'].customServer),
+
+ GET_CUSTOMSERVER: (state, getters, rootState, rootGetters) => coalesce(state.customServer,
+ rootGetters.GET_CONFIG.customServer),
+
GET_BLOCKEDSERVERS: (state) => state.blockedServers,
GET_SLPLAYERQUALITY: (state, getters, rootState, rootGetters) => coalesce(
state.slPlayerQuality,
- rootGetters['config/GET_CONFIG'].slPlayerQuality,
- defaultSettings.slPlayerQuality,
+ rootGetters.GET_CONFIG.slPlayerQuality,
+
) || null,
+
GET_SLPLAYERVOLUME: (state, getters, rootState, rootGetters) => coalesce(
state.slPlayerVolume,
- rootGetters['config/GET_CONFIG'].slPlayerVolume,
- defaultSettings.slPlayerVolume,
+ rootGetters.GET_CONFIG.slPlayerVolume,
),
+
GET_SLPLAYERFORCETRANSCODE: (state, getters, rootState, rootGetters) => coalesce(
state.slPlayerForceTranscode,
- rootGetters['config/GET_CONFIG'].slPlayerForceTranscode,
- defaultSettings.slPlayerForceTranscode,
+ rootGetters.GET_CONFIG.slPlayerForceTranscode,
),
+
GET_HIDEUSERNAME: (state) => state.hideUsername,
GET_ALTUSERNAME: (state) => state.altUsername,
GET_CLIENTIDENTIFIER: (state) => state.clientIdentifier,
diff --git a/src/store/modules/synclounge/actions.js b/src/store/modules/synclounge/actions.js
index bdbac42a..9744a037 100644
--- a/src/store/modules/synclounge/actions.js
+++ b/src/store/modules/synclounge/actions.js
@@ -523,4 +523,10 @@ export default {
room: guid(),
});
},
+
+ JOIN_CONFIG_SYNCLOUNGE_SERVER: ({ rootGetters, dispatch }) => dispatch('autoJoin', {
+ server: rootGetters.GET_CONFIG.autoJoinServer,
+ room: rootGetters.GET_CONFIG.autoJoinRoom,
+ password: rootGetters.GET_CONFIG.autoJoinPassword,
+ }),
};
diff --git a/src/store/modules/synclounge/getters.js b/src/store/modules/synclounge/getters.js
index 4ae700b9..c8a1fde4 100644
--- a/src/store/modules/synclounge/getters.js
+++ b/src/store/modules/synclounge/getters.js
@@ -36,17 +36,17 @@ export default {
GET_SYNCLOUNGE_SERVERS: (state, getters, rootState, rootGetters) => {
- if (rootGetters['config/GET_CONFIG'].servers && rootGetters['config/GET_CONFIG'].servers.length > 0) {
- if (rootGetters['config/GET_CONFIG'].customServer) {
+ if (rootGetters.GET_CONFIG.servers && rootGetters.GET_CONFIG.servers.length > 0) {
+ if (rootGetters.GET_CONFIG.customServer) {
console.error(
"'customServer' setting provided with 'servers' setting. Ignoring 'customServer' setting.",
);
}
- return rootGetters['config/GET_CONFIG'].servers;
+ return rootGetters.GET_CONFIG.servers;
}
- if (rootGetters['config/GET_CONFIG'].customServer) {
- return defaultSyncloungeServers.concat([rootGetters['config/GET_CONFIG'].customServer]);
+ if (rootGetters.GET_CONFIG.customServer) {
+ return defaultSyncloungeServers.concat([rootGetters.GET_CONFIG.customServer]);
}
return defaultSyncloungeServers.concat([rootGetters['settings/GET_CUSTOMSERVER']]);
diff --git a/src/store/mutations.js b/src/store/mutations.js
index e16bc167..4f67f4c1 100644
--- a/src/store/mutations.js
+++ b/src/store/mutations.js
@@ -1,24 +1,9 @@
import Vue from 'vue';
export default {
- SET_PLEX(state, value) {
- state.plex = value;
- },
- SET_AUTOJOIN(state, value) {
- state.autoJoin = value;
- },
SET_BACKGROUND(state, value) {
state.background = value;
},
- SET_AUTOJOINROOM(state, value) {
- state.autoJoinRoom = value;
- },
- SET_AUTOJOINPASSWORD(state, value) {
- state.autoJoinPassword = value;
- },
- SET_AUTOJOINURL(state, value) {
- state.autoJoinUrl = value;
- },
SET_VALUE(state, data) {
const [key, value] = data;
@@ -46,4 +31,16 @@ export default {
SET_PLEX_SERVER_ID: (state, id) => {
state.plexServerId = id;
},
+
+ SET_CONFIG: (state, data) => {
+ state.configuration = data;
+ },
+
+ SET_CONFIGURATION_FETCHED: (state, fetched) => {
+ state.configurationFetcehd = fetched;
+ },
+
+ SET_CONFIGURATION_FETCH_ERROR: (state, error) => {
+ state.configurationFetchError = error;
+ },
};
diff --git a/src/store/state.js b/src/store/state.js
index 83850aa9..0d2f0c21 100644
--- a/src/store/state.js
+++ b/src/store/state.js
@@ -6,16 +6,14 @@ const state = () => ({
background: null,
shownChat: false,
blockAutoPlay: false,
- autoJoin: false,
- autoJoinUrl: null,
- autoJoinRoom: null,
- autoJoinPassword: null,
- autoJoinUsername: null,
extAvailable: false,
lastRatingKey: null,
manualSyncQueued: false,
uuid: guid(),
upNextCache: {},
+ configuration: JSON.parse(process.env.VUE_APP_CONFIGURATION),
+ configurationFetched: false,
+ configurationFetchError: false,
// SETTINGS
stats: {},
diff --git a/vue.config.js b/vue.config.js
index 54e2a30a..c716cbce 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -4,6 +4,8 @@ const { readSettings } = require('./SettingsHelper');
const settings = readSettings();
+process.env.VUE_APP_CONFIGURATION = JSON.stringify(settings);
+
process.env.VUE_APP_VERSION = require('./package.json').version;
module.exports = {