diff --git a/package-lock.json b/package-lock.json
index 3fe64ba..ce4e890 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,7 +11,7 @@
"dependencies": {
"@apollo/client": "^3.7.17",
"@github/time-elements": "^3.1.2",
- "@ropescore/components": "file:../components/ropescore-components-1.6.1.tgz",
+ "@ropescore/components": "^1.6.3",
"@sentry/tracing": "^7.57.0",
"@sentry/vue": "^7.57.0",
"@vue/apollo-composable": "^4.0.0-beta.8",
@@ -4512,10 +4512,9 @@
"dev": true
},
"node_modules/@ropescore/components": {
- "version": "1.6.1",
- "resolved": "file:../components/ropescore-components-1.6.1.tgz",
- "integrity": "sha512-vo8p/FxU12QocTS0i1WhTo7a0UK3T2+RXQUjqiw/WQyYXZfyK1MV1/aB+AZakkCi1gTTxOEfgKfwjX3zWePcHQ==",
- "license": "MIT",
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/@ropescore/components/-/components-1.6.3.tgz",
+ "integrity": "sha512-sfiW6P3OKtPAZ3h28i71jCrwORP9c+uAtCaElnW+ajVVV6z7lUAYC6Qy4RfYH+J3UVEp2k7bzmGnRt+NIplymw==",
"dependencies": {
"uuid": "^9.0.0"
}
@@ -14877,8 +14876,9 @@
"dev": true
},
"@ropescore/components": {
- "version": "file:../components/ropescore-components-1.6.1.tgz",
- "integrity": "sha512-vo8p/FxU12QocTS0i1WhTo7a0UK3T2+RXQUjqiw/WQyYXZfyK1MV1/aB+AZakkCi1gTTxOEfgKfwjX3zWePcHQ==",
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/@ropescore/components/-/components-1.6.3.tgz",
+ "integrity": "sha512-sfiW6P3OKtPAZ3h28i71jCrwORP9c+uAtCaElnW+ajVVV6z7lUAYC6Qy4RfYH+J3UVEp2k7bzmGnRt+NIplymw==",
"requires": {
"uuid": "^9.0.0"
}
diff --git a/package.json b/package.json
index f34ae9e..655e29a 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
"dependencies": {
"@apollo/client": "^3.7.17",
"@github/time-elements": "^3.1.2",
- "@ropescore/components": "file:../components/ropescore-components-1.6.1.tgz",
+ "@ropescore/components": "^1.6.3",
"@sentry/tracing": "^7.57.0",
"@sentry/vue": "^7.57.0",
"@vue/apollo-composable": "^4.0.0-beta.8",
diff --git a/src/App.vue b/src/App.vue
index 39f9970..15d16bd 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -2,14 +2,14 @@
-
+
RopeScore Live
@@ -32,11 +32,14 @@
+
-
+
+
+
© Swantzter 2018-2023
{{ version }}
@@ -49,6 +52,7 @@ import { useRoute } from 'vue-router'
import { useLocalStorage } from '@vueuse/core'
import { ButtonLink, TextButton } from '@ropescore/components'
+import SystemSettingsFooter from './components/SystemSettingsFooter.vue'
const route = useRoute()
diff --git a/src/components/SystemName.vue b/src/components/SystemName.vue
deleted file mode 100644
index 1371acd..0000000
--- a/src/components/SystemName.vue
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
- Update
-
-
-
-
-
diff --git a/src/components/SystemSettingsFooter.vue b/src/components/SystemSettingsFooter.vue
new file mode 100644
index 0000000..4ebc06f
--- /dev/null
+++ b/src/components/SystemSettingsFooter.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+ Server: {{ apiDomain }}
+
+
+
+
+ System ID: {{ auth.loading.value ? 'Loading...' : auth.user.value?.id }}
+
+
+
+
+
diff --git a/src/hooks/auth.ts b/src/hooks/auth.ts
index 54f0c74..1c1d8a7 100644
--- a/src/hooks/auth.ts
+++ b/src/hooks/auth.ts
@@ -9,7 +9,9 @@ export function useAuth () {
const { loading, refetch, result } = useMeQuery({})
const token = useLocalStorage('rs-auth', null)
const registerMutation = useRegisterUserMutation()
+ const loadingRegister = registerMutation.loading
const updateMutation = useUpdateUserMutation()
+ const loadingUpdate = updateMutation.loading
watch(token, (nT, pT) => {
console.log('token', nT)
@@ -39,6 +41,8 @@ export function useAuth () {
return {
token,
loading,
+ loadingRegister,
+ loadingUpdate,
user,
isLoggedIn,
diff --git a/src/hooks/stream-pools.ts b/src/hooks/stream-pools.ts
index fc56ec9..890b2f7 100644
--- a/src/hooks/stream-pools.ts
+++ b/src/hooks/stream-pools.ts
@@ -5,8 +5,21 @@ interface StreamPool {
label?: number
}
-const pools = useLocalStorage('rs-stream-pools', [])
+interface ServoPoolBackgroundsConfig {
+ system: 'servo'
+ url: string
+}
+
+interface DeviceStreamSettings {
+ poolBackgrounds?: ServoPoolBackgroundsConfig | null
+}
+
+const pools = useLocalStorage('rs-device-stream-pools', [])
+const settings = useLocalStorage('rs-device-stream-settings', {})
-export function useStreamPools () {
- return pools
+export function useDeviceStreamPools () {
+ return {
+ pools,
+ settings
+ }
}
diff --git a/src/router.ts b/src/router.ts
index 5ea7f41..b2126a0 100644
--- a/src/router.ts
+++ b/src/router.ts
@@ -1,19 +1,37 @@
import { createWebHistory, createRouter } from 'vue-router'
+import { useAuth } from './hooks/auth'
-export default createRouter({
+const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: async () => import('./views/Home.vue') },
+ { path: '/auth', component: async () => import('./views/Auth.vue') },
- { path: '/groups', component: async () => import('./views/Groups.vue') },
- { path: '/groups/:groupId/live', component: async () => import('./views/Live.vue'), meta: { fullscreen: true } },
- { path: '/groups/:groupId/on-floor', component: async () => import('./views/OnFloor.vue'), meta: { fullscreen: true } },
- { path: '/groups/:groupId/next-up', component: async () => import('./views/NextUp.vue'), meta: { fullscreen: true } },
+ { path: '/groups', component: async () => import('./views/Groups.vue'), meta: { authRequired: true } },
+ { path: '/groups/:groupId/live', component: async () => import('./views/Live.vue'), meta: { fullscreen: true, authRequired: true } },
+ { path: '/groups/:groupId/on-floor', component: async () => import('./views/OnFloor.vue'), meta: { fullscreen: true, authRequired: true } },
+ { path: '/groups/:groupId/next-up', component: async () => import('./views/NextUp.vue'), meta: { fullscreen: true, authRequired: true } },
- { path: '/device-stream', component: async () => import('./views/DeviceStreamSetup.vue') },
- { path: '/device-stream/live', component: async () => import('./views/DeviceStreamLive.vue'), meta: { fullscreen: true } },
+ { path: '/device-stream', component: async () => import('./views/DeviceStreamSetup.vue'), meta: { authRequired: true } },
+ { path: '/device-stream/live', component: async () => import('./views/DeviceStreamLive.vue'), meta: { fullscreen: true, authRequired: true } },
{ path: '/podium', component: async () => import('./views/PodiumConfig.vue') },
{ path: '/podium/live', component: async () => import('./views/PodiumLive.vue'), meta: { fullscreen: true } }
]
})
+export default router
+
+router.beforeEach((to) => {
+ if (!to.meta.authRequired) return
+
+ const auth = useAuth()
+ if (auth.token.value == null) {
+ return {
+ path: '/auth',
+ query: {
+ 'return-to': encodeURIComponent(to.fullPath)
+ },
+ replace: true
+ }
+ }
+})
diff --git a/src/views/Auth.vue b/src/views/Auth.vue
new file mode 100644
index 0000000..6e0bcbd
--- /dev/null
+++ b/src/views/Auth.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
+ Loading...
+
+
diff --git a/src/views/DeviceStreamLive.vue b/src/views/DeviceStreamLive.vue
index 1cb4e0a..1355c5e 100644
--- a/src/views/DeviceStreamLive.vue
+++ b/src/views/DeviceStreamLive.vue
@@ -49,7 +49,7 @@ import { computed, reactive, watch } from 'vue'
import { type DeviceStreamJudgeInfo, type DeviceStreamMarkAddedSubscription, useDeviceStreamMarkAddedSubscription } from '../graphql/generated'
import { type ScoreTally, type Mark } from '../helpers'
import { useAuth } from '../hooks/auth'
-import { useStreamPools } from '../hooks/stream-pools'
+import { useDeviceStreamPools } from '../hooks/stream-pools'
import { useHead } from '@vueuse/head'
import DeviceNotSet from '../components/DeviceNotSet.vue'
@@ -62,7 +62,7 @@ useHead({
})
const auth = useAuth()
-const pools = useStreamPools()
+const { pools, settings } = useDeviceStreamPools()
const cols = computed(() => {
const len = pools.value.length
diff --git a/src/views/DeviceStreamSetup.vue b/src/views/DeviceStreamSetup.vue
index 9fbd51e..0842a6f 100644
--- a/src/views/DeviceStreamSetup.vue
+++ b/src/views/DeviceStreamSetup.vue
@@ -180,22 +180,6 @@
-
-
-
-
Server: {{ apiDomain }}
-
-
- System ID: {{ auth.user.value?.id }}
-
-
-
-
import { ref, computed } from 'vue'
import { useAuth } from '../hooks/auth'
-import { apiDomain, localManual, localApis } from '../apollo'
-import { useStreamPools } from '../hooks/stream-pools'
+import { useDeviceStreamPools } from '../hooks/stream-pools'
import { DeviceStreamShareStatus, useRequestStreamShareMutation, useUserStreamSharesQuery } from '../graphql/generated'
import { useHead } from '@vueuse/head'
import { TextButton, TextField, SelectField, ButtonLink } from '@ropescore/components'
import IconLoading from 'virtual:icons/mdi/loading'
-import SystemName from '../components/SystemName.vue'
useHead({
title: 'Device Stream | RopeScore Live'
@@ -242,7 +224,7 @@ requestShare.onDone(() => {
newDeviceId.value = ''
})
-const pools = useStreamPools()
+const { pools, settings } = useDeviceStreamPools()
// Remove devices you no longer have access to from pools
sharesQuery.onResult(res => {
diff --git a/src/views/Groups.vue b/src/views/Groups.vue
index 77e5281..5426dda 100644
--- a/src/views/Groups.vue
+++ b/src/views/Groups.vue
@@ -8,7 +8,7 @@
-
+
@@ -53,56 +53,6 @@
-
-
- Register
-
-
-
-
- Note that live scoring will send and store data in the cloud,
- Swantzter is the data controller for this and can be reached on
-
privacy@swantzter.se .
- Please make sure you have read the (short and simple!) privacy policy
- available on
-
https://ropescore.com/privacy
-
-
-
- Register
-
-
-
-
-
-
-
Server: {{ apiDomain }}
-
-
- System ID: {{ auth.user.value?.id }}
-
-
-
- You need to add this system as a viewer of the group in RopeScore core,
- do this by entering the ID shown above. It is case sensitive.
-
-
-