diff --git a/README.md b/README.md
index 129bd9fa..d0e1d970 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,13 @@ Vitrivr NG is a web-based user interface developed to be used with the latest ve
For setup information, consult our [Wiki](https://github.com/vitrivr/vitrivr-ng/wiki)
+## Config
+
+There is a `config.json` which enables configuration of the UI to a certain extend.
+While we provide a sensible [default config](src/config.json), the
+some default values are better explored in the [code](src/app/shared/model/config/config.model.ts).
+Information about the configuration can be found in [the wiki](https://github.com/vitrivr/vitrivr-ng/wiki/Configuration).
+
## Development server
From the project folder, run `ng serve` to start a development server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
diff --git a/angular.json b/angular.json
index b96acf69..3bff455a 100644
--- a/angular.json
+++ b/angular.json
@@ -30,6 +30,7 @@
"styles": [
"node_modules/leaflet/dist/leaflet.css",
"node_modules/leaflet-geosearch/dist/geosearch.css",
+ "node_modules/@videogular/ngx-videogular/fonts/videogular.css",
"src/vitrivr-theme.scss"
],
"scripts": [],
diff --git a/src/app/app.component.html b/src/app/app.component.html
index 15d45db1..30a82772 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,73 +1,88 @@
-
+
-
+
-
+
-
+
-
- grid_on
-
+
+ grid_on
+
-
+
-
- view_comfy
-
+
+ view_comfy
+
-
+
-
- list
-
+
+ list
+
-
+
-
- filter_list
-
+
+ filter_list
+
-
+
-
+
-
+
+
-
- av timer
-
+
+
+
+
+
+
+
+
+
+ av timer
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 4773b580..e52f17f7 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -23,17 +23,13 @@ export class AppComponent implements OnInit, AfterViewInit {
settingsbadge = '';
_config: Config;
-
- /** Observable that return the loading state of the QueryService. */
- private readonly _loading: Observable;
-
_loadBool = false
-
+ textualSubmissionOpen = false;
/** Variable to safe currently selected view */
public _active_view: View;
-
competitionHost = ((c: Config) => c._config.competition.host);
-
+ /** Observable that return the loading state of the QueryService. */
+ private readonly _loading: Observable;
/**
* Default constructor. Subscribe for PING messages at the CineastWebSocketFactoryService.
@@ -50,10 +46,10 @@ export class AppComponent implements OnInit, AfterViewInit {
}
})
this._loading = _queryService.observable.pipe(
- filter(msg => ['STARTED', 'ENDED', 'ERROR'].indexOf(msg) > -1),
- map(() => {
- return _queryService.running;
- })
+ filter(msg => ['STARTED', 'ENDED', 'ERROR'].indexOf(msg) > -1),
+ map(() => {
+ return _queryService.running;
+ })
);
_configService.configAsObservable.subscribe(c => this._config = c)
this._active_view = View.GALLERY;
@@ -96,4 +92,9 @@ export class AppComponent implements OnInit, AfterViewInit {
public setActiveView(view: View) {
this._active_view = view;
}
+
+ isCompetitionActive() {
+ return this._configService.configAsObservable;
+ return this._config.dresEndpointRest && (this._config.get('competition.vbs') || this._config.get('competition.lsc'))
+ }
}
diff --git a/src/app/app.config.ts b/src/app/app.config.ts
index 1c861165..ec641a71 100644
--- a/src/app/app.config.ts
+++ b/src/app/app.config.ts
@@ -4,6 +4,7 @@ import {Config} from './shared/model/config/config.model';
import {HttpClient} from '@angular/common/http';
import {UUIDGenerator} from './shared/util/uuid-generator.util';
import {MatSnackBar} from '@angular/material/snack-bar';
+import {Title} from '@angular/platform-browser';
/**
* A service providing the application's configuration and means to (re) load it.
@@ -23,7 +24,12 @@ export class AppConfig {
}
} as ProxyHandler;
- constructor(private http: HttpClient, protected _snackBar: MatSnackBar) {
+ constructor(private http: HttpClient, protected _snackBar: MatSnackBar, private titleService: Title) {
+ AppConfig.settingsSubject.subscribe(settings => {
+ if (settings) {
+ this.titleService.setTitle(settings.get('title'));
+ }
+ });
}
/**
@@ -33,10 +39,6 @@ export class AppConfig {
return AppConfig.settings;
}
- public publishChanges() {
- AppConfig.settingsSubject.next(AppConfig.settings)
- }
-
/**
* Returns the current configuration as observable. Can be used to monitor changes.
*/
@@ -44,6 +46,10 @@ export class AppConfig {
return AppConfig.settingsSubject.asObservable();
}
+ public publishChanges() {
+ AppConfig.settingsSubject.next(AppConfig.settings)
+ }
+
/**
* Loads the default configuration from a JSON file.
*/
diff --git a/src/app/core/vbs/vbs-submission.service.ts b/src/app/core/vbs/vbs-submission.service.ts
index 5d0f293b..9617720f 100644
--- a/src/app/core/vbs/vbs-submission.service.ts
+++ b/src/app/core/vbs/vbs-submission.service.ts
@@ -285,30 +285,54 @@ export class VbsSubmissionService {
mergeMap(([segment, frame]) => {
/* Submit, do some logging and catch HTTP errors. */
return this._dresSubmit.getApiV1Submit(null, segment, null, frame).pipe(
- tap((status: SuccessfulSubmissionsStatus) => {
- switch (status.submission) {
- case 'CORRECT':
- this._snackBar.open(status.description, null, {duration: Config.SNACKBAR_DURATION, panelClass: 'snackbar-success'});
- break;
- case 'WRONG':
- this._snackBar.open(status.description, null, {duration: Config.SNACKBAR_DURATION, panelClass: 'snackbar-warning'});
- break;
- default:
- this._snackBar.open(status.description, null, {duration: Config.SNACKBAR_DURATION});
- break;
- }
- }),
- catchError(err => {
- if (err.error) {
- this._snackBar.open(`Submissions error: ${err.error.description}`, null, {duration: Config.SNACKBAR_DURATION, panelClass: 'snackbar-error'})
- } else {
- this._snackBar.open(`Submissions error: ${err.message}`, null, {duration: Config.SNACKBAR_DURATION, panelClass: 'snackbar-error'})
- }
- return of(null)
- })
+ tap((status: SuccessfulSubmissionsStatus) => {
+ this.handleSubmissionResponse(status);
+ }),
+ catchError(err => {
+ return this.handleSubmissionError(err);
+ })
)
})
).subscribe()
+
+ /* Setup submission subscription, which is triggered manually. */
+ this._submitTextSubscription = this._submitTextSubject.pipe(
+ mergeMap((text) => {
+ /* Submit, do some logging and catch HTTP errors. */
+ return this._dresSubmit.getApiV1Submit(null, null, text).pipe(
+ tap((status: SuccessfulSubmissionsStatus) => {
+ this.handleSubmissionResponse(status);
+ }),
+ catchError(err => {
+ return this.handleSubmissionError(err);
+ })
+ )
+ })
+ ).subscribe()
+ }
+
+
+ private handleSubmissionError(err) {
+ if (err.error) {
+ this._snackBar.open(`Submissions error: ${err.error.description}`, null, {duration: Config.SNACKBAR_DURATION, panelClass: 'snackbar-error'})
+ } else {
+ this._snackBar.open(`Submissions error: ${err.message}`, null, {duration: Config.SNACKBAR_DURATION, panelClass: 'snackbar-error'})
+ }
+ return of(null)
+ }
+
+ private handleSubmissionResponse(status: SuccessfulSubmissionsStatus) {
+ switch (status.submission) {
+ case 'CORRECT':
+ this._snackBar.open(status.description, null, {duration: Config.SNACKBAR_DURATION, panelClass: 'snackbar-success'});
+ break;
+ case 'WRONG':
+ this._snackBar.open(status.description, null, {duration: Config.SNACKBAR_DURATION, panelClass: 'snackbar-warning'});
+ break;
+ default:
+ this._snackBar.open(status.description, null, {duration: Config.SNACKBAR_DURATION});
+ break;
+ }
}
/**
diff --git a/src/app/objectdetails/quick-viewer.component.html b/src/app/objectdetails/quick-viewer.component.html
index 87d84781..489535f7 100644
--- a/src/app/objectdetails/quick-viewer.component.html
+++ b/src/app/objectdetails/quick-viewer.component.html
@@ -11,7 +11,7 @@