admin: add settings section
Signed-off-by: Varun Patil <varunpatil@ucla.edu>pull/563/head
parent
5e32987932
commit
f73b82bdd5
|
@ -47,6 +47,10 @@ Memories is a *batteries-included* photo management solution for Nextcloud with
|
|||
<command>OCA\Memories\Command\PlacesSetup</command>
|
||||
<command>OCA\Memories\Command\MigrateGoogleTakeout</command>
|
||||
</commands>
|
||||
<settings>
|
||||
<admin>OCA\Memories\Settings\Admin</admin>
|
||||
<admin-section>OCA\Memories\Settings\AdminSection</admin-section>
|
||||
</settings>
|
||||
<navigations>
|
||||
<navigation>
|
||||
<name>Memories</name>
|
||||
|
|
|
@ -83,6 +83,8 @@ return [
|
|||
|
||||
// Config API
|
||||
['name' => 'Other#setUserConfig', 'url' => '/api/config/{key}', 'verb' => 'PUT'],
|
||||
['name' => 'Other#getSystemConfig', 'url' => '/api/system-config', 'verb' => 'GET'],
|
||||
['name' => 'Other#setSystemConfig', 'url' => '/api/system-config/{key}', 'verb' => 'PUT'],
|
||||
|
||||
// Service worker
|
||||
['name' => 'Other#serviceWorker', 'url' => '/service-worker.js', 'verb' => 'GET'],
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
id="svg2"
|
||||
sodipodi:docname="app.svg"
|
||||
viewBox="0 0 650 650"
|
||||
version="1.1"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
inkscape:export-filename="C:\Users\varun\Downloads\app.png"
|
||||
inkscape:export-xdpi="44.700001"
|
||||
inkscape:export-ydpi="44.700001"
|
||||
width="650"
|
||||
height="650"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs16" />
|
||||
<title
|
||||
id="title3629">Camera</title>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
bordercolor="#666666"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-y="-9"
|
||||
pagecolor="#ffffff"
|
||||
inkscape:window-height="991"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:zoom="0.35355339"
|
||||
inkscape:window-x="-9"
|
||||
showgrid="false"
|
||||
borderopacity="1.0"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:cx="89.095455"
|
||||
inkscape:cy="148.49242"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:document-units="px"
|
||||
inkscape:pagecheckerboard="0"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="bg"
|
||||
inkscape:groupmode="layer"
|
||||
transform="translate(-151.94602,-318.77312)">
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:2.13333"
|
||||
d="m 197.73165,860.67627 c -18.61338,-6.82684 -36.75782,-26.01129 -41.74653,-44.13937 -1.829,-6.64627 -2.33554,-48.09549 -1.88392,-154.15716 l 0.6177,-145.06666 4.93339,-10.01572 c 16.12451,-32.73596 27.47173,-36.77498 105.46662,-37.5407 l 63.46666,-0.62308 0.0128,-8.97692 c 0.0286,-21.53158 14.50791,-42.38798 33.30228,-47.9693 14.35532,-4.26306 208.49298,-3.66246 220.80965,0.68312 18.77632,6.62468 31.61107,24.94489 31.69598,45.2426 l 0.0459,11.2 h 65.04378 c 84.02378,0 95.74352,3.94726 112.45,37.8737 l 7.03955,14.29547 0.63814,134.29886 c 0.8464,178.12549 -1.26265,188.01876 -43.44674,203.80184 -15.31511,5.73014 -542.98637,6.76314 -558.44531,1.09332 z M 510.98557,774.6975 c 88.64983,-31.88148 102.45316,-145.666 23.87294,-196.79099 -102.54562,-66.7171 -220.77781,66.53341 -142.78216,160.91892 29.81079,36.0752 77.95716,50.59979 118.90922,35.87207 z m -60.78933,-42.43819 c -25.88523,-9.13355 -42.15328,-37.1623 -39.9792,-68.88145 5.67091,-82.737 128.4049,-82.50709 133.37154,0.24984 3.13721,52.27458 -43.21406,86.33693 -93.39234,68.63161 z"
|
||||
id="path3940" />
|
||||
<path
|
||||
style="fill:#000000;stroke-width:2.13333"
|
||||
id="path3510"
|
||||
d="" />
|
||||
<path
|
||||
style="fill:#000000;stroke-width:2.13333"
|
||||
id="path3490"
|
||||
d="" />
|
||||
<path
|
||||
style="fill:#000000;stroke-width:2.13333"
|
||||
id="path3452"
|
||||
d="" />
|
||||
</g>
|
||||
<g
|
||||
id="layer2"
|
||||
inkscape:label="camera"
|
||||
inkscape:groupmode="layer"
|
||||
transform="translate(-151.94602,-318.77312)" />
|
||||
<metadata
|
||||
id="metadata13">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:title>Camera</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
</svg>
|
After Width: | Height: | Size: 3.3 KiB |
|
@ -56,6 +56,59 @@ class OtherController extends GenericApiController
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @AdminRequired
|
||||
*
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function getSystemConfig(): Http\Response
|
||||
{
|
||||
return Util::guardEx(function () {
|
||||
$config = [];
|
||||
foreach (Util::systemConfigDefaults() as $key => $default) {
|
||||
$config[$key] = $this->config->getSystemValue($key, $default);
|
||||
}
|
||||
|
||||
return new JSONResponse($config, Http::STATUS_OK);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @AdminRequired
|
||||
*
|
||||
* @NoCSRFRequired
|
||||
*
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setSystemConfig(string $key, $value): Http\Response
|
||||
{
|
||||
return Util::guardEx(function () use ($key, $value) {
|
||||
// Make sure not running in read-only mode
|
||||
if ($this->config->getSystemValue('memories.readonly', false)) {
|
||||
throw Exceptions::Forbidden('Cannot change settings in readonly mode');
|
||||
}
|
||||
|
||||
// Make sure the key is valid
|
||||
$defaults = Util::systemConfigDefaults();
|
||||
if (!\array_key_exists($key, $defaults)) {
|
||||
throw Exceptions::BadRequest('Invalid key');
|
||||
}
|
||||
|
||||
// Make sure the value has the same type as the default value
|
||||
if (\gettype($value) !== \gettype($defaults[$key])) {
|
||||
throw Exceptions::BadRequest('Invalid value type');
|
||||
}
|
||||
|
||||
if ($value === $defaults[$key]) {
|
||||
$this->config->deleteSystemValue($key);
|
||||
} else {
|
||||
$this->config->setSystemValue($key, $value);
|
||||
}
|
||||
|
||||
return new JSONResponse([], Http::STATUS_OK);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\Memories\Settings;
|
||||
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\IConfig;
|
||||
use OCP\IL10N;
|
||||
use OCP\Settings\ISettings;
|
||||
|
||||
class Admin implements ISettings
|
||||
{
|
||||
/** @var IConfig */
|
||||
private $config;
|
||||
|
||||
/** @var IL10N */
|
||||
private $l;
|
||||
|
||||
public function __construct(
|
||||
IConfig $config,
|
||||
IL10N $l
|
||||
) {
|
||||
$this->config = $config;
|
||||
$this->l = $l;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TemplateResponse
|
||||
*/
|
||||
public function getForm()
|
||||
{
|
||||
$parameters = [
|
||||
];
|
||||
|
||||
\OCP\Util::addScript('memories', 'memories-main');
|
||||
|
||||
return new TemplateResponse('memories', 'admin', $parameters);
|
||||
}
|
||||
|
||||
public function getSection()
|
||||
{
|
||||
return 'memories';
|
||||
}
|
||||
|
||||
public function getPriority()
|
||||
{
|
||||
return 50;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\Memories\Settings;
|
||||
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\IL10N;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\Settings\IIconSection;
|
||||
|
||||
class AdminSection implements IIconSection
|
||||
{
|
||||
/** @var IL10N */
|
||||
private $l;
|
||||
|
||||
/** @var IURLGenerator */
|
||||
private $urlGenerator;
|
||||
|
||||
public function __construct(
|
||||
IL10N $l,
|
||||
IURLGenerator $urlGenerator
|
||||
) {
|
||||
$this->l = $l;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TemplateResponse
|
||||
*/
|
||||
public function getForm()
|
||||
{
|
||||
$parameters = [
|
||||
];
|
||||
|
||||
return new TemplateResponse('memories', 'admin', $parameters);
|
||||
}
|
||||
|
||||
public function getID()
|
||||
{
|
||||
return 'memories';
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->l->t('Memories');
|
||||
}
|
||||
|
||||
public function getPriority()
|
||||
{
|
||||
return 75;
|
||||
}
|
||||
|
||||
public function getIcon()
|
||||
{
|
||||
return $this->urlGenerator->imagePath('memories', 'app-dark.svg');
|
||||
}
|
||||
}
|
64
lib/Util.php
64
lib/Util.php
|
@ -279,7 +279,69 @@ class Util
|
|||
*/
|
||||
public static function placesGISType(): int
|
||||
{
|
||||
return (int) \OC::$server->get(\OCP\IConfig::class)->getSystemValue('memories.gis_type', -1);
|
||||
return self::getSystemConfig('memories.gis_type');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a system config key with the correct default.
|
||||
*
|
||||
* @param null|mixed $default
|
||||
*/
|
||||
public static function getSystemConfig(string $key, $default = null)
|
||||
{
|
||||
$config = \OC::$server->get(\OCP\IConfig::class);
|
||||
|
||||
return $config->getSystemValue($key, $default ?? self::systemConfigDefaults()[$key]);
|
||||
}
|
||||
|
||||
/** Get list of defaults for all system config keys. */
|
||||
public static function systemConfigDefaults(): array
|
||||
{
|
||||
return [
|
||||
// Places database type identifier
|
||||
'memories.gis_type' => -1,
|
||||
|
||||
// Disable transcoding
|
||||
'memories.vod.disable' => true,
|
||||
|
||||
// VA-API configuration options
|
||||
'memories.vod.vaapi' => false, // Transcode with VA-API
|
||||
'memories.vod.vaapi.low_power' => false, // Use low_power mode for VA-API
|
||||
|
||||
// NVENC configuration options
|
||||
'memories.vod.nvenc' => false, // Transcode with NVIDIA NVENC
|
||||
'memories.vod.nvenc.temporal_aq' => false,
|
||||
'memories.vod.nvenc.scale' => 'npp', // npp or cuda
|
||||
|
||||
// Paths to ffmpeg and ffprobe binaries
|
||||
'memories.vod.ffmpeg' => '',
|
||||
'memories.vod.ffprobe' => '',
|
||||
|
||||
// Path to go-vod binary
|
||||
'memories.vod.path' => '',
|
||||
|
||||
// Path to use for transcoded files (/tmp/go-vod/instanceid)
|
||||
// Make sure this has plenty of space
|
||||
'memories.vod.tempdir' => '',
|
||||
|
||||
// Bind address to use when starting the transcoding server
|
||||
'memories.vod.bind' => '127.0.0.1:47788',
|
||||
|
||||
// Address used to connect to the transcoding server
|
||||
// If not specified, the bind address above will be used
|
||||
'memories.vod.connect' => '127.0.0.1:47788',
|
||||
|
||||
// Mark go-vod as external. If true, Memories will not attempt to
|
||||
// start go-vod if it is not running already.
|
||||
'memories.vod.external' => false,
|
||||
|
||||
// Set the default video quality for a first time user
|
||||
// 0 => Auto (default)
|
||||
// -1 => Original (max quality with transcoding)
|
||||
// -2 => Direct (disable transcoding)
|
||||
// 1080 => 1080p (and so on)
|
||||
'memories.video_default_quality' => '0',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,384 @@
|
|||
<template>
|
||||
<div class="outer" v-if="loaded">
|
||||
<div>
|
||||
<h2>{{ t("memories", "Video Streaming") }}</h2>
|
||||
|
||||
<p>
|
||||
{{
|
||||
t(
|
||||
"memories",
|
||||
"Live transcoding provides for adaptive streaming of videos using HLS."
|
||||
)
|
||||
}}
|
||||
<br />
|
||||
{{
|
||||
t(
|
||||
"memories",
|
||||
"Note that this may be very CPU intensive without hardware acceleration."
|
||||
)
|
||||
}}
|
||||
|
||||
<NcCheckboxRadioSwitch
|
||||
:checked.sync="enableTranscoding"
|
||||
@update:checked="update('enableTranscoding')"
|
||||
type="switch"
|
||||
>
|
||||
{{ t("memories", "Enable Transcoding") }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
|
||||
<NcTextField
|
||||
:label="t('memories', 'ffmpeg path')"
|
||||
:label-visible="true"
|
||||
:value="ffmpegPath"
|
||||
@change="update('ffmpegPath', $event.target.value)"
|
||||
/>
|
||||
|
||||
<NcTextField
|
||||
:label="t('memories', 'ffprobe path')"
|
||||
:label-visible="true"
|
||||
:value="ffprobePath"
|
||||
@change="update('ffprobePath', $event.target.value)"
|
||||
/>
|
||||
|
||||
<br />
|
||||
{{ t("memories", "Global default video quality (user may override)") }}
|
||||
<NcCheckboxRadioSwitch
|
||||
:checked.sync="videoDefaultQuality"
|
||||
value="0"
|
||||
name="vdq_radio"
|
||||
type="radio"
|
||||
@update:checked="update('videoDefaultQuality')"
|
||||
>{{ t("memories", "Auto (adaptive transcode)") }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<NcCheckboxRadioSwitch
|
||||
:checked.sync="videoDefaultQuality"
|
||||
value="-1"
|
||||
name="vdq_radio"
|
||||
type="radio"
|
||||
@update:checked="update('videoDefaultQuality')"
|
||||
>{{ t("memories", "Original (transcode with max quality)") }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<NcCheckboxRadioSwitch
|
||||
:checked.sync="videoDefaultQuality"
|
||||
value="-2"
|
||||
name="vdq_radio"
|
||||
type="radio"
|
||||
@update:checked="update('videoDefaultQuality')"
|
||||
>{{ t("memories", "Direct (original video file without transcode)") }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
</p>
|
||||
|
||||
<h3>{{ t("memories", "Transcoder configuration") }}</h3>
|
||||
<p>
|
||||
{{
|
||||
t(
|
||||
"memories",
|
||||
"Memories uses the go-vod transcoder. You can run go-vod exernally (e.g. in a separate Docker container for hardware acceleration) or use the built-in transcoder. To use an external transcoder, enable the following option and follow the instructions at this link:"
|
||||
)
|
||||
}}
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://github.com/pulsejet/memories/wiki/HW-Transcoding"
|
||||
>
|
||||
{{ t("memories", "external transcoder configuration") }}
|
||||
</a>
|
||||
|
||||
<NcCheckboxRadioSwitch
|
||||
:checked.sync="enableExternalTranscoder"
|
||||
@update:checked="update('enableExternalTranscoder')"
|
||||
type="switch"
|
||||
>
|
||||
{{ t("memories", "Enable external transcoder (go-vod)") }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
|
||||
<NcTextField
|
||||
:label="t('memories', 'Binary path (local only)')"
|
||||
:label-visible="true"
|
||||
:value="goVodPath"
|
||||
@change="update('goVodPath', $event.target.value)"
|
||||
/>
|
||||
|
||||
<NcTextField
|
||||
:label="t('memories', 'Bind address (local only)')"
|
||||
:label-visible="true"
|
||||
:value="goVodBind"
|
||||
@change="update('goVodBind', $event.target.value)"
|
||||
/>
|
||||
|
||||
<NcTextField
|
||||
:label="t('memories', 'Connection address (same as bind if local)')"
|
||||
:label-visible="true"
|
||||
:value="goVodConnect"
|
||||
@change="update('goVodConnect', $event.target.value)"
|
||||
/>
|
||||
</p>
|
||||
|
||||
<h3>{{ t("memories", "Hardware Acceleration") }}</h3>
|
||||
|
||||
<p>
|
||||
{{
|
||||
t(
|
||||
"memories",
|
||||
"You must first make sure the correct drivers are installed before configuring acceleration."
|
||||
)
|
||||
}}
|
||||
<br />
|
||||
{{
|
||||
t(
|
||||
"memories",
|
||||
"Make sure you test hardware acceleration with various options after enabling."
|
||||
)
|
||||
}}
|
||||
<br />
|
||||
{{
|
||||
t(
|
||||
"memories",
|
||||
"Do not enable multiple types of hardware acceleration simultaneously."
|
||||
)
|
||||
}}
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
{{
|
||||
t(
|
||||
"memories",
|
||||
"Intel processors supporting QuickSync Video (QSV) as well as some AMD GPUs can be used for transcoding using VA-API acceleration."
|
||||
)
|
||||
}}
|
||||
{{
|
||||
t(
|
||||
"memories",
|
||||
"For more details on driver installation, check the following link:"
|
||||
)
|
||||
}}
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://github.com/pulsejet/memories/wiki/HW-Transcoding#va-api"
|
||||
>
|
||||
VA-API configuration
|
||||
</a>
|
||||
|
||||
<NcNoteCard type="warning">
|
||||
{{
|
||||
t(
|
||||
"memories",
|
||||
"/dev/dri/renderD128 is required for VA-API acceleration."
|
||||
)
|
||||
}}
|
||||
</NcNoteCard>
|
||||
|
||||
<NcCheckboxRadioSwitch
|
||||
:checked.sync="enableVaapi"
|
||||
@update:checked="update('enableVaapi')"
|
||||
type="switch"
|
||||
>
|
||||
{{ t("memories", "Enable acceleration with VA-API") }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
|
||||
<NcCheckboxRadioSwitch
|
||||
:checked.sync="enableVaapiLowPower"
|
||||
@update:checked="update('enableVaapiLowPower')"
|
||||
type="switch"
|
||||
>
|
||||
{{ t("memories", "Enable low-power mode (QSV)") }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
|
||||
{{
|
||||
t(
|
||||
"memories",
|
||||
"NVIDIA GPUs can be used for transcoding using the NVENC encoder with the proper drivers."
|
||||
)
|
||||
}}
|
||||
<br />
|
||||
{{
|
||||
t(
|
||||
"memories",
|
||||
"Depending on the versions of the installed SDK and ffmpeg, you need to specify the scaler to use"
|
||||
)
|
||||
}}
|
||||
|
||||
<NcNoteCard type="warning">
|
||||
{{
|
||||
t(
|
||||
"memories",
|
||||
"No automated tests are available for NVIDIA acceleration."
|
||||
)
|
||||
}}
|
||||
</NcNoteCard>
|
||||
|
||||
<NcCheckboxRadioSwitch
|
||||
:checked.sync="enableNvenc"
|
||||
@update:checked="update('enableNvenc')"
|
||||
type="switch"
|
||||
>
|
||||
{{ t("memories", "Enable acceleration with NVENC") }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<NcCheckboxRadioSwitch
|
||||
:checked.sync="enableNvencTemporalAQ"
|
||||
@update:checked="update('enableNvencTemporalAQ')"
|
||||
type="switch"
|
||||
>
|
||||
{{ t("memories", "Enable NVENC Temporal AQ") }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
|
||||
<NcCheckboxRadioSwitch
|
||||
:checked.sync="nvencScaler"
|
||||
value="npp"
|
||||
name="nvence_scaler_radio"
|
||||
type="radio"
|
||||
@update:checked="update('nvencScaler')"
|
||||
class="m-radio"
|
||||
>{{ t("memories", "NPP scaler") }}
|
||||
</NcCheckboxRadioSwitch>
|
||||
<NcCheckboxRadioSwitch
|
||||
:checked.sync="nvencScaler"
|
||||
value="cuda"
|
||||
name="nvence_scaler_radio"
|
||||
type="radio"
|
||||
class="m-radio"
|
||||
@update:checked="update('nvencScaler')"
|
||||
>{{ t("memories", "CUDA scaler") }}</NcCheckboxRadioSwitch
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "vue";
|
||||
|
||||
import axios from "@nextcloud/axios";
|
||||
import { API } from "./services/API";
|
||||
import { showError } from "@nextcloud/dialogs";
|
||||
|
||||
const NcCheckboxRadioSwitch = () =>
|
||||
import("@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch");
|
||||
const NcNoteCard = () => import("@nextcloud/vue/dist/Components/NcNoteCard");
|
||||
const NcTextField = () => import("@nextcloud/vue/dist/Components/NcTextField");
|
||||
|
||||
/** Map from UI to backend settings */
|
||||
const settings = {
|
||||
enableTranscoding: "memories.vod.disable",
|
||||
ffmpegPath: "memories.vod.ffmpeg",
|
||||
ffprobePath: "memories.vod.ffprobe",
|
||||
goVodPath: "memories.vod.path",
|
||||
goVodBind: "memories.vod.bind",
|
||||
goVodConnect: "memories.vod.connect",
|
||||
enableExternalTranscoder: "memories.vod.external",
|
||||
videoDefaultQuality: "memories.video_default_quality",
|
||||
|
||||
enableVaapi: "memories.vod.vaapi",
|
||||
enableVaapiLowPower: "memories.vod.vaapi.low_power",
|
||||
|
||||
enableNvenc: "memories.vod.nvenc",
|
||||
enableNvencTemporalAQ: "memories.vod.nvenc.temporal_aq",
|
||||
nvencScaler: "memories.vod.nvenc.scale",
|
||||
};
|
||||
|
||||
/** Invert setting before saving */
|
||||
const invertedBooleans = ["enableTranscoding"];
|
||||
|
||||
export default defineComponent({
|
||||
name: "Admin",
|
||||
components: {
|
||||
NcCheckboxRadioSwitch,
|
||||
NcNoteCard,
|
||||
NcTextField,
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
loaded: false,
|
||||
|
||||
enableTranscoding: false,
|
||||
ffmpegPath: "",
|
||||
ffprobePath: "",
|
||||
goVodPath: "",
|
||||
goVodBind: "",
|
||||
goVodConnect: "",
|
||||
enableExternalTranscoder: false,
|
||||
videoDefaultQuality: "",
|
||||
|
||||
enableVaapi: false,
|
||||
enableVaapiLowPower: false,
|
||||
|
||||
enableNvenc: false,
|
||||
enableNvencTemporalAQ: false,
|
||||
nvencScaler: "",
|
||||
}),
|
||||
|
||||
mounted() {
|
||||
this.reload();
|
||||
},
|
||||
|
||||
methods: {
|
||||
async reload() {
|
||||
const res = await axios.get(API.SYSTEM_CONFIG(null));
|
||||
for (const key in settings) {
|
||||
if (!res.data.hasOwnProperty(settings[key])) {
|
||||
console.error(
|
||||
`Setting ${settings[key]} not found in backend response`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
this[key] = res.data[settings[key]];
|
||||
|
||||
if (invertedBooleans.includes(key)) {
|
||||
this[key] = !this[key];
|
||||
}
|
||||
}
|
||||
|
||||
this.loaded = true;
|
||||
},
|
||||
|
||||
async update(key: string, value = null) {
|
||||
value ||= this[key];
|
||||
const setting = settings[key];
|
||||
|
||||
// Inversion
|
||||
if (invertedBooleans.includes(key)) {
|
||||
value = !value;
|
||||
}
|
||||
|
||||
axios
|
||||
.put(API.SYSTEM_CONFIG(setting), {
|
||||
value: value,
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
showError(this.t("memories", "Failed to update setting"));
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.outer {
|
||||
padding: 20px;
|
||||
|
||||
.checkbox-radio-switch {
|
||||
margin: 2px 8px;
|
||||
}
|
||||
|
||||
.m-radio {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.2em;
|
||||
font-weight: 500;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--color-primary-element);
|
||||
}
|
||||
}
|
||||
</style>
|
23
src/main.ts
23
src/main.ts
|
@ -8,6 +8,7 @@ import XImg from "./components/frame/XImg.vue";
|
|||
import GlobalMixin from "./mixins/GlobalMixin";
|
||||
|
||||
import App from "./App.vue";
|
||||
import Admin from "./Admin.vue";
|
||||
import router from "./router";
|
||||
import { Route } from "vue-router";
|
||||
import { generateFilePath } from "@nextcloud/router";
|
||||
|
@ -103,8 +104,20 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
);
|
||||
});
|
||||
|
||||
export default new Vue({
|
||||
el: "#content",
|
||||
router,
|
||||
render: (h) => h(App),
|
||||
});
|
||||
let app = null;
|
||||
|
||||
const adminSection = document.getElementById("memories-admin-content");
|
||||
if (adminSection) {
|
||||
app = new Vue({
|
||||
el: "#memories-admin-content",
|
||||
render: (h) => h(Admin),
|
||||
});
|
||||
} else {
|
||||
app = new Vue({
|
||||
el: "#content",
|
||||
router,
|
||||
render: (h) => h(App),
|
||||
});
|
||||
}
|
||||
|
||||
export default app;
|
||||
|
|
|
@ -184,6 +184,12 @@ export class API {
|
|||
return gen(`${BASE}/config/{setting}`, { setting });
|
||||
}
|
||||
|
||||
static SYSTEM_CONFIG(setting: string | null) {
|
||||
return setting
|
||||
? gen(`${BASE}/system-config/{setting}`, { setting })
|
||||
: gen(`${BASE}/system-config`);
|
||||
}
|
||||
|
||||
static MAP_CLUSTERS() {
|
||||
return tok(gen(`${BASE}/map/clusters`));
|
||||
}
|
||||
|
|
|
@ -297,12 +297,17 @@ export const constants = {
|
|||
|
||||
/** Cache store */
|
||||
let staticCache: Cache | null = null;
|
||||
const cacheName = `memories-${loadState("memories", "version")}-${
|
||||
getCurrentUser()?.uid
|
||||
}`;
|
||||
openCache().then((cache) => {
|
||||
staticCache = cache;
|
||||
});
|
||||
let cacheName: string;
|
||||
let memoriesVersion: string;
|
||||
|
||||
try {
|
||||
memoriesVersion = loadState("memories", "version");
|
||||
const uid = getCurrentUser()?.uid;
|
||||
cacheName = `memories-${memoriesVersion}-${uid}`;
|
||||
openCache().then((cache) => (staticCache = cache));
|
||||
} catch (e) {
|
||||
console.warn("Failed to open cache");
|
||||
}
|
||||
|
||||
// Clear all caches except the current one
|
||||
window.caches?.keys().then((keys) => {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<div id="memories-admin-content"></div>
|
Loading…
Reference in New Issue