mirror of
				https://github.com/KevinMidboe/immich.git
				synced 2025-10-29 17:40:28 +00:00 
			
		
		
		
	feat(server,web): server config (#4006)
* feat: server config * chore: open api * fix: redirect /map to /photos when disabled
This commit is contained in:
		
							
								
								
									
										112
									
								
								cli/src/api/open-api/api.ts
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										112
									
								
								cli/src/api/open-api/api.ts
									
									
									
										generated
									
									
									
								
							| @@ -2343,6 +2343,31 @@ export interface SearchResponseDto { | ||||
|      */ | ||||
|     'assets': SearchAssetResponseDto; | ||||
| } | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
|  * @interface ServerConfigDto | ||||
|  */ | ||||
| export interface ServerConfigDto { | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof ServerConfigDto | ||||
|      */ | ||||
|     'loginPageMessage': string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof ServerConfigDto | ||||
|      */ | ||||
|     'mapTileUrl': string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof ServerConfigDto | ||||
|      */ | ||||
|     'oauthButtonText': string; | ||||
| } | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
| @@ -2367,6 +2392,12 @@ export interface ServerFeaturesDto { | ||||
|      * @memberof ServerFeaturesDto | ||||
|      */ | ||||
|     'facialRecognition': boolean; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {boolean} | ||||
|      * @memberof ServerFeaturesDto | ||||
|      */ | ||||
|     'map': boolean; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {boolean} | ||||
| @@ -2810,6 +2841,12 @@ export interface SystemConfigDto { | ||||
|      * @memberof SystemConfigDto | ||||
|      */ | ||||
|     'machineLearning': SystemConfigMachineLearningDto; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {SystemConfigMapDto} | ||||
|      * @memberof SystemConfigDto | ||||
|      */ | ||||
|     'map': SystemConfigMapDto; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {SystemConfigOAuthDto} | ||||
| @@ -3050,6 +3087,25 @@ export interface SystemConfigMachineLearningDto { | ||||
|      */ | ||||
|     'url': string; | ||||
| } | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
|  * @interface SystemConfigMapDto | ||||
|  */ | ||||
| export interface SystemConfigMapDto { | ||||
|     /** | ||||
|      *  | ||||
|      * @type {boolean} | ||||
|      * @memberof SystemConfigMapDto | ||||
|      */ | ||||
|     'enabled': boolean; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof SystemConfigMapDto | ||||
|      */ | ||||
|     'tileUrl': string; | ||||
| } | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
| @@ -10825,6 +10881,35 @@ export class SearchApi extends BaseAPI { | ||||
|  */ | ||||
| export const ServerInfoApiAxiosParamCreator = function (configuration?: Configuration) { | ||||
|     return { | ||||
|         /** | ||||
|          *  | ||||
|          * @param {*} [options] Override http request option. | ||||
|          * @throws {RequiredError} | ||||
|          */ | ||||
|         getServerConfig: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { | ||||
|             const localVarPath = `/server-info/config`; | ||||
|             // use dummy base URL string because the URL constructor only accepts absolute URLs.
 | ||||
|             const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); | ||||
|             let baseOptions; | ||||
|             if (configuration) { | ||||
|                 baseOptions = configuration.baseOptions; | ||||
|             } | ||||
| 
 | ||||
|             const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; | ||||
|             const localVarHeaderParameter = {} as any; | ||||
|             const localVarQueryParameter = {} as any; | ||||
| 
 | ||||
| 
 | ||||
|      | ||||
|             setSearchParams(localVarUrlObj, localVarQueryParameter); | ||||
|             let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; | ||||
|             localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; | ||||
| 
 | ||||
|             return { | ||||
|                 url: toPathString(localVarUrlObj), | ||||
|                 options: localVarRequestOptions, | ||||
|             }; | ||||
|         }, | ||||
|         /** | ||||
|          *  | ||||
|          * @param {*} [options] Override http request option. | ||||
| @@ -11027,6 +11112,15 @@ export const ServerInfoApiAxiosParamCreator = function (configuration?: Configur | ||||
| export const ServerInfoApiFp = function(configuration?: Configuration) { | ||||
|     const localVarAxiosParamCreator = ServerInfoApiAxiosParamCreator(configuration) | ||||
|     return { | ||||
|         /** | ||||
|          *  | ||||
|          * @param {*} [options] Override http request option. | ||||
|          * @throws {RequiredError} | ||||
|          */ | ||||
|         async getServerConfig(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ServerConfigDto>> { | ||||
|             const localVarAxiosArgs = await localVarAxiosParamCreator.getServerConfig(options); | ||||
|             return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); | ||||
|         }, | ||||
|         /** | ||||
|          *  | ||||
|          * @param {*} [options] Override http request option. | ||||
| @@ -11091,6 +11185,14 @@ export const ServerInfoApiFp = function(configuration?: Configuration) { | ||||
| export const ServerInfoApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { | ||||
|     const localVarFp = ServerInfoApiFp(configuration) | ||||
|     return { | ||||
|         /** | ||||
|          *  | ||||
|          * @param {*} [options] Override http request option. | ||||
|          * @throws {RequiredError} | ||||
|          */ | ||||
|         getServerConfig(options?: AxiosRequestConfig): AxiosPromise<ServerConfigDto> { | ||||
|             return localVarFp.getServerConfig(options).then((request) => request(axios, basePath)); | ||||
|         }, | ||||
|         /** | ||||
|          *  | ||||
|          * @param {*} [options] Override http request option. | ||||
| @@ -11149,6 +11251,16 @@ export const ServerInfoApiFactory = function (configuration?: Configuration, bas | ||||
|  * @extends {BaseAPI} | ||||
|  */ | ||||
| export class ServerInfoApi extends BaseAPI { | ||||
|     /** | ||||
|      *  | ||||
|      * @param {*} [options] Override http request option. | ||||
|      * @throws {RequiredError} | ||||
|      * @memberof ServerInfoApi | ||||
|      */ | ||||
|     public getServerConfig(options?: AxiosRequestConfig) { | ||||
|         return ServerInfoApiFp(this.configuration).getServerConfig(options).then((request) => request(this.axios, this.basePath)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      *  | ||||
|      * @param {*} [options] Override http request option. | ||||
|   | ||||
							
								
								
									
										6
									
								
								mobile/openapi/.openapi-generator/FILES
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								mobile/openapi/.openapi-generator/FILES
									
									
									
										generated
									
									
									
								
							| @@ -97,6 +97,7 @@ doc/SearchExploreResponseDto.md | ||||
| doc/SearchFacetCountResponseDto.md | ||||
| doc/SearchFacetResponseDto.md | ||||
| doc/SearchResponseDto.md | ||||
| doc/ServerConfigDto.md | ||||
| doc/ServerFeaturesDto.md | ||||
| doc/ServerInfoApi.md | ||||
| doc/ServerInfoResponseDto.md | ||||
| @@ -116,6 +117,7 @@ doc/SystemConfigDto.md | ||||
| doc/SystemConfigFFmpegDto.md | ||||
| doc/SystemConfigJobDto.md | ||||
| doc/SystemConfigMachineLearningDto.md | ||||
| doc/SystemConfigMapDto.md | ||||
| doc/SystemConfigOAuthDto.md | ||||
| doc/SystemConfigPasswordLoginDto.md | ||||
| doc/SystemConfigStorageTemplateDto.md | ||||
| @@ -249,6 +251,7 @@ lib/model/search_explore_response_dto.dart | ||||
| lib/model/search_facet_count_response_dto.dart | ||||
| lib/model/search_facet_response_dto.dart | ||||
| lib/model/search_response_dto.dart | ||||
| lib/model/server_config_dto.dart | ||||
| lib/model/server_features_dto.dart | ||||
| lib/model/server_info_response_dto.dart | ||||
| lib/model/server_media_types_response_dto.dart | ||||
| @@ -265,6 +268,7 @@ lib/model/system_config_dto.dart | ||||
| lib/model/system_config_f_fmpeg_dto.dart | ||||
| lib/model/system_config_job_dto.dart | ||||
| lib/model/system_config_machine_learning_dto.dart | ||||
| lib/model/system_config_map_dto.dart | ||||
| lib/model/system_config_o_auth_dto.dart | ||||
| lib/model/system_config_password_login_dto.dart | ||||
| lib/model/system_config_storage_template_dto.dart | ||||
| @@ -382,6 +386,7 @@ test/search_explore_response_dto_test.dart | ||||
| test/search_facet_count_response_dto_test.dart | ||||
| test/search_facet_response_dto_test.dart | ||||
| test/search_response_dto_test.dart | ||||
| test/server_config_dto_test.dart | ||||
| test/server_features_dto_test.dart | ||||
| test/server_info_api_test.dart | ||||
| test/server_info_response_dto_test.dart | ||||
| @@ -401,6 +406,7 @@ test/system_config_dto_test.dart | ||||
| test/system_config_f_fmpeg_dto_test.dart | ||||
| test/system_config_job_dto_test.dart | ||||
| test/system_config_machine_learning_dto_test.dart | ||||
| test/system_config_map_dto_test.dart | ||||
| test/system_config_o_auth_dto_test.dart | ||||
| test/system_config_password_login_dto_test.dart | ||||
| test/system_config_storage_template_dto_test.dart | ||||
|   | ||||
							
								
								
									
										3
									
								
								mobile/openapi/README.md
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3
									
								
								mobile/openapi/README.md
									
									
									
										generated
									
									
									
								
							| @@ -142,6 +142,7 @@ Class | Method | HTTP request | Description | ||||
| *PersonApi* | [**updatePerson**](doc//PersonApi.md#updateperson) | **PUT** /person/{id} |  | ||||
| *SearchApi* | [**getExploreData**](doc//SearchApi.md#getexploredata) | **GET** /search/explore |  | ||||
| *SearchApi* | [**search**](doc//SearchApi.md#search) | **GET** /search |  | ||||
| *ServerInfoApi* | [**getServerConfig**](doc//ServerInfoApi.md#getserverconfig) | **GET** /server-info/config |  | ||||
| *ServerInfoApi* | [**getServerFeatures**](doc//ServerInfoApi.md#getserverfeatures) | **GET** /server-info/features |  | ||||
| *ServerInfoApi* | [**getServerInfo**](doc//ServerInfoApi.md#getserverinfo) | **GET** /server-info |  | ||||
| *ServerInfoApi* | [**getServerVersion**](doc//ServerInfoApi.md#getserverversion) | **GET** /server-info/version |  | ||||
| @@ -266,6 +267,7 @@ Class | Method | HTTP request | Description | ||||
|  - [SearchFacetCountResponseDto](doc//SearchFacetCountResponseDto.md) | ||||
|  - [SearchFacetResponseDto](doc//SearchFacetResponseDto.md) | ||||
|  - [SearchResponseDto](doc//SearchResponseDto.md) | ||||
|  - [ServerConfigDto](doc//ServerConfigDto.md) | ||||
|  - [ServerFeaturesDto](doc//ServerFeaturesDto.md) | ||||
|  - [ServerInfoResponseDto](doc//ServerInfoResponseDto.md) | ||||
|  - [ServerMediaTypesResponseDto](doc//ServerMediaTypesResponseDto.md) | ||||
| @@ -282,6 +284,7 @@ Class | Method | HTTP request | Description | ||||
|  - [SystemConfigFFmpegDto](doc//SystemConfigFFmpegDto.md) | ||||
|  - [SystemConfigJobDto](doc//SystemConfigJobDto.md) | ||||
|  - [SystemConfigMachineLearningDto](doc//SystemConfigMachineLearningDto.md) | ||||
|  - [SystemConfigMapDto](doc//SystemConfigMapDto.md) | ||||
|  - [SystemConfigOAuthDto](doc//SystemConfigOAuthDto.md) | ||||
|  - [SystemConfigPasswordLoginDto](doc//SystemConfigPasswordLoginDto.md) | ||||
|  - [SystemConfigStorageTemplateDto](doc//SystemConfigStorageTemplateDto.md) | ||||
|   | ||||
							
								
								
									
										17
									
								
								mobile/openapi/doc/ServerConfigDto.md
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								mobile/openapi/doc/ServerConfigDto.md
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| # openapi.model.ServerConfigDto | ||||
| 
 | ||||
| ## Load the model package | ||||
| ```dart | ||||
| import 'package:openapi/api.dart'; | ||||
| ``` | ||||
| 
 | ||||
| ## Properties | ||||
| Name | Type | Description | Notes | ||||
| ------------ | ------------- | ------------- | ------------- | ||||
| **loginPageMessage** | **String** |  |  | ||||
| **mapTileUrl** | **String** |  |  | ||||
| **oauthButtonText** | **String** |  |  | ||||
| 
 | ||||
| [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										1
									
								
								mobile/openapi/doc/ServerFeaturesDto.md
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								mobile/openapi/doc/ServerFeaturesDto.md
									
									
									
										generated
									
									
									
								
							| @@ -11,6 +11,7 @@ Name | Type | Description | Notes | ||||
| **clipEncode** | **bool** |  |  | ||||
| **configFile** | **bool** |  |  | ||||
| **facialRecognition** | **bool** |  |  | ||||
| **map** | **bool** |  |  | ||||
| **oauth** | **bool** |  |  | ||||
| **oauthAutoLaunch** | **bool** |  |  | ||||
| **passwordLogin** | **bool** |  |  | ||||
|   | ||||
							
								
								
									
										38
									
								
								mobile/openapi/doc/ServerInfoApi.md
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										38
									
								
								mobile/openapi/doc/ServerInfoApi.md
									
									
									
										generated
									
									
									
								
							| @@ -9,6 +9,7 @@ All URIs are relative to */api* | ||||
| 
 | ||||
| Method | HTTP request | Description | ||||
| ------------- | ------------- | ------------- | ||||
| [**getServerConfig**](ServerInfoApi.md#getserverconfig) | **GET** /server-info/config |  | ||||
| [**getServerFeatures**](ServerInfoApi.md#getserverfeatures) | **GET** /server-info/features |  | ||||
| [**getServerInfo**](ServerInfoApi.md#getserverinfo) | **GET** /server-info |  | ||||
| [**getServerVersion**](ServerInfoApi.md#getserverversion) | **GET** /server-info/version |  | ||||
| @@ -17,6 +18,43 @@ Method | HTTP request | Description | ||||
| [**pingServer**](ServerInfoApi.md#pingserver) | **GET** /server-info/ping |  | ||||
| 
 | ||||
| 
 | ||||
| # **getServerConfig** | ||||
| > ServerConfigDto getServerConfig() | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| ### Example | ||||
| ```dart | ||||
| import 'package:openapi/api.dart'; | ||||
| 
 | ||||
| final api_instance = ServerInfoApi(); | ||||
| 
 | ||||
| try { | ||||
|     final result = api_instance.getServerConfig(); | ||||
|     print(result); | ||||
| } catch (e) { | ||||
|     print('Exception when calling ServerInfoApi->getServerConfig: $e\n'); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ### Parameters | ||||
| This endpoint does not need any parameter. | ||||
| 
 | ||||
| ### Return type | ||||
| 
 | ||||
| [**ServerConfigDto**](ServerConfigDto.md) | ||||
| 
 | ||||
| ### Authorization | ||||
| 
 | ||||
| No authorization required | ||||
| 
 | ||||
| ### HTTP request headers | ||||
| 
 | ||||
|  - **Content-Type**: Not defined | ||||
|  - **Accept**: application/json | ||||
| 
 | ||||
| [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) | ||||
| 
 | ||||
| # **getServerFeatures** | ||||
| > ServerFeaturesDto getServerFeatures() | ||||
| 
 | ||||
|   | ||||
							
								
								
									
										1
									
								
								mobile/openapi/doc/SystemConfigDto.md
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								mobile/openapi/doc/SystemConfigDto.md
									
									
									
										generated
									
									
									
								
							| @@ -11,6 +11,7 @@ Name | Type | Description | Notes | ||||
| **ffmpeg** | [**SystemConfigFFmpegDto**](SystemConfigFFmpegDto.md) |  |  | ||||
| **job** | [**SystemConfigJobDto**](SystemConfigJobDto.md) |  |  | ||||
| **machineLearning** | [**SystemConfigMachineLearningDto**](SystemConfigMachineLearningDto.md) |  |  | ||||
| **map** | [**SystemConfigMapDto**](SystemConfigMapDto.md) |  |  | ||||
| **oauth** | [**SystemConfigOAuthDto**](SystemConfigOAuthDto.md) |  |  | ||||
| **passwordLogin** | [**SystemConfigPasswordLoginDto**](SystemConfigPasswordLoginDto.md) |  |  | ||||
| **storageTemplate** | [**SystemConfigStorageTemplateDto**](SystemConfigStorageTemplateDto.md) |  |  | ||||
|   | ||||
							
								
								
									
										16
									
								
								mobile/openapi/doc/SystemConfigMapDto.md
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								mobile/openapi/doc/SystemConfigMapDto.md
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| # openapi.model.SystemConfigMapDto | ||||
| 
 | ||||
| ## Load the model package | ||||
| ```dart | ||||
| import 'package:openapi/api.dart'; | ||||
| ``` | ||||
| 
 | ||||
| ## Properties | ||||
| Name | Type | Description | Notes | ||||
| ------------ | ------------- | ------------- | ------------- | ||||
| **enabled** | **bool** |  |  | ||||
| **tileUrl** | **String** |  |  | ||||
| 
 | ||||
| [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										2
									
								
								mobile/openapi/lib/api.dart
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								mobile/openapi/lib/api.dart
									
									
									
										generated
									
									
									
								
							| @@ -128,6 +128,7 @@ part 'model/search_explore_response_dto.dart'; | ||||
| part 'model/search_facet_count_response_dto.dart'; | ||||
| part 'model/search_facet_response_dto.dart'; | ||||
| part 'model/search_response_dto.dart'; | ||||
| part 'model/server_config_dto.dart'; | ||||
| part 'model/server_features_dto.dart'; | ||||
| part 'model/server_info_response_dto.dart'; | ||||
| part 'model/server_media_types_response_dto.dart'; | ||||
| @@ -144,6 +145,7 @@ part 'model/system_config_dto.dart'; | ||||
| part 'model/system_config_f_fmpeg_dto.dart'; | ||||
| part 'model/system_config_job_dto.dart'; | ||||
| part 'model/system_config_machine_learning_dto.dart'; | ||||
| part 'model/system_config_map_dto.dart'; | ||||
| part 'model/system_config_o_auth_dto.dart'; | ||||
| part 'model/system_config_password_login_dto.dart'; | ||||
| part 'model/system_config_storage_template_dto.dart'; | ||||
|   | ||||
							
								
								
									
										41
									
								
								mobile/openapi/lib/api/server_info_api.dart
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										41
									
								
								mobile/openapi/lib/api/server_info_api.dart
									
									
									
										generated
									
									
									
								
							| @@ -16,6 +16,47 @@ class ServerInfoApi { | ||||
| 
 | ||||
|   final ApiClient apiClient; | ||||
| 
 | ||||
|   /// Performs an HTTP 'GET /server-info/config' operation and returns the [Response]. | ||||
|   Future<Response> getServerConfigWithHttpInfo() async { | ||||
|     // ignore: prefer_const_declarations | ||||
|     final path = r'/server-info/config'; | ||||
| 
 | ||||
|     // ignore: prefer_final_locals | ||||
|     Object? postBody; | ||||
| 
 | ||||
|     final queryParams = <QueryParam>[]; | ||||
|     final headerParams = <String, String>{}; | ||||
|     final formParams = <String, String>{}; | ||||
| 
 | ||||
|     const contentTypes = <String>[]; | ||||
| 
 | ||||
| 
 | ||||
|     return apiClient.invokeAPI( | ||||
|       path, | ||||
|       'GET', | ||||
|       queryParams, | ||||
|       postBody, | ||||
|       headerParams, | ||||
|       formParams, | ||||
|       contentTypes.isEmpty ? null : contentTypes.first, | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   Future<ServerConfigDto?> getServerConfig() async { | ||||
|     final response = await getServerConfigWithHttpInfo(); | ||||
|     if (response.statusCode >= HttpStatus.badRequest) { | ||||
|       throw ApiException(response.statusCode, await _decodeBodyBytes(response)); | ||||
|     } | ||||
|     // When a remote server returns no body with a status of 204, we shall not decode it. | ||||
|     // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" | ||||
|     // FormatException when trying to decode an empty string. | ||||
|     if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { | ||||
|       return await apiClient.deserializeAsync(await _decodeBodyBytes(response), 'ServerConfigDto',) as ServerConfigDto; | ||||
|      | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   /// Performs an HTTP 'GET /server-info/features' operation and returns the [Response]. | ||||
|   Future<Response> getServerFeaturesWithHttpInfo() async { | ||||
|     // ignore: prefer_const_declarations | ||||
|   | ||||
							
								
								
									
										4
									
								
								mobile/openapi/lib/api_client.dart
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								mobile/openapi/lib/api_client.dart
									
									
									
										generated
									
									
									
								
							| @@ -349,6 +349,8 @@ class ApiClient { | ||||
|           return SearchFacetResponseDto.fromJson(value); | ||||
|         case 'SearchResponseDto': | ||||
|           return SearchResponseDto.fromJson(value); | ||||
|         case 'ServerConfigDto': | ||||
|           return ServerConfigDto.fromJson(value); | ||||
|         case 'ServerFeaturesDto': | ||||
|           return ServerFeaturesDto.fromJson(value); | ||||
|         case 'ServerInfoResponseDto': | ||||
| @@ -381,6 +383,8 @@ class ApiClient { | ||||
|           return SystemConfigJobDto.fromJson(value); | ||||
|         case 'SystemConfigMachineLearningDto': | ||||
|           return SystemConfigMachineLearningDto.fromJson(value); | ||||
|         case 'SystemConfigMapDto': | ||||
|           return SystemConfigMapDto.fromJson(value); | ||||
|         case 'SystemConfigOAuthDto': | ||||
|           return SystemConfigOAuthDto.fromJson(value); | ||||
|         case 'SystemConfigPasswordLoginDto': | ||||
|   | ||||
							
								
								
									
										114
									
								
								mobile/openapi/lib/model/server_config_dto.dart
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								mobile/openapi/lib/model/server_config_dto.dart
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| // | ||||
| // AUTO-GENERATED FILE, DO NOT MODIFY! | ||||
| // | ||||
| // @dart=2.12 | ||||
| 
 | ||||
| // ignore_for_file: unused_element, unused_import | ||||
| // ignore_for_file: always_put_required_named_parameters_first | ||||
| // ignore_for_file: constant_identifier_names | ||||
| // ignore_for_file: lines_longer_than_80_chars | ||||
| 
 | ||||
| part of openapi.api; | ||||
| 
 | ||||
| class ServerConfigDto { | ||||
|   /// Returns a new [ServerConfigDto] instance. | ||||
|   ServerConfigDto({ | ||||
|     required this.loginPageMessage, | ||||
|     required this.mapTileUrl, | ||||
|     required this.oauthButtonText, | ||||
|   }); | ||||
| 
 | ||||
|   String loginPageMessage; | ||||
| 
 | ||||
|   String mapTileUrl; | ||||
| 
 | ||||
|   String oauthButtonText; | ||||
| 
 | ||||
|   @override | ||||
|   bool operator ==(Object other) => identical(this, other) || other is ServerConfigDto && | ||||
|      other.loginPageMessage == loginPageMessage && | ||||
|      other.mapTileUrl == mapTileUrl && | ||||
|      other.oauthButtonText == oauthButtonText; | ||||
| 
 | ||||
|   @override | ||||
|   int get hashCode => | ||||
|     // ignore: unnecessary_parenthesis | ||||
|     (loginPageMessage.hashCode) + | ||||
|     (mapTileUrl.hashCode) + | ||||
|     (oauthButtonText.hashCode); | ||||
| 
 | ||||
|   @override | ||||
|   String toString() => 'ServerConfigDto[loginPageMessage=$loginPageMessage, mapTileUrl=$mapTileUrl, oauthButtonText=$oauthButtonText]'; | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() { | ||||
|     final json = <String, dynamic>{}; | ||||
|       json[r'loginPageMessage'] = this.loginPageMessage; | ||||
|       json[r'mapTileUrl'] = this.mapTileUrl; | ||||
|       json[r'oauthButtonText'] = this.oauthButtonText; | ||||
|     return json; | ||||
|   } | ||||
| 
 | ||||
|   /// Returns a new [ServerConfigDto] instance and imports its values from | ||||
|   /// [value] if it's a [Map], null otherwise. | ||||
|   // ignore: prefer_constructors_over_static_methods | ||||
|   static ServerConfigDto? fromJson(dynamic value) { | ||||
|     if (value is Map) { | ||||
|       final json = value.cast<String, dynamic>(); | ||||
| 
 | ||||
|       return ServerConfigDto( | ||||
|         loginPageMessage: mapValueOfType<String>(json, r'loginPageMessage')!, | ||||
|         mapTileUrl: mapValueOfType<String>(json, r'mapTileUrl')!, | ||||
|         oauthButtonText: mapValueOfType<String>(json, r'oauthButtonText')!, | ||||
|       ); | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   static List<ServerConfigDto> listFromJson(dynamic json, {bool growable = false,}) { | ||||
|     final result = <ServerConfigDto>[]; | ||||
|     if (json is List && json.isNotEmpty) { | ||||
|       for (final row in json) { | ||||
|         final value = ServerConfigDto.fromJson(row); | ||||
|         if (value != null) { | ||||
|           result.add(value); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return result.toList(growable: growable); | ||||
|   } | ||||
| 
 | ||||
|   static Map<String, ServerConfigDto> mapFromJson(dynamic json) { | ||||
|     final map = <String, ServerConfigDto>{}; | ||||
|     if (json is Map && json.isNotEmpty) { | ||||
|       json = json.cast<String, dynamic>(); // ignore: parameter_assignments | ||||
|       for (final entry in json.entries) { | ||||
|         final value = ServerConfigDto.fromJson(entry.value); | ||||
|         if (value != null) { | ||||
|           map[entry.key] = value; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return map; | ||||
|   } | ||||
| 
 | ||||
|   // maps a json object with a list of ServerConfigDto-objects as value to a dart map | ||||
|   static Map<String, List<ServerConfigDto>> mapListFromJson(dynamic json, {bool growable = false,}) { | ||||
|     final map = <String, List<ServerConfigDto>>{}; | ||||
|     if (json is Map && json.isNotEmpty) { | ||||
|       // ignore: parameter_assignments | ||||
|       json = json.cast<String, dynamic>(); | ||||
|       for (final entry in json.entries) { | ||||
|         map[entry.key] = ServerConfigDto.listFromJson(entry.value, growable: growable,); | ||||
|       } | ||||
|     } | ||||
|     return map; | ||||
|   } | ||||
| 
 | ||||
|   /// The list of required keys that must be present in a JSON. | ||||
|   static const requiredKeys = <String>{ | ||||
|     'loginPageMessage', | ||||
|     'mapTileUrl', | ||||
|     'oauthButtonText', | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										10
									
								
								mobile/openapi/lib/model/server_features_dto.dart
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										10
									
								
								mobile/openapi/lib/model/server_features_dto.dart
									
									
									
										generated
									
									
									
								
							| @@ -16,6 +16,7 @@ class ServerFeaturesDto { | ||||
|     required this.clipEncode, | ||||
|     required this.configFile, | ||||
|     required this.facialRecognition, | ||||
|     required this.map, | ||||
|     required this.oauth, | ||||
|     required this.oauthAutoLaunch, | ||||
|     required this.passwordLogin, | ||||
| @@ -30,6 +31,8 @@ class ServerFeaturesDto { | ||||
| 
 | ||||
|   bool facialRecognition; | ||||
| 
 | ||||
|   bool map; | ||||
| 
 | ||||
|   bool oauth; | ||||
| 
 | ||||
|   bool oauthAutoLaunch; | ||||
| @@ -47,6 +50,7 @@ class ServerFeaturesDto { | ||||
|      other.clipEncode == clipEncode && | ||||
|      other.configFile == configFile && | ||||
|      other.facialRecognition == facialRecognition && | ||||
|      other.map == map && | ||||
|      other.oauth == oauth && | ||||
|      other.oauthAutoLaunch == oauthAutoLaunch && | ||||
|      other.passwordLogin == passwordLogin && | ||||
| @@ -60,6 +64,7 @@ class ServerFeaturesDto { | ||||
|     (clipEncode.hashCode) + | ||||
|     (configFile.hashCode) + | ||||
|     (facialRecognition.hashCode) + | ||||
|     (map.hashCode) + | ||||
|     (oauth.hashCode) + | ||||
|     (oauthAutoLaunch.hashCode) + | ||||
|     (passwordLogin.hashCode) + | ||||
| @@ -68,13 +73,14 @@ class ServerFeaturesDto { | ||||
|     (tagImage.hashCode); | ||||
| 
 | ||||
|   @override | ||||
|   String toString() => 'ServerFeaturesDto[clipEncode=$clipEncode, configFile=$configFile, facialRecognition=$facialRecognition, oauth=$oauth, oauthAutoLaunch=$oauthAutoLaunch, passwordLogin=$passwordLogin, search=$search, sidecar=$sidecar, tagImage=$tagImage]'; | ||||
|   String toString() => 'ServerFeaturesDto[clipEncode=$clipEncode, configFile=$configFile, facialRecognition=$facialRecognition, map=$map, oauth=$oauth, oauthAutoLaunch=$oauthAutoLaunch, passwordLogin=$passwordLogin, search=$search, sidecar=$sidecar, tagImage=$tagImage]'; | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() { | ||||
|     final json = <String, dynamic>{}; | ||||
|       json[r'clipEncode'] = this.clipEncode; | ||||
|       json[r'configFile'] = this.configFile; | ||||
|       json[r'facialRecognition'] = this.facialRecognition; | ||||
|       json[r'map'] = this.map; | ||||
|       json[r'oauth'] = this.oauth; | ||||
|       json[r'oauthAutoLaunch'] = this.oauthAutoLaunch; | ||||
|       json[r'passwordLogin'] = this.passwordLogin; | ||||
| @@ -95,6 +101,7 @@ class ServerFeaturesDto { | ||||
|         clipEncode: mapValueOfType<bool>(json, r'clipEncode')!, | ||||
|         configFile: mapValueOfType<bool>(json, r'configFile')!, | ||||
|         facialRecognition: mapValueOfType<bool>(json, r'facialRecognition')!, | ||||
|         map: mapValueOfType<bool>(json, r'map')!, | ||||
|         oauth: mapValueOfType<bool>(json, r'oauth')!, | ||||
|         oauthAutoLaunch: mapValueOfType<bool>(json, r'oauthAutoLaunch')!, | ||||
|         passwordLogin: mapValueOfType<bool>(json, r'passwordLogin')!, | ||||
| @@ -151,6 +158,7 @@ class ServerFeaturesDto { | ||||
|     'clipEncode', | ||||
|     'configFile', | ||||
|     'facialRecognition', | ||||
|     'map', | ||||
|     'oauth', | ||||
|     'oauthAutoLaunch', | ||||
|     'passwordLogin', | ||||
|   | ||||
							
								
								
									
										10
									
								
								mobile/openapi/lib/model/system_config_dto.dart
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										10
									
								
								mobile/openapi/lib/model/system_config_dto.dart
									
									
									
										generated
									
									
									
								
							| @@ -16,6 +16,7 @@ class SystemConfigDto { | ||||
|     required this.ffmpeg, | ||||
|     required this.job, | ||||
|     required this.machineLearning, | ||||
|     required this.map, | ||||
|     required this.oauth, | ||||
|     required this.passwordLogin, | ||||
|     required this.storageTemplate, | ||||
| @@ -28,6 +29,8 @@ class SystemConfigDto { | ||||
| 
 | ||||
|   SystemConfigMachineLearningDto machineLearning; | ||||
| 
 | ||||
|   SystemConfigMapDto map; | ||||
| 
 | ||||
|   SystemConfigOAuthDto oauth; | ||||
| 
 | ||||
|   SystemConfigPasswordLoginDto passwordLogin; | ||||
| @@ -41,6 +44,7 @@ class SystemConfigDto { | ||||
|      other.ffmpeg == ffmpeg && | ||||
|      other.job == job && | ||||
|      other.machineLearning == machineLearning && | ||||
|      other.map == map && | ||||
|      other.oauth == oauth && | ||||
|      other.passwordLogin == passwordLogin && | ||||
|      other.storageTemplate == storageTemplate && | ||||
| @@ -52,19 +56,21 @@ class SystemConfigDto { | ||||
|     (ffmpeg.hashCode) + | ||||
|     (job.hashCode) + | ||||
|     (machineLearning.hashCode) + | ||||
|     (map.hashCode) + | ||||
|     (oauth.hashCode) + | ||||
|     (passwordLogin.hashCode) + | ||||
|     (storageTemplate.hashCode) + | ||||
|     (thumbnail.hashCode); | ||||
| 
 | ||||
|   @override | ||||
|   String toString() => 'SystemConfigDto[ffmpeg=$ffmpeg, job=$job, machineLearning=$machineLearning, oauth=$oauth, passwordLogin=$passwordLogin, storageTemplate=$storageTemplate, thumbnail=$thumbnail]'; | ||||
|   String toString() => 'SystemConfigDto[ffmpeg=$ffmpeg, job=$job, machineLearning=$machineLearning, map=$map, oauth=$oauth, passwordLogin=$passwordLogin, storageTemplate=$storageTemplate, thumbnail=$thumbnail]'; | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() { | ||||
|     final json = <String, dynamic>{}; | ||||
|       json[r'ffmpeg'] = this.ffmpeg; | ||||
|       json[r'job'] = this.job; | ||||
|       json[r'machineLearning'] = this.machineLearning; | ||||
|       json[r'map'] = this.map; | ||||
|       json[r'oauth'] = this.oauth; | ||||
|       json[r'passwordLogin'] = this.passwordLogin; | ||||
|       json[r'storageTemplate'] = this.storageTemplate; | ||||
| @@ -83,6 +89,7 @@ class SystemConfigDto { | ||||
|         ffmpeg: SystemConfigFFmpegDto.fromJson(json[r'ffmpeg'])!, | ||||
|         job: SystemConfigJobDto.fromJson(json[r'job'])!, | ||||
|         machineLearning: SystemConfigMachineLearningDto.fromJson(json[r'machineLearning'])!, | ||||
|         map: SystemConfigMapDto.fromJson(json[r'map'])!, | ||||
|         oauth: SystemConfigOAuthDto.fromJson(json[r'oauth'])!, | ||||
|         passwordLogin: SystemConfigPasswordLoginDto.fromJson(json[r'passwordLogin'])!, | ||||
|         storageTemplate: SystemConfigStorageTemplateDto.fromJson(json[r'storageTemplate'])!, | ||||
| @@ -137,6 +144,7 @@ class SystemConfigDto { | ||||
|     'ffmpeg', | ||||
|     'job', | ||||
|     'machineLearning', | ||||
|     'map', | ||||
|     'oauth', | ||||
|     'passwordLogin', | ||||
|     'storageTemplate', | ||||
|   | ||||
							
								
								
									
										106
									
								
								mobile/openapi/lib/model/system_config_map_dto.dart
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								mobile/openapi/lib/model/system_config_map_dto.dart
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| // | ||||
| // AUTO-GENERATED FILE, DO NOT MODIFY! | ||||
| // | ||||
| // @dart=2.12 | ||||
| 
 | ||||
| // ignore_for_file: unused_element, unused_import | ||||
| // ignore_for_file: always_put_required_named_parameters_first | ||||
| // ignore_for_file: constant_identifier_names | ||||
| // ignore_for_file: lines_longer_than_80_chars | ||||
| 
 | ||||
| part of openapi.api; | ||||
| 
 | ||||
| class SystemConfigMapDto { | ||||
|   /// Returns a new [SystemConfigMapDto] instance. | ||||
|   SystemConfigMapDto({ | ||||
|     required this.enabled, | ||||
|     required this.tileUrl, | ||||
|   }); | ||||
| 
 | ||||
|   bool enabled; | ||||
| 
 | ||||
|   String tileUrl; | ||||
| 
 | ||||
|   @override | ||||
|   bool operator ==(Object other) => identical(this, other) || other is SystemConfigMapDto && | ||||
|      other.enabled == enabled && | ||||
|      other.tileUrl == tileUrl; | ||||
| 
 | ||||
|   @override | ||||
|   int get hashCode => | ||||
|     // ignore: unnecessary_parenthesis | ||||
|     (enabled.hashCode) + | ||||
|     (tileUrl.hashCode); | ||||
| 
 | ||||
|   @override | ||||
|   String toString() => 'SystemConfigMapDto[enabled=$enabled, tileUrl=$tileUrl]'; | ||||
| 
 | ||||
|   Map<String, dynamic> toJson() { | ||||
|     final json = <String, dynamic>{}; | ||||
|       json[r'enabled'] = this.enabled; | ||||
|       json[r'tileUrl'] = this.tileUrl; | ||||
|     return json; | ||||
|   } | ||||
| 
 | ||||
|   /// Returns a new [SystemConfigMapDto] instance and imports its values from | ||||
|   /// [value] if it's a [Map], null otherwise. | ||||
|   // ignore: prefer_constructors_over_static_methods | ||||
|   static SystemConfigMapDto? fromJson(dynamic value) { | ||||
|     if (value is Map) { | ||||
|       final json = value.cast<String, dynamic>(); | ||||
| 
 | ||||
|       return SystemConfigMapDto( | ||||
|         enabled: mapValueOfType<bool>(json, r'enabled')!, | ||||
|         tileUrl: mapValueOfType<String>(json, r'tileUrl')!, | ||||
|       ); | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
| 
 | ||||
|   static List<SystemConfigMapDto> listFromJson(dynamic json, {bool growable = false,}) { | ||||
|     final result = <SystemConfigMapDto>[]; | ||||
|     if (json is List && json.isNotEmpty) { | ||||
|       for (final row in json) { | ||||
|         final value = SystemConfigMapDto.fromJson(row); | ||||
|         if (value != null) { | ||||
|           result.add(value); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return result.toList(growable: growable); | ||||
|   } | ||||
| 
 | ||||
|   static Map<String, SystemConfigMapDto> mapFromJson(dynamic json) { | ||||
|     final map = <String, SystemConfigMapDto>{}; | ||||
|     if (json is Map && json.isNotEmpty) { | ||||
|       json = json.cast<String, dynamic>(); // ignore: parameter_assignments | ||||
|       for (final entry in json.entries) { | ||||
|         final value = SystemConfigMapDto.fromJson(entry.value); | ||||
|         if (value != null) { | ||||
|           map[entry.key] = value; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return map; | ||||
|   } | ||||
| 
 | ||||
|   // maps a json object with a list of SystemConfigMapDto-objects as value to a dart map | ||||
|   static Map<String, List<SystemConfigMapDto>> mapListFromJson(dynamic json, {bool growable = false,}) { | ||||
|     final map = <String, List<SystemConfigMapDto>>{}; | ||||
|     if (json is Map && json.isNotEmpty) { | ||||
|       // ignore: parameter_assignments | ||||
|       json = json.cast<String, dynamic>(); | ||||
|       for (final entry in json.entries) { | ||||
|         map[entry.key] = SystemConfigMapDto.listFromJson(entry.value, growable: growable,); | ||||
|       } | ||||
|     } | ||||
|     return map; | ||||
|   } | ||||
| 
 | ||||
|   /// The list of required keys that must be present in a JSON. | ||||
|   static const requiredKeys = <String>{ | ||||
|     'enabled', | ||||
|     'tileUrl', | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										37
									
								
								mobile/openapi/test/server_config_dto_test.dart
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								mobile/openapi/test/server_config_dto_test.dart
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| // | ||||
| // AUTO-GENERATED FILE, DO NOT MODIFY! | ||||
| // | ||||
| // @dart=2.12 | ||||
| 
 | ||||
| // ignore_for_file: unused_element, unused_import | ||||
| // ignore_for_file: always_put_required_named_parameters_first | ||||
| // ignore_for_file: constant_identifier_names | ||||
| // ignore_for_file: lines_longer_than_80_chars | ||||
| 
 | ||||
| import 'package:openapi/api.dart'; | ||||
| import 'package:test/test.dart'; | ||||
| 
 | ||||
| // tests for ServerConfigDto | ||||
| void main() { | ||||
|   // final instance = ServerConfigDto(); | ||||
| 
 | ||||
|   group('test ServerConfigDto', () { | ||||
|     // String loginPageMessage | ||||
|     test('to test the property `loginPageMessage`', () async { | ||||
|       // TODO | ||||
|     }); | ||||
| 
 | ||||
|     // String mapTileUrl | ||||
|     test('to test the property `mapTileUrl`', () async { | ||||
|       // TODO | ||||
|     }); | ||||
| 
 | ||||
|     // String oauthButtonText | ||||
|     test('to test the property `oauthButtonText`', () async { | ||||
|       // TODO | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|   }); | ||||
| 
 | ||||
| } | ||||
| @@ -31,6 +31,11 @@ void main() { | ||||
|       // TODO | ||||
|     }); | ||||
| 
 | ||||
|     // bool map | ||||
|     test('to test the property `map`', () async { | ||||
|       // TODO | ||||
|     }); | ||||
| 
 | ||||
|     // bool oauth | ||||
|     test('to test the property `oauth`', () async { | ||||
|       // TODO | ||||
|   | ||||
							
								
								
									
										5
									
								
								mobile/openapi/test/server_info_api_test.dart
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5
									
								
								mobile/openapi/test/server_info_api_test.dart
									
									
									
										generated
									
									
									
								
							| @@ -17,6 +17,11 @@ void main() { | ||||
|   // final instance = ServerInfoApi(); | ||||
| 
 | ||||
|   group('tests for ServerInfoApi', () { | ||||
|     //Future<ServerConfigDto> getServerConfig() async | ||||
|     test('test getServerConfig', () async { | ||||
|       // TODO | ||||
|     }); | ||||
| 
 | ||||
|     //Future<ServerFeaturesDto> getServerFeatures() async | ||||
|     test('test getServerFeatures', () async { | ||||
|       // TODO | ||||
|   | ||||
							
								
								
									
										5
									
								
								mobile/openapi/test/system_config_dto_test.dart
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5
									
								
								mobile/openapi/test/system_config_dto_test.dart
									
									
									
										generated
									
									
									
								
							| @@ -31,6 +31,11 @@ void main() { | ||||
|       // TODO | ||||
|     }); | ||||
| 
 | ||||
|     // SystemConfigMapDto map | ||||
|     test('to test the property `map`', () async { | ||||
|       // TODO | ||||
|     }); | ||||
| 
 | ||||
|     // SystemConfigOAuthDto oauth | ||||
|     test('to test the property `oauth`', () async { | ||||
|       // TODO | ||||
|   | ||||
							
								
								
									
										32
									
								
								mobile/openapi/test/system_config_map_dto_test.dart
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								mobile/openapi/test/system_config_map_dto_test.dart
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| // | ||||
| // AUTO-GENERATED FILE, DO NOT MODIFY! | ||||
| // | ||||
| // @dart=2.12 | ||||
| 
 | ||||
| // ignore_for_file: unused_element, unused_import | ||||
| // ignore_for_file: always_put_required_named_parameters_first | ||||
| // ignore_for_file: constant_identifier_names | ||||
| // ignore_for_file: lines_longer_than_80_chars | ||||
| 
 | ||||
| import 'package:openapi/api.dart'; | ||||
| import 'package:test/test.dart'; | ||||
| 
 | ||||
| // tests for SystemConfigMapDto | ||||
| void main() { | ||||
|   // final instance = SystemConfigMapDto(); | ||||
| 
 | ||||
|   group('test SystemConfigMapDto', () { | ||||
|     // bool enabled | ||||
|     test('to test the property `enabled`', () async { | ||||
|       // TODO | ||||
|     }); | ||||
| 
 | ||||
|     // String tileUrl | ||||
|     test('to test the property `tileUrl`', () async { | ||||
|       // TODO | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|   }); | ||||
| 
 | ||||
| } | ||||
| @@ -3342,6 +3342,27 @@ | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|     "/server-info/config": { | ||||
|       "get": { | ||||
|         "operationId": "getServerConfig", | ||||
|         "parameters": [], | ||||
|         "responses": { | ||||
|           "200": { | ||||
|             "content": { | ||||
|               "application/json": { | ||||
|                 "schema": { | ||||
|                   "$ref": "#/components/schemas/ServerConfigDto" | ||||
|                 } | ||||
|               } | ||||
|             }, | ||||
|             "description": "" | ||||
|           } | ||||
|         }, | ||||
|         "tags": [ | ||||
|           "Server Info" | ||||
|         ] | ||||
|       } | ||||
|     }, | ||||
|     "/server-info/features": { | ||||
|       "get": { | ||||
|         "operationId": "getServerFeatures", | ||||
| @@ -6618,6 +6639,25 @@ | ||||
|         ], | ||||
|         "type": "object" | ||||
|       }, | ||||
|       "ServerConfigDto": { | ||||
|         "properties": { | ||||
|           "loginPageMessage": { | ||||
|             "type": "string" | ||||
|           }, | ||||
|           "mapTileUrl": { | ||||
|             "type": "string" | ||||
|           }, | ||||
|           "oauthButtonText": { | ||||
|             "type": "string" | ||||
|           } | ||||
|         }, | ||||
|         "required": [ | ||||
|           "oauthButtonText", | ||||
|           "loginPageMessage", | ||||
|           "mapTileUrl" | ||||
|         ], | ||||
|         "type": "object" | ||||
|       }, | ||||
|       "ServerFeaturesDto": { | ||||
|         "properties": { | ||||
|           "clipEncode": { | ||||
| @@ -6629,6 +6669,9 @@ | ||||
|           "facialRecognition": { | ||||
|             "type": "boolean" | ||||
|           }, | ||||
|           "map": { | ||||
|             "type": "boolean" | ||||
|           }, | ||||
|           "oauth": { | ||||
|             "type": "boolean" | ||||
|           }, | ||||
| @@ -6649,15 +6692,16 @@ | ||||
|           } | ||||
|         }, | ||||
|         "required": [ | ||||
|           "configFile", | ||||
|           "clipEncode", | ||||
|           "configFile", | ||||
|           "facialRecognition", | ||||
|           "sidecar", | ||||
|           "search", | ||||
|           "tagImage", | ||||
|           "map", | ||||
|           "oauth", | ||||
|           "oauthAutoLaunch", | ||||
|           "passwordLogin" | ||||
|           "passwordLogin", | ||||
|           "sidecar", | ||||
|           "search", | ||||
|           "tagImage" | ||||
|         ], | ||||
|         "type": "object" | ||||
|       }, | ||||
| @@ -6989,6 +7033,9 @@ | ||||
|           "machineLearning": { | ||||
|             "$ref": "#/components/schemas/SystemConfigMachineLearningDto" | ||||
|           }, | ||||
|           "map": { | ||||
|             "$ref": "#/components/schemas/SystemConfigMapDto" | ||||
|           }, | ||||
|           "oauth": { | ||||
|             "$ref": "#/components/schemas/SystemConfigOAuthDto" | ||||
|           }, | ||||
| @@ -7005,6 +7052,7 @@ | ||||
|         "required": [ | ||||
|           "ffmpeg", | ||||
|           "machineLearning", | ||||
|           "map", | ||||
|           "oauth", | ||||
|           "passwordLogin", | ||||
|           "storageTemplate", | ||||
| @@ -7162,6 +7210,21 @@ | ||||
|         ], | ||||
|         "type": "object" | ||||
|       }, | ||||
|       "SystemConfigMapDto": { | ||||
|         "properties": { | ||||
|           "enabled": { | ||||
|             "type": "boolean" | ||||
|           }, | ||||
|           "tileUrl": { | ||||
|             "type": "string" | ||||
|           } | ||||
|         }, | ||||
|         "required": [ | ||||
|           "enabled", | ||||
|           "tileUrl" | ||||
|         ], | ||||
|         "type": "object" | ||||
|       }, | ||||
|       "SystemConfigOAuthDto": { | ||||
|         "properties": { | ||||
|           "autoLaunch": { | ||||
|   | ||||
| @@ -79,16 +79,21 @@ export class ServerMediaTypesResponseDto { | ||||
|   sidecar!: string[]; | ||||
| } | ||||
|  | ||||
| export class ServerFeaturesDto implements FeatureFlags { | ||||
|   configFile!: boolean; | ||||
|   clipEncode!: boolean; | ||||
|   facialRecognition!: boolean; | ||||
|   sidecar!: boolean; | ||||
|   search!: boolean; | ||||
|   tagImage!: boolean; | ||||
| export class ServerConfigDto { | ||||
|   oauthButtonText!: string; | ||||
|   loginPageMessage!: string; | ||||
|   mapTileUrl!: string; | ||||
| } | ||||
|  | ||||
|   // TODO: use these instead of `POST oauth/config` | ||||
| export class ServerFeaturesDto implements FeatureFlags { | ||||
|   clipEncode!: boolean; | ||||
|   configFile!: boolean; | ||||
|   facialRecognition!: boolean; | ||||
|   map!: boolean; | ||||
|   oauth!: boolean; | ||||
|   oauthAutoLaunch!: boolean; | ||||
|   passwordLogin!: boolean; | ||||
|   sidecar!: boolean; | ||||
|   search!: boolean; | ||||
|   tagImage!: boolean; | ||||
| } | ||||
|   | ||||
| @@ -143,12 +143,14 @@ describe(ServerInfoService.name, () => { | ||||
|     it('should respond the server version', () => { | ||||
|       expect(sut.getVersion()).toEqual(serverVersion); | ||||
|     }); | ||||
|   }); | ||||
|  | ||||
|   describe('getFeatures', () => { | ||||
|     it('should respond the server features', async () => { | ||||
|       await expect(sut.getFeatures()).resolves.toEqual({ | ||||
|         clipEncode: true, | ||||
|         facialRecognition: true, | ||||
|         map: true, | ||||
|         oauth: false, | ||||
|         oauthAutoLaunch: false, | ||||
|         passwordLogin: true, | ||||
| @@ -160,6 +162,16 @@ describe(ServerInfoService.name, () => { | ||||
|       expect(configMock.load).toHaveBeenCalled(); | ||||
|     }); | ||||
|   }); | ||||
|  | ||||
|   describe('getConfig', () => { | ||||
|     it('should respond the server configuration', async () => { | ||||
|       await expect(sut.getConfig()).resolves.toEqual({ | ||||
|         loginPageMessage: '', | ||||
|         oauthButtonText: 'Login with OAuth', | ||||
|         mapTileUrl: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', | ||||
|       }); | ||||
|       expect(configMock.load).toHaveBeenCalled(); | ||||
|     }); | ||||
|   }); | ||||
|  | ||||
|   describe('getStats', () => { | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import { IStorageRepository, StorageCore, StorageFolder } from '../storage'; | ||||
| import { ISystemConfigRepository, SystemConfigCore } from '../system-config'; | ||||
| import { IUserRepository, UserStatsQueryResponse } from '../user'; | ||||
| import { | ||||
|   ServerConfigDto, | ||||
|   ServerFeaturesDto, | ||||
|   ServerInfoResponseDto, | ||||
|   ServerMediaTypesResponseDto, | ||||
| @@ -55,6 +56,19 @@ export class ServerInfoService { | ||||
|     return this.configCore.getFeatures(); | ||||
|   } | ||||
|  | ||||
|   async getConfig(): Promise<ServerConfigDto> { | ||||
|     const config = await this.configCore.getConfig(); | ||||
|  | ||||
|     // TODO move to system config | ||||
|     const loginPageMessage = process.env.PUBLIC_LOGIN_PAGE_MESSAGE || ''; | ||||
|  | ||||
|     return { | ||||
|       loginPageMessage, | ||||
|       mapTileUrl: config.map.tileUrl, | ||||
|       oauthButtonText: config.oauth.buttonText, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   async getStats(): Promise<ServerStatsResponseDto> { | ||||
|     const userStats: UserStatsQueryResponse[] = await this.userRepository.getUserStats(); | ||||
|     const serverStats = new ServerStatsResponseDto(); | ||||
|   | ||||
| @@ -0,0 +1,9 @@ | ||||
| import { IsBoolean, IsString } from 'class-validator'; | ||||
|  | ||||
| export class SystemConfigMapDto { | ||||
|   @IsBoolean() | ||||
|   enabled!: boolean; | ||||
|  | ||||
|   @IsString() | ||||
|   tileUrl!: string; | ||||
| } | ||||
| @@ -5,6 +5,7 @@ import { IsObject, ValidateNested } from 'class-validator'; | ||||
| import { SystemConfigFFmpegDto } from './system-config-ffmpeg.dto'; | ||||
| import { SystemConfigJobDto } from './system-config-job.dto'; | ||||
| import { SystemConfigMachineLearningDto } from './system-config-machine-learning.dto'; | ||||
| import { SystemConfigMapDto } from './system-config-map.dto'; | ||||
| import { SystemConfigOAuthDto } from './system-config-oauth.dto'; | ||||
| import { SystemConfigPasswordLoginDto } from './system-config-password-login.dto'; | ||||
| import { SystemConfigStorageTemplateDto } from './system-config-storage-template.dto'; | ||||
| @@ -20,6 +21,11 @@ export class SystemConfigDto implements SystemConfig { | ||||
|   @IsObject() | ||||
|   machineLearning!: SystemConfigMachineLearningDto; | ||||
|  | ||||
|   @Type(() => SystemConfigMapDto) | ||||
|   @ValidateNested() | ||||
|   @IsObject() | ||||
|   map!: SystemConfigMapDto; | ||||
|  | ||||
|   @Type(() => SystemConfigOAuthDto) | ||||
|   @ValidateNested() | ||||
|   @IsObject() | ||||
|   | ||||
| @@ -55,7 +55,6 @@ export const defaults = Object.freeze<SystemConfig>({ | ||||
|     [QueueName.THUMBNAIL_GENERATION]: { concurrency: 5 }, | ||||
|     [QueueName.VIDEO_CONVERSION]: { concurrency: 1 }, | ||||
|   }, | ||||
|  | ||||
|   machineLearning: { | ||||
|     enabled: process.env.IMMICH_MACHINE_LEARNING_ENABLED !== 'false', | ||||
|     url: process.env.IMMICH_MACHINE_LEARNING_URL || 'http://immich-machine-learning:3003', | ||||
| @@ -75,6 +74,10 @@ export const defaults = Object.freeze<SystemConfig>({ | ||||
|       maxDistance: 0.6, | ||||
|     }, | ||||
|   }, | ||||
|   map: { | ||||
|     enabled: true, | ||||
|     tileUrl: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', | ||||
|   }, | ||||
|   oauth: { | ||||
|     enabled: false, | ||||
|     issuerUrl: '', | ||||
| @@ -108,6 +111,7 @@ export enum FeatureFlag { | ||||
|   CLIP_ENCODE = 'clipEncode', | ||||
|   FACIAL_RECOGNITION = 'facialRecognition', | ||||
|   TAG_IMAGE = 'tagImage', | ||||
|   MAP = 'map', | ||||
|   SIDECAR = 'sidecar', | ||||
|   SEARCH = 'search', | ||||
|   OAUTH = 'oauth', | ||||
| @@ -169,6 +173,7 @@ export class SystemConfigCore { | ||||
|       [FeatureFlag.CLIP_ENCODE]: mlEnabled && config.machineLearning.clip.enabled, | ||||
|       [FeatureFlag.FACIAL_RECOGNITION]: mlEnabled && config.machineLearning.facialRecognition.enabled, | ||||
|       [FeatureFlag.TAG_IMAGE]: mlEnabled && config.machineLearning.classification.enabled, | ||||
|       [FeatureFlag.MAP]: config.map.enabled, | ||||
|       [FeatureFlag.SIDECAR]: true, | ||||
|       [FeatureFlag.SEARCH]: process.env.TYPESENSE_ENABLED !== 'false', | ||||
|  | ||||
|   | ||||
| @@ -73,6 +73,10 @@ const updatedConfig = Object.freeze<SystemConfig>({ | ||||
|       maxDistance: 0.6, | ||||
|     }, | ||||
|   }, | ||||
|   map: { | ||||
|     enabled: true, | ||||
|     tileUrl: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', | ||||
|   }, | ||||
|   oauth: { | ||||
|     autoLaunch: true, | ||||
|     autoRegister: true, | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import { | ||||
|   ServerConfigDto, | ||||
|   ServerFeaturesDto, | ||||
|   ServerInfoResponseDto, | ||||
|   ServerInfoService, | ||||
| @@ -42,6 +43,12 @@ export class ServerInfoController { | ||||
|     return this.service.getFeatures(); | ||||
|   } | ||||
|  | ||||
|   @PublicRoute() | ||||
|   @Get('config') | ||||
|   getServerConfig(): Promise<ServerConfigDto> { | ||||
|     return this.service.getConfig(); | ||||
|   } | ||||
|  | ||||
|   @AdminRoute() | ||||
|   @Get('stats') | ||||
|   getStats(): Promise<ServerStatsResponseDto> { | ||||
|   | ||||
| @@ -58,6 +58,9 @@ export enum SystemConfigKey { | ||||
|   MACHINE_LEARNING_FACIAL_RECOGNITION_MIN_SCORE = 'machineLearning.facialRecognition.minScore', | ||||
|   MACHINE_LEARNING_FACIAL_RECOGNITION_MAX_DISTANCE = 'machineLearning.facialRecognition.maxDistance', | ||||
|  | ||||
|   MAP_ENABLED = 'map.enabled', | ||||
|   MAP_TILE_URL = 'map.tileUrl', | ||||
|  | ||||
|   OAUTH_ENABLED = 'oauth.enabled', | ||||
|   OAUTH_ISSUER_URL = 'oauth.issuerUrl', | ||||
|   OAUTH_CLIENT_ID = 'oauth.clientId', | ||||
| @@ -164,6 +167,10 @@ export interface SystemConfig { | ||||
|       maxDistance: number; | ||||
|     }; | ||||
|   }; | ||||
|   map: { | ||||
|     enabled: boolean; | ||||
|     tileUrl: string; | ||||
|   }; | ||||
|   oauth: { | ||||
|     enabled: boolean; | ||||
|     issuerUrl: string; | ||||
|   | ||||
| @@ -83,6 +83,7 @@ describe(`${ServerInfoController.name} (e2e)`, () => { | ||||
|         clipEncode: true, | ||||
|         configFile: false, | ||||
|         facialRecognition: true, | ||||
|         map: true, | ||||
|         oauth: false, | ||||
|         oauthAutoLaunch: false, | ||||
|         passwordLogin: true, | ||||
| @@ -93,6 +94,18 @@ describe(`${ServerInfoController.name} (e2e)`, () => { | ||||
|     }); | ||||
|   }); | ||||
|  | ||||
|   describe('GET /server-info/config', () => { | ||||
|     it('should respond with the server configuration', async () => { | ||||
|       const { status, body } = await request(server).get('/server-info/config'); | ||||
|       expect(status).toBe(200); | ||||
|       expect(body).toEqual({ | ||||
|         loginPageMessage: '', | ||||
|         oauthButtonText: 'Login with OAuth', | ||||
|         mapTileUrl: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', | ||||
|       }); | ||||
|     }); | ||||
|   }); | ||||
|  | ||||
|   describe('GET /server-info/stats', () => { | ||||
|     it('should require authentication', async () => { | ||||
|       const { status, body } = await request(server).get('/server-info/stats'); | ||||
|   | ||||
							
								
								
									
										112
									
								
								web/src/api/open-api/api.ts
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										112
									
								
								web/src/api/open-api/api.ts
									
									
									
										generated
									
									
									
								
							| @@ -2343,6 +2343,31 @@ export interface SearchResponseDto { | ||||
|      */ | ||||
|     'assets': SearchAssetResponseDto; | ||||
| } | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
|  * @interface ServerConfigDto | ||||
|  */ | ||||
| export interface ServerConfigDto { | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof ServerConfigDto | ||||
|      */ | ||||
|     'loginPageMessage': string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof ServerConfigDto | ||||
|      */ | ||||
|     'mapTileUrl': string; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof ServerConfigDto | ||||
|      */ | ||||
|     'oauthButtonText': string; | ||||
| } | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
| @@ -2367,6 +2392,12 @@ export interface ServerFeaturesDto { | ||||
|      * @memberof ServerFeaturesDto | ||||
|      */ | ||||
|     'facialRecognition': boolean; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {boolean} | ||||
|      * @memberof ServerFeaturesDto | ||||
|      */ | ||||
|     'map': boolean; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {boolean} | ||||
| @@ -2810,6 +2841,12 @@ export interface SystemConfigDto { | ||||
|      * @memberof SystemConfigDto | ||||
|      */ | ||||
|     'machineLearning': SystemConfigMachineLearningDto; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {SystemConfigMapDto} | ||||
|      * @memberof SystemConfigDto | ||||
|      */ | ||||
|     'map': SystemConfigMapDto; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {SystemConfigOAuthDto} | ||||
| @@ -3050,6 +3087,25 @@ export interface SystemConfigMachineLearningDto { | ||||
|      */ | ||||
|     'url': string; | ||||
| } | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
|  * @interface SystemConfigMapDto | ||||
|  */ | ||||
| export interface SystemConfigMapDto { | ||||
|     /** | ||||
|      *  | ||||
|      * @type {boolean} | ||||
|      * @memberof SystemConfigMapDto | ||||
|      */ | ||||
|     'enabled': boolean; | ||||
|     /** | ||||
|      *  | ||||
|      * @type {string} | ||||
|      * @memberof SystemConfigMapDto | ||||
|      */ | ||||
|     'tileUrl': string; | ||||
| } | ||||
| /** | ||||
|  *  | ||||
|  * @export | ||||
| @@ -10825,6 +10881,35 @@ export class SearchApi extends BaseAPI { | ||||
|  */ | ||||
| export const ServerInfoApiAxiosParamCreator = function (configuration?: Configuration) { | ||||
|     return { | ||||
|         /** | ||||
|          *  | ||||
|          * @param {*} [options] Override http request option. | ||||
|          * @throws {RequiredError} | ||||
|          */ | ||||
|         getServerConfig: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => { | ||||
|             const localVarPath = `/server-info/config`; | ||||
|             // use dummy base URL string because the URL constructor only accepts absolute URLs.
 | ||||
|             const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); | ||||
|             let baseOptions; | ||||
|             if (configuration) { | ||||
|                 baseOptions = configuration.baseOptions; | ||||
|             } | ||||
| 
 | ||||
|             const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; | ||||
|             const localVarHeaderParameter = {} as any; | ||||
|             const localVarQueryParameter = {} as any; | ||||
| 
 | ||||
| 
 | ||||
|      | ||||
|             setSearchParams(localVarUrlObj, localVarQueryParameter); | ||||
|             let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; | ||||
|             localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; | ||||
| 
 | ||||
|             return { | ||||
|                 url: toPathString(localVarUrlObj), | ||||
|                 options: localVarRequestOptions, | ||||
|             }; | ||||
|         }, | ||||
|         /** | ||||
|          *  | ||||
|          * @param {*} [options] Override http request option. | ||||
| @@ -11027,6 +11112,15 @@ export const ServerInfoApiAxiosParamCreator = function (configuration?: Configur | ||||
| export const ServerInfoApiFp = function(configuration?: Configuration) { | ||||
|     const localVarAxiosParamCreator = ServerInfoApiAxiosParamCreator(configuration) | ||||
|     return { | ||||
|         /** | ||||
|          *  | ||||
|          * @param {*} [options] Override http request option. | ||||
|          * @throws {RequiredError} | ||||
|          */ | ||||
|         async getServerConfig(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ServerConfigDto>> { | ||||
|             const localVarAxiosArgs = await localVarAxiosParamCreator.getServerConfig(options); | ||||
|             return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); | ||||
|         }, | ||||
|         /** | ||||
|          *  | ||||
|          * @param {*} [options] Override http request option. | ||||
| @@ -11091,6 +11185,14 @@ export const ServerInfoApiFp = function(configuration?: Configuration) { | ||||
| export const ServerInfoApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { | ||||
|     const localVarFp = ServerInfoApiFp(configuration) | ||||
|     return { | ||||
|         /** | ||||
|          *  | ||||
|          * @param {*} [options] Override http request option. | ||||
|          * @throws {RequiredError} | ||||
|          */ | ||||
|         getServerConfig(options?: AxiosRequestConfig): AxiosPromise<ServerConfigDto> { | ||||
|             return localVarFp.getServerConfig(options).then((request) => request(axios, basePath)); | ||||
|         }, | ||||
|         /** | ||||
|          *  | ||||
|          * @param {*} [options] Override http request option. | ||||
| @@ -11149,6 +11251,16 @@ export const ServerInfoApiFactory = function (configuration?: Configuration, bas | ||||
|  * @extends {BaseAPI} | ||||
|  */ | ||||
| export class ServerInfoApi extends BaseAPI { | ||||
|     /** | ||||
|      *  | ||||
|      * @param {*} [options] Override http request option. | ||||
|      * @throws {RequiredError} | ||||
|      * @memberof ServerInfoApi | ||||
|      */ | ||||
|     public getServerConfig(options?: AxiosRequestConfig) { | ||||
|         return ServerInfoApiFp(this.configuration).getServerConfig(options).then((request) => request(this.axios, this.basePath)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      *  | ||||
|      * @param {*} [options] Override http request option. | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|     NotificationType, | ||||
|   } from '$lib/components/shared-components/notification/notification'; | ||||
|   import { AppRoute } from '$lib/constants'; | ||||
|   import { featureFlags } from '$lib/stores/feature-flags.store'; | ||||
|   import { featureFlags } from '$lib/stores/server-config.store'; | ||||
|   import { handleError } from '$lib/utils/handle-error'; | ||||
|   import { AllJobStatusResponseDto, api, JobCommand, JobCommandDto, JobName } from '@api'; | ||||
|   import type { ComponentType } from 'svelte'; | ||||
|   | ||||
| @@ -0,0 +1,98 @@ | ||||
| <script lang="ts"> | ||||
|   import { | ||||
|     notificationController, | ||||
|     NotificationType, | ||||
|   } from '$lib/components/shared-components/notification/notification'; | ||||
|   import { handleError } from '$lib/utils/handle-error'; | ||||
|   import { api, SystemConfigMapDto } from '@api'; | ||||
|   import { isEqual } from 'lodash-es'; | ||||
|   import { fade } from 'svelte/transition'; | ||||
|   import SettingButtonsRow from '../setting-buttons-row.svelte'; | ||||
|   import SettingSwitch from '../setting-switch.svelte'; | ||||
|   import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte'; | ||||
|  | ||||
|   export let mapConfig: SystemConfigMapDto; // this is the config that is being edited | ||||
|   export let disabled = false; | ||||
|  | ||||
|   let savedConfig: SystemConfigMapDto; | ||||
|   let defaultConfig: SystemConfigMapDto; | ||||
|  | ||||
|   async function getConfigs() { | ||||
|     [savedConfig, defaultConfig] = await Promise.all([ | ||||
|       api.systemConfigApi.getConfig().then((res) => res.data.map), | ||||
|       api.systemConfigApi.getDefaults().then((res) => res.data.map), | ||||
|     ]); | ||||
|   } | ||||
|  | ||||
|   async function saveSetting() { | ||||
|     try { | ||||
|       const { data: current } = await api.systemConfigApi.getConfig(); | ||||
|       const { data: updated } = await api.systemConfigApi.updateConfig({ | ||||
|         systemConfigDto: { ...current, map: mapConfig }, | ||||
|       }); | ||||
|  | ||||
|       mapConfig = { ...updated.map }; | ||||
|       savedConfig = { ...updated.map }; | ||||
|  | ||||
|       notificationController.show({ message: 'Settings saved', type: NotificationType.Info }); | ||||
|     } catch (error) { | ||||
|       handleError(error, 'Unable to save settings'); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async function reset() { | ||||
|     const { data: resetConfig } = await api.systemConfigApi.getConfig(); | ||||
|  | ||||
|     mapConfig = { ...resetConfig.map }; | ||||
|     savedConfig = { ...resetConfig.map }; | ||||
|  | ||||
|     notificationController.show({ | ||||
|       message: 'Reset settings to the recent saved settings', | ||||
|       type: NotificationType.Info, | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   async function resetToDefault() { | ||||
|     const { data: configs } = await api.systemConfigApi.getDefaults(); | ||||
|  | ||||
|     mapConfig = { ...configs.map }; | ||||
|     defaultConfig = { ...configs.map }; | ||||
|  | ||||
|     notificationController.show({ | ||||
|       message: 'Reset map settings to default', | ||||
|       type: NotificationType.Info, | ||||
|     }); | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <div> | ||||
|   {#await getConfigs() then} | ||||
|     <div in:fade={{ duration: 500 }}> | ||||
|       <form autocomplete="off" on:submit|preventDefault> | ||||
|         <div class="ml-4 mt-4 flex flex-col gap-4"> | ||||
|           <SettingSwitch title="ENABLED" {disabled} subtitle="Enable map features" bind:checked={mapConfig.enabled} /> | ||||
|  | ||||
|           <hr /> | ||||
|  | ||||
|           <SettingInputField | ||||
|             inputType={SettingInputFieldType.TEXT} | ||||
|             label="Tile URL" | ||||
|             desc="URL to a leaflet compatible tile server" | ||||
|             bind:value={mapConfig.tileUrl} | ||||
|             required={true} | ||||
|             disabled={disabled || !mapConfig.enabled} | ||||
|             isEdited={mapConfig.tileUrl !== savedConfig.tileUrl} | ||||
|           /> | ||||
|  | ||||
|           <SettingButtonsRow | ||||
|             on:reset={reset} | ||||
|             on:save={saveSetting} | ||||
|             on:reset-to-default={resetToDefault} | ||||
|             showResetToDefault={!isEqual(savedConfig, defaultConfig)} | ||||
|             {disabled} | ||||
|           /> | ||||
|         </div> | ||||
|       </form> | ||||
|     </div> | ||||
|   {/await} | ||||
| </div> | ||||
| @@ -1,18 +1,19 @@ | ||||
| <script lang="ts"> | ||||
|   import { page } from '$app/stores'; | ||||
|   import { locale } from '$lib/stores/preferences.store'; | ||||
|   import { featureFlags, serverConfig } from '$lib/stores/server-config.store'; | ||||
|   import { getAssetFilename } from '$lib/utils/asset-utils'; | ||||
|   import { AlbumResponseDto, AssetResponseDto, ThumbnailFormat, api } from '@api'; | ||||
|   import type { LatLngTuple } from 'leaflet'; | ||||
|   import { DateTime } from 'luxon'; | ||||
|   import { createEventDispatcher } from 'svelte'; | ||||
|   import Calendar from 'svelte-material-icons/Calendar.svelte'; | ||||
|   import CameraIris from 'svelte-material-icons/CameraIris.svelte'; | ||||
|   import Close from 'svelte-material-icons/Close.svelte'; | ||||
|   import ImageOutline from 'svelte-material-icons/ImageOutline.svelte'; | ||||
|   import MapMarkerOutline from 'svelte-material-icons/MapMarkerOutline.svelte'; | ||||
|   import { createEventDispatcher } from 'svelte'; | ||||
|   import { AssetResponseDto, AlbumResponseDto, api, ThumbnailFormat } from '@api'; | ||||
|   import { asByteUnitString } from '../../utils/byte-units'; | ||||
|   import ImageThumbnail from '../assets/thumbnail/image-thumbnail.svelte'; | ||||
|   import { getAssetFilename } from '$lib/utils/asset-utils'; | ||||
|   import UserAvatar from '../shared-components/user-avatar.svelte'; | ||||
|  | ||||
|   export let asset: AssetResponseDto; | ||||
| @@ -268,12 +269,12 @@ | ||||
|   </div> | ||||
| </section> | ||||
|  | ||||
| {#if latlng} | ||||
| {#if latlng && $featureFlags.loaded && $featureFlags.map} | ||||
|   <div class="h-[360px]"> | ||||
|     {#await import('../shared-components/leaflet') then { Map, TileLayer, Marker }} | ||||
|       <Map center={latlng} zoom={14}> | ||||
|         <TileLayer | ||||
|           urlTemplate={'https://tile.openstreetmap.org/{z}/{x}/{y}.png'} | ||||
|           urlTemplate={$serverConfig.mapTileUrl} | ||||
|           options={{ | ||||
|             attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>', | ||||
|           }} | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|   import { goto } from '$app/navigation'; | ||||
|   import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte'; | ||||
|   import { AppRoute } from '$lib/constants'; | ||||
|   import { featureFlags } from '$lib/stores/feature-flags.store'; | ||||
|   import { featureFlags, serverConfig } from '$lib/stores/server-config.store'; | ||||
|   import { getServerErrorMessage, handleError } from '$lib/utils/handle-error'; | ||||
|   import { api, oauth } from '@api'; | ||||
|   import { createEventDispatcher, onMount } from 'svelte'; | ||||
| @@ -158,7 +158,7 @@ | ||||
|           <LoadingSpinner /> | ||||
|         </span> | ||||
|       {:else} | ||||
|         {$featureFlags.passwordLogin ? 'Login with OAuth' : 'Login'} | ||||
|         {$serverConfig.oauthButtonText} | ||||
|       {/if} | ||||
|     </Button> | ||||
|   </div> | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <script lang="ts"> | ||||
|   import { onDestroy, onMount } from 'svelte'; | ||||
|   import { TileLayer, type TileLayerOptions } from 'leaflet'; | ||||
|   import { onDestroy, onMount } from 'svelte'; | ||||
|   import { getMapContext } from './map.svelte'; | ||||
|  | ||||
|   export let urlTemplate: string; | ||||
| @@ -15,6 +15,6 @@ | ||||
|   }); | ||||
|  | ||||
|   onDestroy(() => { | ||||
|     if (tileLayer) tileLayer.remove(); | ||||
|     tileLayer?.remove(); | ||||
|   }); | ||||
| </script> | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|   import IconButton from '$lib/components/elements/buttons/icon-button.svelte'; | ||||
|   import Cog from 'svelte-material-icons/Cog.svelte'; | ||||
|   import UserAvatar from '../user-avatar.svelte'; | ||||
|   import { featureFlags } from '$lib/stores/feature-flags.store'; | ||||
|   import { featureFlags } from '$lib/stores/server-config.store'; | ||||
|   export let user: UserResponseDto; | ||||
|   export let showUploadButton = true; | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,7 @@ | ||||
|   import SideBarButton from './side-bar-button.svelte'; | ||||
|   import { locale } from '$lib/stores/preferences.store'; | ||||
|   import SideBarSection from './side-bar-section.svelte'; | ||||
|   import { featureFlags } from '$lib/stores/feature-flags.store'; | ||||
|   import { featureFlags } from '$lib/stores/server-config.store'; | ||||
|  | ||||
|   const getStats = async (dto: AssetApiGetAssetStatsRequest) => { | ||||
|     const { data: stats } = await api.assetApi.getAssetStats(dto); | ||||
| @@ -62,9 +62,11 @@ | ||||
|       <SideBarButton title="Explore" logo={Magnify} isSelected={$page.route.id === '/(user)/explore'} /> | ||||
|     </a> | ||||
|   {/if} | ||||
|   {#if $featureFlags.map} | ||||
|     <a data-sveltekit-preload-data="hover" href={AppRoute.MAP} draggable="false"> | ||||
|       <SideBarButton title="Map" logo={Map} isSelected={$page.route.id === '/(user)/map'} /> | ||||
|     </a> | ||||
|   {/if} | ||||
|   <a data-sveltekit-preload-data="hover" href={AppRoute.SHARING} draggable="false"> | ||||
|     <SideBarButton | ||||
|       title="Sharing" | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <script lang="ts"> | ||||
|   import { goto } from '$app/navigation'; | ||||
|   import { featureFlags } from '$lib/stores/feature-flags.store'; | ||||
|   import { featureFlags } from '$lib/stores/server-config.store'; | ||||
|   import { oauth, UserResponseDto } from '@api'; | ||||
|   import { onMount } from 'svelte'; | ||||
|   import { fade } from 'svelte/transition'; | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| <script lang="ts"> | ||||
|   import { browser } from '$app/environment'; | ||||
|   import { page } from '$app/stores'; | ||||
|   import { featureFlags } from '$lib/stores/feature-flags.store'; | ||||
|   import { featureFlags } from '$lib/stores/server-config.store'; | ||||
|   import { APIKeyResponseDto, AuthDeviceResponseDto, oauth, UserResponseDto } from '@api'; | ||||
|   import SettingAccordion from '../admin-page/settings/setting-accordion.svelte'; | ||||
|   import ChangePasswordSettings from './change-password-settings.svelte'; | ||||
|   | ||||
| @@ -1,6 +1,3 @@ | ||||
| import { env } from '$env/dynamic/public'; | ||||
| export const loginPageMessage: string | undefined = env.PUBLIC_LOGIN_PAGE_MESSAGE; | ||||
|  | ||||
| export enum AssetAction { | ||||
|   ARCHIVE = 'archive', | ||||
|   UNARCHIVE = 'unarchive', | ||||
|   | ||||
| @@ -1,22 +0,0 @@ | ||||
| import { api, ServerFeaturesDto } from '@api'; | ||||
| import { writable } from 'svelte/store'; | ||||
|  | ||||
| export type FeatureFlags = ServerFeaturesDto & { loaded: boolean }; | ||||
|  | ||||
| export const featureFlags = writable<FeatureFlags>({ | ||||
|   loaded: false, | ||||
|   clipEncode: true, | ||||
|   facialRecognition: true, | ||||
|   sidecar: true, | ||||
|   tagImage: true, | ||||
|   search: true, | ||||
|   oauth: false, | ||||
|   oauthAutoLaunch: false, | ||||
|   passwordLogin: true, | ||||
|   configFile: false, | ||||
| }); | ||||
|  | ||||
| export const loadFeatureFlags = async () => { | ||||
|   const { data } = await api.serverInfoApi.getServerFeatures(); | ||||
|   featureFlags.update(() => ({ ...data, loaded: true })); | ||||
| }; | ||||
							
								
								
									
										37
									
								
								web/src/lib/stores/server-config.store.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								web/src/lib/stores/server-config.store.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| import { api, ServerConfigDto, ServerFeaturesDto } from '@api'; | ||||
| import { writable } from 'svelte/store'; | ||||
|  | ||||
| export type FeatureFlags = ServerFeaturesDto & { loaded: boolean }; | ||||
|  | ||||
| export const featureFlags = writable<FeatureFlags>({ | ||||
|   loaded: false, | ||||
|   clipEncode: true, | ||||
|   facialRecognition: true, | ||||
|   sidecar: true, | ||||
|   tagImage: true, | ||||
|   map: true, | ||||
|   search: true, | ||||
|   oauth: false, | ||||
|   oauthAutoLaunch: false, | ||||
|   passwordLogin: true, | ||||
|   configFile: false, | ||||
| }); | ||||
|  | ||||
| export type ServerConfig = ServerConfigDto & { loaded: boolean }; | ||||
|  | ||||
| export const serverConfig = writable<ServerConfig>({ | ||||
|   loaded: false, | ||||
|   oauthButtonText: '', | ||||
|   mapTileUrl: '', | ||||
|   loginPageMessage: '', | ||||
| }); | ||||
|  | ||||
| export const loadConfig = async () => { | ||||
|   const [{ data: flags }, { data: config }] = await Promise.all([ | ||||
|     api.serverInfoApi.getServerFeatures(), | ||||
|     api.serverInfoApi.getServerConfig(), | ||||
|   ]); | ||||
|  | ||||
|   featureFlags.update(() => ({ ...flags, loaded: true })); | ||||
|   serverConfig.update(() => ({ ...config, loaded: true })); | ||||
| }; | ||||
| @@ -1,16 +1,19 @@ | ||||
| <script lang="ts"> | ||||
|   import { goto } from '$app/navigation'; | ||||
|   import AssetViewer from '$lib/components/asset-viewer/asset-viewer.svelte'; | ||||
|   import UserPageLayout from '$lib/components/layouts/user-page-layout.svelte'; | ||||
|   import MapSettingsModal from '$lib/components/map-page/map-settings-modal.svelte'; | ||||
|   import Portal from '$lib/components/shared-components/portal/portal.svelte'; | ||||
|   import { AppRoute } from '$lib/constants'; | ||||
|   import { assetViewingStore } from '$lib/stores/asset-viewing.store'; | ||||
|   import { mapSettings } from '$lib/stores/preferences.store'; | ||||
|   import { featureFlags, serverConfig } from '$lib/stores/server-config.store'; | ||||
|   import { MapMarkerResponseDto, api } from '@api'; | ||||
|   import { isEqual, omit } from 'lodash-es'; | ||||
|   import { DateTime, Duration } from 'luxon'; | ||||
|   import { onDestroy, onMount } from 'svelte'; | ||||
|   import Cog from 'svelte-material-icons/Cog.svelte'; | ||||
|   import type { PageData } from './$types'; | ||||
|   import { DateTime, Duration } from 'luxon'; | ||||
|   import { assetViewingStore } from '$lib/stores/asset-viewing.store'; | ||||
|  | ||||
|   export let data: PageData; | ||||
|  | ||||
| @@ -29,12 +32,12 @@ | ||||
|   }); | ||||
|  | ||||
|   onDestroy(() => { | ||||
|     if (abortController) { | ||||
|       abortController.abort(); | ||||
|     } | ||||
|     abortController?.abort(); | ||||
|     assetViewingStore.showAssetViewer(false); | ||||
|   }); | ||||
|  | ||||
|   $: $featureFlags.map || goto(AppRoute.PHOTOS); | ||||
|  | ||||
|   async function loadMapMarkers() { | ||||
|     if (abortController) { | ||||
|       abortController.abort(); | ||||
| @@ -98,7 +101,8 @@ | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <UserPageLayout user={data.user} title={data.meta.title}> | ||||
| {#if $featureFlags.loaded && $featureFlags.map} | ||||
|   <UserPageLayout user={data.user} title={data.meta.title}> | ||||
|     <div class="isolate h-full w-full"> | ||||
|       {#if leaflet} | ||||
|         {@const { Map, TileLayer, AssetMarkerCluster, Control } = leaflet} | ||||
| @@ -115,7 +119,7 @@ | ||||
|           }} | ||||
|         > | ||||
|           <TileLayer | ||||
|           urlTemplate={'https://tile.openstreetmap.org/{z}/{x}/{y}.png'} | ||||
|             urlTemplate={$serverConfig.mapTileUrl} | ||||
|             options={{ | ||||
|               attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>', | ||||
|             }} | ||||
| @@ -136,9 +140,9 @@ | ||||
|         </Map> | ||||
|       {/if} | ||||
|     </div> | ||||
| </UserPageLayout> | ||||
|   </UserPageLayout> | ||||
|  | ||||
| <Portal target="body"> | ||||
|   <Portal target="body"> | ||||
|     {#if $showAssetViewer} | ||||
|       <AssetViewer | ||||
|         asset={$viewingAsset} | ||||
| @@ -148,9 +152,9 @@ | ||||
|         on:close={() => assetViewingStore.showAssetViewer(false)} | ||||
|       /> | ||||
|     {/if} | ||||
| </Portal> | ||||
|   </Portal> | ||||
|  | ||||
| {#if showSettingsModal} | ||||
|   {#if showSettingsModal} | ||||
|     <MapSettingsModal | ||||
|       settings={{ ...$mapSettings }} | ||||
|       on:close={() => (showSettingsModal = false)} | ||||
| @@ -164,4 +168,5 @@ | ||||
|         } | ||||
|       }} | ||||
|     /> | ||||
|   {/if} | ||||
| {/if} | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
|   import AppleHeader from '$lib/components/shared-components/apple-header.svelte'; | ||||
|   import FaviconHeader from '$lib/components/shared-components/favicon-header.svelte'; | ||||
|   import { onMount } from 'svelte'; | ||||
|   import { loadFeatureFlags } from '$lib/stores/feature-flags.store'; | ||||
|   import { loadConfig } from '$lib/stores/server-config.store'; | ||||
|   import { handleError } from '$lib/utils/handle-error'; | ||||
|   import { dragAndDropFilesStore } from '$lib/stores/drag-and-drop-files.store'; | ||||
|   import { api } from '@api'; | ||||
| @@ -37,9 +37,9 @@ | ||||
|  | ||||
|   onMount(async () => { | ||||
|     try { | ||||
|       await loadFeatureFlags(); | ||||
|       await loadConfig(); | ||||
|     } catch (error) { | ||||
|       handleError(error, 'Unable to load feature flags'); | ||||
|       handleError(error, 'Unable to connect to server'); | ||||
|     } | ||||
|   }); | ||||
|  | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
|   import FFmpegSettings from '$lib/components/admin-page/settings/ffmpeg/ffmpeg-settings.svelte'; | ||||
|   import JobSettings from '$lib/components/admin-page/settings/job-settings/job-settings.svelte'; | ||||
|   import MachineLearningSettings from '$lib/components/admin-page/settings/machine-learning-settings/machine-learning-settings.svelte'; | ||||
|   import MapSettings from '$lib/components/admin-page/settings/map-settings/map-settings.svelte'; | ||||
|   import OAuthSettings from '$lib/components/admin-page/settings/oauth/oauth-settings.svelte'; | ||||
|   import PasswordLoginSettings from '$lib/components/admin-page/settings/password-login/password-login-settings.svelte'; | ||||
|   import SettingAccordion from '$lib/components/admin-page/settings/setting-accordion.svelte'; | ||||
| @@ -11,7 +12,7 @@ | ||||
|   import Button from '$lib/components/elements/buttons/button.svelte'; | ||||
|   import LoadingSpinner from '$lib/components/shared-components/loading-spinner.svelte'; | ||||
|   import { downloadManager } from '$lib/stores/download'; | ||||
|   import { featureFlags } from '$lib/stores/feature-flags.store'; | ||||
|   import { featureFlags } from '$lib/stores/server-config.store'; | ||||
|   import { downloadBlob } from '$lib/utils/asset-utils'; | ||||
|   import { SystemConfigDto, api, copyToClipboard } from '@api'; | ||||
|   import Alert from 'svelte-material-icons/Alert.svelte'; | ||||
| @@ -57,20 +58,6 @@ | ||||
|         <span class="pl-2">Export as JSON</span> | ||||
|       </Button> | ||||
|     </div> | ||||
|     <SettingAccordion title="Thumbnail Settings" subtitle="Manage the resolution of thumbnail sizes"> | ||||
|       <ThumbnailSettings disabled={$featureFlags.configFile} thumbnailConfig={configs.thumbnail} /> | ||||
|     </SettingAccordion> | ||||
|  | ||||
|     <SettingAccordion | ||||
|       title="Video Transcoding Settings" | ||||
|       subtitle="Manage the resolution and encoding information of the video files" | ||||
|     > | ||||
|       <FFmpegSettings disabled={$featureFlags.configFile} ffmpegConfig={configs.ffmpeg} /> | ||||
|     </SettingAccordion> | ||||
|  | ||||
|     <SettingAccordion title="Machine Learning Settings" subtitle="Manage model settings"> | ||||
|       <MachineLearningSettings disabled={$featureFlags.configFile} machineLearningConfig={configs.machineLearning} /> | ||||
|     </SettingAccordion> | ||||
|  | ||||
|     <SettingAccordion | ||||
|       title="Job Settings" | ||||
| @@ -80,14 +67,22 @@ | ||||
|       <JobSettings disabled={$featureFlags.configFile} jobConfig={configs.job} /> | ||||
|     </SettingAccordion> | ||||
|  | ||||
|     <SettingAccordion title="Password Authentication" subtitle="Manage login with password settings"> | ||||
|       <PasswordLoginSettings disabled={$featureFlags.configFile} passwordLoginConfig={configs.passwordLogin} /> | ||||
|     <SettingAccordion title="Machine Learning Settings" subtitle="Manage model settings"> | ||||
|       <MachineLearningSettings disabled={$featureFlags.configFile} machineLearningConfig={configs.machineLearning} /> | ||||
|     </SettingAccordion> | ||||
|  | ||||
|     <SettingAccordion title="Map Settings" subtitle="Manage map settings"> | ||||
|       <MapSettings disabled={$featureFlags.configFile} mapConfig={configs.map} /> | ||||
|     </SettingAccordion> | ||||
|  | ||||
|     <SettingAccordion title="OAuth Authentication" subtitle="Manage the login with OAuth settings"> | ||||
|       <OAuthSettings disabled={$featureFlags.configFile} oauthConfig={configs.oauth} /> | ||||
|     </SettingAccordion> | ||||
|  | ||||
|     <SettingAccordion title="Password Authentication" subtitle="Manage login with password settings"> | ||||
|       <PasswordLoginSettings disabled={$featureFlags.configFile} passwordLoginConfig={configs.passwordLogin} /> | ||||
|     </SettingAccordion> | ||||
|  | ||||
|     <SettingAccordion | ||||
|       title="Storage Template" | ||||
|       subtitle="Manage the folder structure and file name of the upload asset" | ||||
| @@ -99,5 +94,16 @@ | ||||
|         user={data.user} | ||||
|       /> | ||||
|     </SettingAccordion> | ||||
|  | ||||
|     <SettingAccordion title="Thumbnail Settings" subtitle="Manage the resolution of thumbnail sizes"> | ||||
|       <ThumbnailSettings disabled={$featureFlags.configFile} thumbnailConfig={configs.thumbnail} /> | ||||
|     </SettingAccordion> | ||||
|  | ||||
|     <SettingAccordion | ||||
|       title="Video Transcoding Settings" | ||||
|       subtitle="Manage the resolution and encoding information of the video files" | ||||
|     > | ||||
|       <FFmpegSettings disabled={$featureFlags.configFile} ffmpegConfig={configs.ffmpeg} /> | ||||
|     </SettingAccordion> | ||||
|   {/await} | ||||
| </section> | ||||
|   | ||||
| @@ -3,18 +3,17 @@ | ||||
|   import LoginForm from '$lib/components/forms/login-form.svelte'; | ||||
|   import FullscreenContainer from '$lib/components/shared-components/fullscreen-container.svelte'; | ||||
|   import { AppRoute } from '$lib/constants'; | ||||
|   import { loginPageMessage } from '$lib/constants'; | ||||
|   import { featureFlags } from '$lib/stores/feature-flags.store'; | ||||
|   import { featureFlags, serverConfig } from '$lib/stores/server-config.store'; | ||||
|   import type { PageData } from './$types'; | ||||
|  | ||||
|   export let data: PageData; | ||||
| </script> | ||||
|  | ||||
| {#if $featureFlags.loaded} | ||||
|   <FullscreenContainer title={data.meta.title} showMessage={!!loginPageMessage}> | ||||
|   <FullscreenContainer title={data.meta.title} showMessage={!!$serverConfig.loginPageMessage}> | ||||
|     <p slot="message"> | ||||
|       <!-- eslint-disable-next-line svelte/no-at-html-tags --> | ||||
|       {@html loginPageMessage} | ||||
|       {@html $serverConfig.loginPageMessage} | ||||
|     </p> | ||||
|  | ||||
|     <LoginForm | ||||
|   | ||||
		Reference in New Issue
	
	Block a user