Initial WebUI code not exposed to public yet.
This commit is contained in:
49
NEWS.md
Normal file
49
NEWS.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Old Updates
|
||||
|
||||
### 2024-03-08
|
||||
|
||||
This update include breaking changes to how we process commands, we have streamlined the command interface to accept
|
||||
some consistent flags and options. Notably, we have added `-s, --select-backend` flag to all commands that accept it.
|
||||
commands that were accepting comma separated list of backends now needs to be separate option call for example
|
||||
`--select-backend home_plex --select-backend home_jellyfin` instead of `--select-backend home_plex,home_jellyfin`.
|
||||
|
||||
All commands that was accepting backend name as argument now accepts `-s, --select-backend` flag. This change is to make
|
||||
the command interface more consistent and easier to use.
|
||||
|
||||
Another breaking change is the removal of the `-c, --config` flag from all commands that was accepting it. This flag was
|
||||
used to override the default `servers.yaml` file. This was not working as expected as there are more than just the `servers.yaml`
|
||||
to consider like, the state of cache, and the state of the database. As such, we have removed this flag. However, we have
|
||||
added a new environment variable called `WS_BACKENDS_FILE` which can be used to override the default `servers.yaml` file.
|
||||
We strongly recommend not to use it as it might lead to unexpected behavior.
|
||||
|
||||
We started working on a `Web API` which hopefully will lead to a `web frontend` to manage the tool. This is a long
|
||||
term goal, and it's not expected to be ready soon. However, the `Web API` is expected within 3rd quarter of 2024.
|
||||
|
||||
### 2023-11-11
|
||||
|
||||
We added new feature `watch progress tracking` YAY which works exclusively via webhooks at the moment to keep tracking
|
||||
of your play progress.
|
||||
As this feature is quite **EXPERIMENTAL** we have separate command and task for it `state:progress` will send back
|
||||
progress to your backends.
|
||||
However, Sadly this feature is not working at the moment with `Jellyfin` once they accept
|
||||
my [PR #10573](https://github.com/jellyfin/jellyfin/pull/10573) i'll add support for it. However,
|
||||
The feature works well with both `Plex` and `Emby`.
|
||||
|
||||
The support via `webhooks` is excellent, and it's the recommended way to track your progress. However, if you cant use
|
||||
webhooks, the `state:import` command
|
||||
will pull the progress from your backends. however at reduced rate due to the nature of the command. If you want faster
|
||||
progress tracking, you should use `webhooks`.
|
||||
|
||||
To sync the progress update, You have to use `state:progress` command, it will push the update to all `export` enabled
|
||||
backends.
|
||||
This feature is disabled by default like the other features. To enable it add new environment variable
|
||||
called`WS_CRON_PROGRESS=1`.
|
||||
We push progress update every `45 minutes`, to change it like other features add `WS_CRON_PROGRESS_AT="*/45 * * * *"`
|
||||
This is the default timer.
|
||||
|
||||
On another point, we have decided to enable backup by default. To disable it simply add new environment
|
||||
variable `WS_CRON_BACKUP=0`.
|
||||
|
||||
### 2023-10-31
|
||||
|
||||
We added new command called `db:parity` which will check if your backends are reporting the same data.
|
||||
50
README.md
50
README.md
@@ -9,53 +9,13 @@ out of the box, this tool support `Jellyfin`, `Plex` and `Emby` media servers.
|
||||
|
||||
## updates
|
||||
|
||||
### 2024-03-08
|
||||
### 2024-04-30 - [BREAKING CHANGE]
|
||||
|
||||
This update include breaking changes to how we process commands, we have streamlined the command interface to accept
|
||||
some consistent flags and options. Notably, we have added `-s, --select-backend` flag to all commands that accept it.
|
||||
commands that were accepting comma separated list of backends now needs to be separate option call for example
|
||||
`--select-backend home_plex --select-backend home_jellyfin` instead of `--select-backend home_plex,home_jellyfin`.
|
||||
We are going to retire the old webhooks endpoint, please refer to the [FAQ](FAQ.md#how-to-add-webhooks) to know how to update
|
||||
to the new API endpoint. We are going to include `WebUI` for alpha testing after two weeks from today `2024-05-15`. Which most likely means the old webhooks
|
||||
endpoint will be removed. We will try to preseve the old endpoint for a while, but it's not guaranteed we will be able to.
|
||||
|
||||
All commands that was accepting backend name as argument now accepts `-s, --select-backend` flag. This change is to make
|
||||
the command interface more consistent and easier to use.
|
||||
|
||||
Another breaking change is the removal of the `-c, --config` flag from all commands that was accepting it. This flag was
|
||||
used to override the default `servers.yaml` file. This was not working as expected as there are more than just the `servers.yaml`
|
||||
to consider like, the state of cache, and the state of the database. As such, we have removed this flag. However, we have
|
||||
added a new environment variable called `WS_BACKENDS_FILE` which can be used to override the default `servers.yaml` file.
|
||||
We strongly recommend not to use it as it might lead to unexpected behavior.
|
||||
|
||||
We started working on a `Web API` which hopefully will lead to a `web frontend` to manage the tool. This is a long
|
||||
term goal, and it's not expected to be ready soon. However, the `Web API` is expected within 3rd quarter of 2024.
|
||||
|
||||
### 2023-11-11
|
||||
|
||||
We added new feature `watch progress tracking` YAY which works exclusively via webhooks at the moment to keep tracking
|
||||
of your play progress.
|
||||
As this feature is quite **EXPERIMENTAL** we have separate command and task for it `state:progress` will send back
|
||||
progress to your backends.
|
||||
However, Sadly this feature is not working at the moment with `Jellyfin` once they accept
|
||||
my [PR #10573](https://github.com/jellyfin/jellyfin/pull/10573) i'll add support for it. However,
|
||||
The feature works well with both `Plex` and `Emby`.
|
||||
|
||||
The support via `webhooks` is excellent, and it's the recommended way to track your progress. However, if you cant use
|
||||
webhooks, the `state:import` command
|
||||
will pull the progress from your backends. however at reduced rate due to the nature of the command. If you want faster
|
||||
progress tracking, you should use `webhooks`.
|
||||
|
||||
To sync the progress update, You have to use `state:progress` command, it will push the update to all `export` enabled
|
||||
backends.
|
||||
This feature is disabled by default like the other features. To enable it add new environment variable
|
||||
called`WS_CRON_PROGRESS=1`.
|
||||
We push progress update every `45 minutes`, to change it like other features add `WS_CRON_PROGRESS_AT="*/45 * * * *"`
|
||||
This is the default timer.
|
||||
|
||||
On another point, we have decided to enable backup by default. To disable it simply add new environment
|
||||
variable `WS_CRON_BACKUP=0`.
|
||||
|
||||
### 2023-10-31
|
||||
|
||||
We added new command called `db:parity` which will check if your backends are reporting the same data.
|
||||
Refer to [NEWS](NEWS.md) for old updates.
|
||||
|
||||
# Features
|
||||
|
||||
|
||||
24
frontend/.gitignore
vendored
Normal file
24
frontend/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# Nuxt dev/build outputs
|
||||
.output
|
||||
.data
|
||||
.nuxt
|
||||
.nitro
|
||||
.cache
|
||||
dist
|
||||
|
||||
# Node dependencies
|
||||
node_modules
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.fleet
|
||||
.idea
|
||||
|
||||
# Local env files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
10607
frontend/assets/css/all.css
Normal file
10607
frontend/assets/css/all.css
Normal file
File diff suppressed because it is too large
Load Diff
24826
frontend/assets/css/bulma.css
vendored
Normal file
24826
frontend/assets/css/bulma.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
109
frontend/assets/css/style.css
Normal file
109
frontend/assets/css/style.css
Normal file
@@ -0,0 +1,109 @@
|
||||
* {
|
||||
unicode-bidi: plaintext;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 1em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.container,
|
||||
.card,
|
||||
.box,
|
||||
.navbar {
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.is-bordered-danger {
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.is-bordered-info {
|
||||
border: 1px solid #3e8ed0;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
background-color: #eaeaea;
|
||||
}
|
||||
|
||||
.container {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
hr {
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.is-unselectable {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.is-text-overflow {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
* {
|
||||
unicode-bidi: plaintext;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 1em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.container,
|
||||
.card,
|
||||
.box,
|
||||
.navbar {
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
.is-bordered-danger {
|
||||
border: 1px solid red;
|
||||
}
|
||||
|
||||
.is-bordered-info {
|
||||
border: 1px solid #3e8ed0;
|
||||
}
|
||||
|
||||
hr {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
.container {
|
||||
background-color: #0f1010;
|
||||
}
|
||||
|
||||
.is-unselectable {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.is-text-overflow {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.is-borderless {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.is-marginless {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.is-paddingless {
|
||||
padding: 0 !important;
|
||||
}
|
||||
BIN
frontend/assets/webfonts/fa-brands-400.ttf
Normal file
BIN
frontend/assets/webfonts/fa-brands-400.ttf
Normal file
Binary file not shown.
BIN
frontend/assets/webfonts/fa-brands-400.woff2
Normal file
BIN
frontend/assets/webfonts/fa-brands-400.woff2
Normal file
Binary file not shown.
BIN
frontend/assets/webfonts/fa-regular-400.ttf
Normal file
BIN
frontend/assets/webfonts/fa-regular-400.ttf
Normal file
Binary file not shown.
BIN
frontend/assets/webfonts/fa-regular-400.woff2
Normal file
BIN
frontend/assets/webfonts/fa-regular-400.woff2
Normal file
Binary file not shown.
BIN
frontend/assets/webfonts/fa-solid-900.ttf
Normal file
BIN
frontend/assets/webfonts/fa-solid-900.ttf
Normal file
Binary file not shown.
BIN
frontend/assets/webfonts/fa-solid-900.woff2
Normal file
BIN
frontend/assets/webfonts/fa-solid-900.woff2
Normal file
Binary file not shown.
BIN
frontend/assets/webfonts/fa-v4compatibility.ttf
Normal file
BIN
frontend/assets/webfonts/fa-v4compatibility.ttf
Normal file
Binary file not shown.
BIN
frontend/assets/webfonts/fa-v4compatibility.woff2
Normal file
BIN
frontend/assets/webfonts/fa-v4compatibility.woff2
Normal file
Binary file not shown.
142
frontend/layouts/default.vue
Normal file
142
frontend/layouts/default.vue
Normal file
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<nav class="navbar is-dark">
|
||||
<div class="navbar-brand pl-5">
|
||||
<NuxtLink class="navbar-item" href="/">
|
||||
<span class="icon-text">
|
||||
<span class="icon"><i class="fas fa-home"></i></span>
|
||||
<span>Home</span>
|
||||
</span>
|
||||
</NuxtLink>
|
||||
|
||||
<button class="navbar-burger burger" @click="showMenu = !showMenu">
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="navbar-menu" :class="{'is-active':showMenu}">
|
||||
<div class="navbar-start">
|
||||
<a class="navbar-item" href="/backends">
|
||||
<span class="icon-text">
|
||||
<span class="icon"><i class="fas fa-server"></i></span>
|
||||
<span>Backends</span>
|
||||
</span>
|
||||
</a>
|
||||
<a class="navbar-item" href="/history">
|
||||
<span class="icon-text">
|
||||
<span class="icon"><i class="fas fa-history"></i></span>
|
||||
<span>History</span>
|
||||
</span>
|
||||
</a>
|
||||
<a class="navbar-item" href="/logs">
|
||||
<span class="icon-text">
|
||||
<span class="icon"><i class="fas fa-globe"></i></span>
|
||||
<span>Logs</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
<div class="navbar-item">
|
||||
<button class="button is-dark has-tooltip-bottom" @click="selectedTheme = 'light'"
|
||||
v-if="'dark' === selectedTheme">
|
||||
<span class="icon is-small is-left has-text-warning">
|
||||
<i class="fas fa-sun"></i>
|
||||
</span>
|
||||
</button>
|
||||
<button class="button is-dark has-tooltip-bottom" @click="selectedTheme = 'dark'"
|
||||
v-if="'light' === selectedTheme">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fas fa-moon"></i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="columns">
|
||||
<div class="column is-12">
|
||||
<slot/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="columns mt-3 is-mobile">
|
||||
<div class="column is-8-mobile">
|
||||
<div class="has-text-left">
|
||||
© {{ Year }} - <a href="https://github.com/arabcoders/watchstate" target="_blank">WatchState</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref} from 'vue'
|
||||
import 'assets/css/bulma.css'
|
||||
import 'assets/css/style.css'
|
||||
import 'assets/css/all.css'
|
||||
import {useStorage} from '@vueuse/core'
|
||||
|
||||
const selectedTheme = useStorage('theme', (() => window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')());
|
||||
|
||||
const Year = ref(new Date().getFullYear())
|
||||
const showMenu = ref(false)
|
||||
|
||||
const applyPreferredColorScheme = (scheme) => {
|
||||
for (let s = 0; s < document.styleSheets.length; s++) {
|
||||
for (let i = 0; i < document.styleSheets[s].cssRules.length; i++) {
|
||||
try {
|
||||
const rule = document.styleSheets[s].cssRules[i];
|
||||
if (rule && rule.media && rule.media.mediaText.includes("prefers-color-scheme")) {
|
||||
switch (scheme) {
|
||||
case "light":
|
||||
rule.media.appendMedium("original-prefers-color-scheme");
|
||||
if (rule.media.mediaText.includes("light")) {
|
||||
rule.media.deleteMedium("(prefers-color-scheme: light)");
|
||||
}
|
||||
if (rule.media.mediaText.includes("dark")) {
|
||||
rule.media.deleteMedium("(prefers-color-scheme: dark)");
|
||||
}
|
||||
break;
|
||||
case "dark":
|
||||
rule.media.appendMedium("(prefers-color-scheme: light)");
|
||||
rule.media.appendMedium("(prefers-color-scheme: dark)");
|
||||
if (rule.media.mediaText.includes("original")) {
|
||||
rule.media.deleteMedium("original-prefers-color-scheme");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rule.media.appendMedium("(prefers-color-scheme: dark)");
|
||||
if (rule.media.mediaText.includes("light")) {
|
||||
rule.media.deleteMedium("(prefers-color-scheme: light)");
|
||||
}
|
||||
if (rule.media.mediaText.includes("original")) {
|
||||
rule.media.deleteMedium("original-prefers-color-scheme");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.debug(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
try {
|
||||
applyPreferredColorScheme(selectedTheme.value);
|
||||
} catch (e) {
|
||||
}
|
||||
})
|
||||
|
||||
watch(selectedTheme, (value) => {
|
||||
try {
|
||||
applyPreferredColorScheme(value);
|
||||
} catch (e) {
|
||||
}
|
||||
})
|
||||
</script>
|
||||
31
frontend/nuxt.config.ts
Normal file
31
frontend/nuxt.config.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
|
||||
import path from "path";
|
||||
|
||||
export default defineNuxtConfig({
|
||||
ssr: false,
|
||||
devtools: {enabled: true},
|
||||
app: {
|
||||
head: {
|
||||
"meta": [
|
||||
{"charset": "utf-8"},
|
||||
{"name": "viewport", "content": "width=device-width, initial-scale=1.0, maximum-scale=1.0"},
|
||||
{"name": "theme-color", "content": "#000000"}
|
||||
],
|
||||
},
|
||||
buildAssetsDir: "assets",
|
||||
},
|
||||
router: {
|
||||
options: {
|
||||
linkActiveClass: "is-active",
|
||||
}
|
||||
},
|
||||
modules: [
|
||||
'@vueuse/nuxt',
|
||||
],
|
||||
nitro: {
|
||||
output: {
|
||||
publicDir: path.join(__dirname, 'exported')
|
||||
}
|
||||
},
|
||||
})
|
||||
19
frontend/package.json
Normal file
19
frontend/package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "nuxt-app",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "nuxt build",
|
||||
"dev": "nuxt dev",
|
||||
"generate": "nuxt generate",
|
||||
"preview": "nuxt preview",
|
||||
"postinstall": "nuxt prepare"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vueuse/core": "^10.9.0",
|
||||
"@vueuse/nuxt": "^10.9.0",
|
||||
"nuxt": "^3.11.2",
|
||||
"vue": "^3.4.21",
|
||||
"vue-router": "^4.3.0"
|
||||
}
|
||||
}
|
||||
3
frontend/pages/backends/index.vue
Normal file
3
frontend/pages/backends/index.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<p>NYI</p>
|
||||
</template>
|
||||
5
frontend/pages/history/index.vue
Normal file
5
frontend/pages/history/index.vue
Normal file
@@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<p>NYI</p>
|
||||
</template>
|
||||
<script setup>
|
||||
</script>
|
||||
3
frontend/pages/index.vue
Normal file
3
frontend/pages/index.vue
Normal file
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<p>foo</p>
|
||||
</template>
|
||||
BIN
frontend/public/favicon.ico
Normal file
BIN
frontend/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
4
frontend/tsconfig.json
Normal file
4
frontend/tsconfig.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
// https://nuxt.com/docs/guide/concepts/typescript
|
||||
"extends": "./.nuxt/tsconfig.json"
|
||||
}
|
||||
5811
frontend/yarn.lock
Normal file
5811
frontend/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user