Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Event Video Magnification #252

Merged
merged 11 commits into from
Jul 25, 2024
14 changes: 8 additions & 6 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -547,14 +547,16 @@
"privacyPolicy": "Privacy Policy",
"termsOfService": "Terms of Service",
"@@ADVANCED_OPTIONS": {},
"matrixZoom": "Area Magnification",
"matrixedViewZoom": "Area Magnification enabled",
"matrixedViewZoomDescription": "Magnify a area of the matrix view when selected. This is useful when you have a lot of cameras and want to see a specific area in more detail, or when a multicast stream is provided.",
"matrixMagnification": "Area Magnification",
"matrixedViewMagnification": "Area Magnification enabled",
"matrixedViewMagnificationDescription": "Magnify a area of the matrix view when selected. This is useful when you have a lot of cameras and want to see a specific area in more detail, or when a multicast stream is provided.",
"matrixType": "Matrix type",
"defaultMatrixSize": "Default Magnification Proportion",
"softwareZoom": "Software zoom",
"softwareZoomDescription": "When enabled, the magnification will not happen in the GPU. This is useful when the hardware magnification is not working properly.",
"softwareZoomDescriptionMacOS": "When enabled, the magnification will not happen in the GPU. This is useful when the hardware magnification is not working properly. On macOS, this can not be disabled.",
"softwareMagnification": "Software Magnification",
"softwareMagnificationDescription": "When enabled, the magnification will not happen in the GPU. This is useful when the hardware magnification is not working properly.",
"softwareMagnificationDescriptionMacOS": "When enabled, the magnification will not happen in the GPU. This is useful when the hardware magnification is not working properly. On macOS, this can not be disabled.",
"eventMagnification": "Event Magnification",
"eventMagnificationDescription": "Magnify the event video when selected. This is useful when you want to see the event in more detail.",
"developerOptions": "Developer options",
"openLogFile": "Open log file",
"openAppDataDirectory": "Open app data directory",
Expand Down
14 changes: 8 additions & 6 deletions lib/l10n/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -523,14 +523,16 @@
"privacyPolicy": "Politique de confidentialité",
"termsOfService": "Conditions 'utilisations",
"@@ADVANCED_OPTIONS": {},
"matrixZoom": "Zoom aatriciel",
"matrixedViewZoom": "Vue zoom matriciel",
"matrixedViewZoomDescription": "Zoomer sur une zone matricielle de 16x16 pour voir plus de détails.",
"matrixMagnification": "Area Magnification",
"matrixedViewMagnification": "Area Magnification enabled",
"matrixedViewMagnificationDescription": "Magnify a area of the matrix view when selected. This is useful when you have a lot of cameras and want to see a specific area in more detail, or when a multicast stream is provided.",
"matrixType": "Type de matrice",
"defaultMatrixSize": "Taille de matrice par défaut",
"softwareZoom": "Zoom logiciel",
"softwareZoomDescription": "Lorsque activé, le zoom matriciel n'utilisera pas le GPU. Cette option est utile lorsque le zoom matériel ne fonctionne pas correctement.",
"softwareZoomDescriptionMacOS": "Lorsque activé, le zoom matriciel n'utilisera pas le GPU. Cette option est utile lorsque le zoom matériel ne fonctionne pas correctement. Sur macOS, cette option ne peut être désactivée.",
"softwareMagnification": "Software Magnification",
"softwareMagnificationDescription": "When enabled, the magnification will not happen in the GPU. This is useful when the hardware magnification is not working properly.",
"softwareMagnificationDescriptionMacOS": "When enabled, the magnification will not happen in the GPU. This is useful when the hardware magnification is not working properly. On macOS, this can not be disabled.",
"eventMagnification": "Event Magnification",
"eventMagnificationDescription": "Magnify the event video when selected. This is useful when you want to see the event in more detail.",
"developerOptions": "Options de développement",
"openLogFile": "Ovrir les fichiers logs",
"openAppDataDirectory": "Ouvrir le répertoir de l'application",
Expand Down
14 changes: 8 additions & 6 deletions lib/l10n/app_pl.arb
Original file line number Diff line number Diff line change
Expand Up @@ -547,14 +547,16 @@
"privacyPolicy": "Privacy Policy",
"termsOfService": "Terms of Service",
"@@ADVANCED_OPTIONS": {},
"matrixZoom": "Matrix Zoom",
"matrixedViewZoom": "Matrixed view zoom",
"matrixedViewZoomDescription": "Zoom in on a 16x16 matrixed view to see more detail.",
"matrixMagnification": "Area Magnification",
"matrixedViewMagnification": "Area Magnification enabled",
"matrixedViewMagnificationDescription": "Magnify a area of the matrix view when selected. This is useful when you have a lot of cameras and want to see a specific area in more detail, or when a multicast stream is provided.",
"matrixType": "Matrix type",
"defaultMatrixSize": "Default Matrix Size",
"softwareZoom": "Software zoom",
"softwareZoomDescription": "When enabled, the matrix zoom will not happen in the GPU. This is useful when the hardware zoom is not working properly.",
"softwareZoomDescriptionMacOS": "When enabled, the matrix zoom will not happen in the GPU. This is useful when the hardware zoom is not working properly. On macOS, this can not be disabled.",
"softwareMagnification": "Software Magnification",
"softwareMagnificationDescription": "When enabled, the magnification will not happen in the GPU. This is useful when the hardware magnification is not working properly.",
"softwareMagnificationDescriptionMacOS": "When enabled, the magnification will not happen in the GPU. This is useful when the hardware magnification is not working properly. On macOS, this can not be disabled.",
"eventMagnification": "Event Magnification",
"eventMagnificationDescription": "Magnify the event video when selected. This is useful when you want to see the event in more detail.",
"developerOptions": "Developer options",
"openLogFile": "Open log file",
"openAppDataDirectory": "Open app data directory",
Expand Down
14 changes: 8 additions & 6 deletions lib/l10n/app_pt.arb
Original file line number Diff line number Diff line change
Expand Up @@ -547,14 +547,16 @@
"privacyPolicy": "Política de Privacidade",
"termsOfService": "Termos de Serviço",
"@@ADVANCED_OPTIONS": {},
"matrixZoom": "Zoom da Matriz",
"matrixedViewZoom": "Zoom em Visualização Matrixial",
"matrixedViewZoomDescription": "Dê zoom em uma visualização matrixial 16x16 para ver mais detalhes.",
"matrixMagnification": "Ampliar",
"matrixedViewMagnification": "Ampliação de Área ativada",
"matrixedViewMagnificationDescription": "Ampliar a área da visualização da matriz quando selecionado. Isso é útil quando você tem muitas câmeras e deseja ver uma área específica com mais detalhes, ou quando uma stream multicast é usada.",
"matrixType": "Tipo de Matrix",
"defaultMatrixSize": "Tamanho Padrão da Matriz",
"softwareZoom": "Zoom do Software",
"softwareZoomDescription": "Quando ativado, o zoom não ocorrerá na GPU. Isso é útil quando o zoom do hardware não está funcionando corretamente.",
"softwareZoomDescriptionMacOS": "Quando ativado, o zoom da matriz não ocorrerá na GPU. Isso é útil quando o zoom do hardware não está funcionando corretamente. No macOS, isso não pode ser desativado.",
"softwareMagnification": "Ampliação de Software",
"softwareMagnificationDescription": "Quando ativado, a ampliação não ocorrerá na GPU. Isso é útil quando a ampliação no hardware não está funcionando corretamente.",
"softwareMagnificationDescriptionMacOS": "Quando ativado, a ampliação não ocorrerá na GPU. Isso é útil quando a ampliação no hardware não está funcionando corretamente. No macOS, isso não pode ser desativado.",
"eventMagnification": "Ampliar Evento",
"eventMagnificationDescription": "Ampliar o vídeo do evento quando selecionado. Isso é útil quando você deseja ver o evento em mais detalhes.",
"developerOptions": "Opções de Desenvolvedor",
"openLogFile": "Abrir Arquivo de Log",
"openAppDataDirectory": "Abrir Diretório de Dados do Aplicativo",
Expand Down
5 changes: 3 additions & 2 deletions lib/models/device.dart
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,12 @@ class Device {
this.resolutionY = 480,
this.hasPTZ = false,
this.url,
this.matrixType = MatrixType.t16,
MatrixType? matrixType,
this.overlays = const [],
this.preferredStreamingType,
this.externalData,
}) : server = Server.dump();
}) : server = Server.dump(),
matrixType = matrixType ?? SettingsProvider.instance.kMatrixSize.value;

