Skip to content

Commit

Permalink
Server settings (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdlukaa authored Nov 27, 2023
2 parents 9a11fe8 + ef2d0ec commit 01f8aca
Show file tree
Hide file tree
Showing 29 changed files with 897 additions and 353 deletions.
12 changes: 12 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@
"videoError": "An error happened while trying to play the video.",
"ok": "OK",
"retry": "Retry",
"clear": "Clear",
"serverSettings": "Server settings",
"serverSettingsDescription": "Settings that will only be applied to this server. If they are not provided, the values from General Settings will be used. You can change these values later.",
"editServerSettingsInfo": "Edit server settings",
"editServerSettings": "Edit server settings {serverName}",
"@editServerSettings": {
"placeholders": {
"serverName": {
"type": "String"
}
}
},
"removeCamera": "Remove Camera",
"replaceCamera": "Replace Camera",
"reloadCamera": "Reload Camera",
Expand Down
12 changes: 12 additions & 0 deletions lib/l10n/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@
"videoError": "Une erreur est survenue lors de la lecture de la vidé.",
"ok": "OK",
"retry": "Réessayer",
"clear": "Clear",
"serverSettings": "Server settings",
"serverSettingsDescription": "Settings that will only be applied to this server. If they are not provided, the values from General Settings will be used. You can change these values later.",
"editServerSettingsInfo": "Edit server settings",
"editServerSettings": "Edit server settings",
"@editServerSettings": {
"placeholders": {
"serverName": {
"type": "String"
}
}
},
"removeCamera": "Enlever caméra",
"replaceCamera": "Remplacer caméra",
"reloadCamera": "Recharger caméra",
Expand Down
12 changes: 12 additions & 0 deletions lib/l10n/app_pl.arb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@
"videoError": "An error happened while trying to play the video.",
"ok": "OK",
"retry": "Spróbuj ponownie",
"clear": "Clear",
"serverSettings": "Server settings",
"serverSettingsDescription": "Settings that will only be applied to this server. If they are not provided, the values from General Settings will be used. You can change these values later.",
"editServerSettingsInfo": "Edit server settings",
"editServerSettings": "Edit server settings",
"@editServerSettings": {
"placeholders": {
"serverName": {
"type": "String"
}
}
},
"removeCamera": "Usuń kamerę",
"replaceCamera": "Zastąp kamerę",
"reloadCamera": "Odśwież kamerę",
Expand Down
22 changes: 17 additions & 5 deletions lib/l10n/app_pt.arb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"@@locale": "pt",
"welcome": "Bem vindo!",
"welcomeDescription": "Sea bem vindo ao Bluecherry Surveillance DVR!\nVamos conectar ao seu servidor DVR em um instante!",
"welcomeDescription": "Seja bem vindo ao Bluecherry Surveillance DVR!\nVamos conectar ao seu servidor DVR em um instante!",
"configure": "Configure um Servidor DVR",
"configureDescription": "Configure uma conexão com seu servidor DVR remoto. Você pode se conectar a quantos servidores quiser de qualquer lugar do mundo.",
"hostname": "Hostname",
Expand Down Expand Up @@ -63,6 +63,18 @@
"videoError": "Ocorreu um erro ao tentar reproduzir o vídeo.",
"ok": "OK",
"retry": "Tentar novamente",
"clear": "Limpar",
"serverSettings": "Configurações do servidor",
"serverSettingsDescription": "Configurações que serão aplicadas apenas a este servidor. Se não forem selectionados, os valores de Configurações serão usados. Você pode alterar esses valores posteriormente.",
"editServerSettingsInfo": "Editar Configurações do servidor",
"editServerSettings": "Editar configurações do servidor {serverName}",
"@editServerSettings": {
"placeholders": {
"serverName": {
"type": "String"
}
}
},
"removeCamera": "Remover Câmera",
"replaceCamera": "Substituir Câmera",
"reloadCamera": "Recarregar Câmera",
Expand Down Expand Up @@ -218,8 +230,8 @@
"downloadPath": "Diretório de Download",
"delete": "Deletar",
"showInFiles": "Ver no Explorador de Arquivos",
"noDownloads": "Você ainda não fez o download de nenhum evento :/",
"howToDownload": " ao \"Histórico de Eventos\" para fazer o download de eventos.",
"noDownloads": "Você ainda não baixou nenhum evento :/",
"howToDownload": " ao \"Histórico de Eventos\" para baixar eventos.",
"downloadTitle": "{event} de {device} do servidor {server} em {date}",
"@downloadTitle": {
"placeholders": {
Expand Down Expand Up @@ -403,8 +415,8 @@
"@@MISC": {},
"general": "Geral",
"miscellaneous": "Outros",
"wakelock": "Deixar tela ligada",
"wakelockDescription": "Mantenha a tela ligada enquanto estiver assistindo a streams ao vivo ou gravações",
"wakelock": "Manter tela ativa",
"wakelockDescription": "Mantenha a tela ativa enquanto estiver assistindo a transmissões ao vivo ou gravações",
"@Snoozing": {},
"snooze15": "15 minutos",
"snooze30": "30 minutos",
Expand Down
2 changes: 1 addition & 1 deletion lib/models/device.dart
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class Device {

/// The preferred streaming type.
///
/// If not provided, defaults to the type declared in the app settings.
/// If not provided, defaults to [Server.preferredStreamingType]
final StreamingType? preferredStreamingType;

/// The external device data.
Expand Down
135 changes: 126 additions & 9 deletions lib/models/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,121 @@
*/

import 'package:bluecherry_client/models/device.dart';
import 'package:bluecherry_client/providers/settings_provider.dart';
import 'package:bluecherry_client/utils/constants.dart';
import 'package:bluecherry_client/utils/extensions.dart';
import 'package:flutter/foundation.dart';
import 'package:unity_video_player/unity_video_player.dart';

class AdditionalServerOptions {
/// Whether to connect to this server automatically at startup.
///
/// If false, the server will have to be connected to manually.
final bool connectAutomaticallyAtStartup;

/// The preferred streaming type.
///
/// If not provided, defaults to the type declared in the app settings.
final StreamingType? preferredStreamingType;

/// The preferred RTSP protocol when the streaming type is RTSP.
final RTSPProtocol? rtspProtocol;

/// The quality of the video rendering.
final RenderingQuality? renderingQuality;

/// The preferred video fit.
final UnityVideoFit? videoFit;

const AdditionalServerOptions({
this.connectAutomaticallyAtStartup = true,
this.preferredStreamingType,
this.rtspProtocol,
this.renderingQuality,
this.videoFit,
});

AdditionalServerOptions copyWith({
bool? connectAutomaticallyAtStartup,
StreamingType? preferredStreamingType,
RTSPProtocol? rtspProtocol,
RenderingQuality? renderingQuality,
UnityVideoFit? videoFit,
}) {
return AdditionalServerOptions(
connectAutomaticallyAtStartup:
connectAutomaticallyAtStartup ?? this.connectAutomaticallyAtStartup,
preferredStreamingType:
preferredStreamingType ?? this.preferredStreamingType,
rtspProtocol: rtspProtocol ?? this.rtspProtocol,
renderingQuality: renderingQuality ?? this.renderingQuality,
videoFit: videoFit ?? this.videoFit,
);
}

Map<String, dynamic> toMap() {
return {
'connectAutomaticallyAtStartup': connectAutomaticallyAtStartup,
'preferredStreamingType': preferredStreamingType?.name,
'rtspProtocol': rtspProtocol?.name,
'renderingQuality': renderingQuality?.name,
'videoFit': videoFit?.name,
};
}

factory AdditionalServerOptions.fromMap(Map<String, dynamic> map) {
return AdditionalServerOptions(
connectAutomaticallyAtStartup:
map['connectAutomaticallyAtStartup'] ?? false,
preferredStreamingType: map['preferredStreamingType'] != null
? StreamingType.values.firstWhereOrNull(
(type) => type.name == map['preferredStreamingType'],
)
: null,
rtspProtocol: map['rtspProtocol'] != null
? RTSPProtocol.values.firstWhereOrNull(
(type) => type.name == map['rtspProtocol'],
)
: null,
renderingQuality: map['renderingQuality'] != null
? RenderingQuality.values.firstWhereOrNull(
(type) => type.name == map['renderingQuality'],
)
: null,
videoFit: map['videoFit'] != null
? UnityVideoFit.values.firstWhereOrNull(
(type) => type.name == map['videoFit'],
)
: null,
);
}

@override
String toString() {
return 'AdditionalServerOptions(connectAutomaticallyAtStartup: $connectAutomaticallyAtStartup, preferredStreamingType: $preferredStreamingType, rtspProtocol: $rtspProtocol, renderingQuality: $renderingQuality, videoFit: $videoFit)';
}

@override
bool operator ==(Object other) {
if (identical(this, other)) return true;

return other is AdditionalServerOptions &&
other.connectAutomaticallyAtStartup == connectAutomaticallyAtStartup &&
other.preferredStreamingType == preferredStreamingType &&
other.rtspProtocol == rtspProtocol &&
other.renderingQuality == renderingQuality &&
other.videoFit == videoFit;
}

@override
int get hashCode {
return connectAutomaticallyAtStartup.hashCode ^
preferredStreamingType.hashCode ^
rtspProtocol.hashCode ^
renderingQuality.hashCode ^
videoFit.hashCode;
}
}

/// A [Server] added by a user.
class Server {
Expand All @@ -43,11 +156,6 @@ class Server {
/// The password to connect to the server.
final String password;

/// Whether to connect to this server automatically at startup.
///
/// If false, the server will have to be connected to manually.
final bool connectAutomaticallyAtStartup;

/// The list of devices that are available on this server.
List<Device> devices = [];
final String? serverUUID;
Expand All @@ -64,6 +172,9 @@ class Server {
/// * [Device.hlsURL]
bool passedCertificates = true;

/// Additional settings for this server.
final AdditionalServerOptions additionalSettings;

/// Creates a new [Server].
Server({
required this.name,
Expand All @@ -75,9 +186,9 @@ class Server {
this.rtspPort = kDefaultRTSPPort,
this.serverUUID,
this.cookie,
this.connectAutomaticallyAtStartup = true,
this.online = true,
this.passedCertificates = true,
this.additionalSettings = const AdditionalServerOptions(),
});

/// Creates a server with fake values.
Expand All @@ -95,9 +206,9 @@ class Server {
this.rtspPort = kDefaultRTSPPort,
this.serverUUID,
this.cookie,
this.connectAutomaticallyAtStartup = true,
this.online = true,
this.passedCertificates = true,
this.additionalSettings = const AdditionalServerOptions(),
});

String get id {
Expand All @@ -119,7 +230,7 @@ class Server {
other.rtspPort == rtspPort &&
other.login == login &&
other.password == password &&
other.connectAutomaticallyAtStartup == connectAutomaticallyAtStartup &&
other.additionalSettings == additionalSettings &&
listEquals(other.devices, devices) &&
other.serverUUID == serverUUID &&
other.cookie == cookie &&
Expand All @@ -135,7 +246,7 @@ class Server {
rtspPort.hashCode ^
login.hashCode ^
password.hashCode ^
connectAutomaticallyAtStartup.hashCode ^
additionalSettings.hashCode ^
devices.hashCode ^
serverUUID.hashCode ^
cookie.hashCode ^
Expand All @@ -154,6 +265,7 @@ class Server {
String? serverUUID,
String? cookie,
bool? online,
AdditionalServerOptions? additionalSettings,
}) {
return Server(
name: name ?? this.name,
Expand All @@ -165,6 +277,7 @@ class Server {
rtspPort: rtspPort ?? this.rtspPort,
serverUUID: serverUUID ?? this.serverUUID,
cookie: cookie ?? this.cookie,
additionalSettings: additionalSettings ?? this.additionalSettings,
);
}

Expand All @@ -181,6 +294,7 @@ class Server {
'devices': !devices ? [] : this.devices.map((e) => e.toJson()).toList(),
'serverUUID': serverUUID,
'cookie': cookie,
'additionalSettings': additionalSettings.toMap(),
};

factory Server.fromJson(Map<String, dynamic> json) => Server(
Expand All @@ -197,5 +311,8 @@ class Server {
rtspPort: json['rtspPort'],
serverUUID: json['serverUUID'],
cookie: json['cookie'],
additionalSettings: json['additionalSettings'] != null
? AdditionalServerOptions.fromMap(json['additionalSettings'])
: const AdditionalServerOptions(),
);
}
18 changes: 16 additions & 2 deletions lib/providers/desktop_view_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class DesktopViewProvider extends ChangeNotifier {
void _releaseDevice(Device device) {
if (!UnityPlayers.players.containsKey(device.uuid)) return;
if (!layouts
.any((layout) => layout.devices.any((d) => d.id == device.id))) {
.any((layout) => layout.devices.any((d) => d.uuid == device.uuid))) {
UnityPlayers.releaseDevice(device.uuid);
}
}
Expand Down Expand Up @@ -173,7 +173,21 @@ class DesktopViewProvider extends ChangeNotifier {
_releaseDevice(device);
}

return _save();
notifyListeners();
return _save(notifyListeners: false);
}

Future<void> removeDevicesFromCurrentLayout(Iterable<Device> devices) {
currentLayout.devices.removeWhere(
(d1) => devices.any((d2) => d1.uri == d2.uri),
);

for (final device in devices) {
_releaseDevice(device);
}

notifyListeners();
return _save(notifyListeners: false);
}

/// Moves a device tile from [initial] position to [end] position inside a [tab].
Expand Down
4 changes: 3 additions & 1 deletion lib/providers/server_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,9 @@ class ServersProvider extends ChangeNotifier {
}) async {
await Future.wait(servers.map((server) async {
if (ids != null && !ids.contains(server.id)) return;
if (startup && !server.connectAutomaticallyAtStartup) return;
if (startup && !server.additionalSettings.connectAutomaticallyAtStartup) {
return;
}

if (!loadingServer.contains(server.id)) {
loadingServer.add(server.id);
Expand Down
Loading

0 comments on commit 01f8aca

Please sign in to comment.