String get uri => 'live/$id';

Expand Down
8 changes: 6 additions & 2 deletions lib/providers/desktop_view_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,9 @@ class DesktopViewProvider extends UnityProvider {
/// Updates a device in all the layouts.
///
/// If [reload] is `true`, the device player will be reloaded.
Future<void> updateDevice(
///
/// Return the new device.
Device updateDevice(
Device previousDevice,
Device device, {
bool reload = false,
Expand All @@ -343,6 +345,8 @@ class DesktopViewProvider extends UnityProvider {
}

notifyListeners();
return save(notifyListeners: false);
save(notifyListeners: false);

return device;
}
}
15 changes: 11 additions & 4 deletions lib/providers/settings_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ class SettingsProvider extends UnityProvider {
);

// Other
final kDefaultBetaMatrixedZoomEnabled = _SettingsOption(
final kMatrixedZoomEnabled = _SettingsOption(
def: false,
key: 'other.matrixed_zoom_enabled',
);
Expand All @@ -411,6 +411,10 @@ class SettingsProvider extends UnityProvider {
? () => true
: null,
);
final kEventsMatrixedZoom = _SettingsOption(
def: true,
key: 'other.zoom_matrixed_zoom_enabled',
);
final kShowDebugInfo = _SettingsOption(
def: kDebugMode,
key: 'other.show_debug_info',
Expand Down Expand Up @@ -477,9 +481,10 @@ class SettingsProvider extends UnityProvider {
kAllowCrashReports.loadData(data),
kAutoUpdate.loadData(data),
kShowReleaseNotes.loadData(data),
kDefaultBetaMatrixedZoomEnabled.loadData(data),
kMatrixedZoomEnabled.loadData(data),
kMatrixSize.loadData(data),
kSoftwareZooming.loadData(data),
kEventsMatrixedZoom.loadData(data),
kShowDebugInfo.loadData(data),
kShowNetworkUsage.loadData(data),
]);
Expand Down Expand Up @@ -559,10 +564,12 @@ class SettingsProvider extends UnityProvider {
kAutoUpdate.key: kAutoUpdate.saveAs(kAutoUpdate.value),
kShowReleaseNotes.key:
kShowReleaseNotes.saveAs(kShowReleaseNotes.value),
kDefaultBetaMatrixedZoomEnabled.key: kDefaultBetaMatrixedZoomEnabled
.saveAs(kDefaultBetaMatrixedZoomEnabled.value),
kMatrixedZoomEnabled.key:
kMatrixedZoomEnabled.saveAs(kMatrixedZoomEnabled.value),
kMatrixSize.key: kMatrixSize.saveAs(kMatrixSize.value),
kSoftwareZooming.key: kSoftwareZooming.saveAs(kSoftwareZooming.value),
kEventsMatrixedZoom.key:
kEventsMatrixedZoom.saveAs(kEventsMatrixedZoom.value),
kShowDebugInfo.key: kShowDebugInfo.saveAs(kShowDebugInfo.value),
kShowNetworkUsage.key:
kShowNetworkUsage.saveAs(kShowNetworkUsage.value),
Expand Down
108 changes: 80 additions & 28 deletions lib/screens/events_timeline/desktop/timeline.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class TimelineTile {
quality: UnityVideoQuality.p480,
enableCache: true,
title: device.fullName,
softwareZoom: SettingsProvider.instance.kSoftwareZooming.value,
matrixType: SettingsProvider.instance.kMatrixSize.value,
);
videoController.setMultipleDataSource(
events.map((event) => event.videoUrl),
Expand Down Expand Up @@ -110,49 +112,58 @@ class TimelineEvent {
return [
TimelineEvent(
duration: const Duration(minutes: 1),
startTime: DateTime(2023).add(
Duration(hours: Random().nextInt(4), minutes: Random().nextInt(60)),
),
startTime: DateTime.now()
.add(
Duration(
hours: Random().nextInt(4), minutes: Random().nextInt(60)),
)
.toUtc(),
event: Event.dump(),
),
TimelineEvent(
duration: const Duration(hours: 1),
startTime: DateTime(2023).add(Duration(hours: Random().nextInt(4) + 5)),
startTime: DateTime.now()
.add(Duration(hours: Random().nextInt(4) + 5))
.toUtc(),
event: Event.dump(),
),
TimelineEvent(
duration: const Duration(minutes: 1),
startTime: DateTime(2023).add(Duration(hours: Random().nextInt(4) + 9)),
startTime: DateTime.now()
.add(Duration(hours: Random().nextInt(4) + 9))
.toUtc(),
event: Event.dump(),
),
TimelineEvent(
duration: const Duration(minutes: 1),
startTime: DateTime(2023).add(
Duration(
hours: Random().nextInt(4) + 13,
minutes: Random().nextInt(60),
),
),
startTime: DateTime.now()
.add(
Duration(
hours: Random().nextInt(4) + 13,
minutes: Random().nextInt(60),
),
)
.toUtc(),
event: Event.dump(),
),
TimelineEvent(
duration: const Duration(minutes: 1),
startTime: DateTime(2023).add(
Duration(
hours: Random().nextInt(4) + 14,
minutes: Random().nextInt(60),
),
),
startTime: DateTime.now()
.add(Duration(
hours: Random().nextInt(4) + 14,
minutes: Random().nextInt(60),
))
.toUtc(),
event: Event.dump(),
),
TimelineEvent(
duration: const Duration(minutes: 1),
startTime: DateTime(2023).add(
Duration(
hours: Random().nextInt(4) + 20,
minutes: Random().nextInt(60),
),
),
startTime: DateTime.now()
.add(Duration(
hours: Random().nextInt(4) + 20,
minutes: Random().nextInt(60),
))
.toUtc(),
event: Event.dump(),
),
];
Expand All @@ -179,13 +190,14 @@ class Timeline extends ChangeNotifier {
final List<TimelineTile> tiles = [];

/// All the events must have happened in the same day
final DateTime date;
late final DateTime date;

Timeline({
required List<TimelineTile> tiles,
required this.date,
required DateTime date,
Duration initialPosition = Duration.zero,
}) {
this.date = DateTime(date.year, date.month, date.day).toLocal();
currentPosition = initialPosition;

add(tiles.where((tile) => tile.events.isNotEmpty));
Expand All @@ -201,6 +213,29 @@ class Timeline extends ChangeNotifier {
zoomController.addListener(notifyListeners);
}

Timeline.dump()
: this(
tiles: [
TimelineTile(
device: Device.dump(name: 'device1'),
events: TimelineEvent.fakeData,
),
TimelineTile(
device: Device.dump(name: 'device2'),
events: TimelineEvent.fakeData,
),
TimelineTile(
device: Device.dump(name: 'device3'),
events: TimelineEvent.fakeData,
),
TimelineTile(
device: Device.dump(name: 'device4'),
events: TimelineEvent.fakeData,
),
],
date: DateTime.now(),
);

void _eventCallback(TimelineTile tile, {bool notify = true}) {
if (tile.videoController.duration <= Duration.zero) return;

Expand Down Expand Up @@ -511,6 +546,8 @@ class _TimelineEventsViewState extends State<TimelineEventsView> {

final verticalScrollController = ScrollController();

bool _isCollapsed = false;

@override
void initState() {
super.initState();
Expand Down Expand Up @@ -597,6 +634,16 @@ class _TimelineEventsViewState extends State<TimelineEventsView> {
end: 8.0,
),
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
SquaredIconButton(
icon:
Icon(_isCollapsed ? Icons.expand_more : Icons.expand_less),
onPressed: () {
setState(() {
_isCollapsed = !_isCollapsed;
});
},
tooltip: _isCollapsed ? loc.expand : loc.collapse,
),
Expanded(
child: Row(mainAxisAlignment: MainAxisAlignment.end, children: [
if (timeline.pausedToBuffer.isNotEmpty)
Expand Down Expand Up @@ -696,11 +743,16 @@ class _TimelineEventsViewState extends State<TimelineEventsView> {
'${settings.kDateFormat.value.format(timeline.currentDate)} '
'${timelineTimeFormat.format(timeline.currentDate)}',
),
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: _kTimelineTileHeight * 5.0,
AnimatedContainer(
duration: const Duration(milliseconds: 300),
constraints: BoxConstraints(
maxHeight: _isCollapsed ? 0.0 : _kTimelineTileHeight * 5.0,
),
child: LayoutBuilder(builder: (context, constraints) {
if (constraints.maxHeight < _kTimelineTileHeight / 1.9) {
return const SizedBox.shrink();
}

final tileWidth =
(constraints.maxWidth - _kDeviceNameWidth) * timeline.zoom;
final hourWidth = tileWidth / 24;
Expand Down
Loading
Loading