Skip to content

Commit

Permalink
feat: Overlays view on import
Browse files Browse the repository at this point in the history
  • Loading branch information
bdlukaa committed Nov 12, 2023
1 parent d7be623 commit 9a4772b
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 41 deletions.
45 changes: 42 additions & 3 deletions lib/utils/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,39 @@ class VideoOverlay {
visible: map['visible'] ?? false,
);
}

VideoOverlay copyWith({
String? text,
TextStyle? textStyle,
Offset? position,
bool? visible,
}) {
return VideoOverlay(
text: text ?? this.text,
textStyle: textStyle ?? this.textStyle,
position: position ?? this.position,
visible: visible ?? this.visible,
);
}

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

return other is VideoOverlay &&
other.text == text &&
other.textStyle == textStyle &&
other.position == position &&
other.visible == visible;
}

@override
int get hashCode {
return text.hashCode ^
textStyle.hashCode ^
position.hashCode ^
visible.hashCode;
}
}

/// Parses the config file content and returns a map with the config values.
Expand Down Expand Up @@ -182,8 +215,8 @@ void ensureFileFormat(Map<String, dynamic> configData) {
}
}

void handleConfigurationFile(File file) {
var configData = parseConfig(file.readAsStringSync());
Future<void> handleConfigurationFile(File file) async {
var configData = parseConfig(await file.readAsString());
ensureFileFormat(configData);

final context = navigatorKey.currentContext;
Expand Down Expand Up @@ -229,5 +262,11 @@ void handleConfigurationFile(File file) {
}
}

AddExternalStreamDialog.show(context, defaultUrl: videoUrl);
if (context.mounted) {
await AddExternalStreamDialog.show(
context,
defaultUrl: videoUrl,
overlays: overlays,
);
}
}
150 changes: 113 additions & 37 deletions lib/widgets/device_grid/desktop/external_stream.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import 'package:bluecherry_client/models/layout.dart';
import 'package:bluecherry_client/models/server.dart';
import 'package:bluecherry_client/providers/desktop_view_provider.dart';
import 'package:bluecherry_client/providers/settings_provider.dart';
import 'package:bluecherry_client/utils/config.dart';
import 'package:bluecherry_client/utils/extensions.dart';
import 'package:bluecherry_client/widgets/misc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';
Expand Down Expand Up @@ -61,20 +63,24 @@ enum MatrixType {

class AddExternalStreamDialog extends StatefulWidget {
final String? defaultUrl;
final List<VideoOverlay> overlays;

const AddExternalStreamDialog({
super.key,
this.defaultUrl,
this.overlays = const [],
});

static Future<void> show(
BuildContext context, {
String? defaultUrl,
List<VideoOverlay> overlays = const [],
}) {
return showDialog(
context: context,
builder: (context) => AddExternalStreamDialog(
defaultUrl: defaultUrl,
overlays: overlays,
),
);
}
Expand All @@ -84,6 +90,7 @@ class AddExternalStreamDialog extends StatefulWidget {
String url, {
String? name,
MatrixType matrixType = MatrixType.t16,
List<VideoOverlay> overlays = const [],
}) {
final loc = AppLocalizations.of(context);
AppLocalizations.localizationsDelegates;
Expand All @@ -92,6 +99,7 @@ class AddExternalStreamDialog extends StatefulWidget {
url: url,
id: const Uuid().v4().hashCode,
matrixType: matrixType,
overlays: overlays,
)..server = Server.dump(name: url);

final view = context.read<DesktopViewProvider>();
Expand Down Expand Up @@ -122,6 +130,8 @@ class _AddExternalStreamDialogState extends State<AddExternalStreamDialog> {

var matrixType = MatrixType.t16;

late final overlays = List<VideoOverlay>.from(widget.overlays);

@override
void dispose() {
nameController.dispose();
Expand All @@ -141,50 +151,57 @@ class _AddExternalStreamDialogState extends State<AddExternalStreamDialog> {
constraints: BoxConstraints(
minWidth: MediaQuery.sizeOf(context).width * 0.425,
),
child: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
Expanded(
child: TextFormField(
autofocus: true,
controller: nameController,
decoration: InputDecoration(label: Text(loc.streamName)),
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null || value.isEmpty) {
return loc.streamNameRequired;
}
return null;
},
),
),
const SizedBox(width: 16.0),
Expanded(
flex: 2,
child: TextFormField(
controller: urlController,
decoration: InputDecoration(label: Text(loc.streamURL)),
textInputAction: TextInputAction.done,
onFieldSubmitted: (_) => _finish(),
validator: (value) {
if (value == null || value.isEmpty) {
return loc.streamNameRequired;
} else if (Uri.tryParse(value) == null) {
return loc.streamURLNotValid;
}

return null;
},
),
Form(
key: _formKey,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: TextFormField(
autofocus: true,
controller: nameController,
decoration:
InputDecoration(label: Text(loc.streamName)),
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null || value.isEmpty) {
return loc.streamNameRequired;
}
return null;
},
),
),
const SizedBox(width: 16.0),
Expanded(
flex: 2,
child: TextFormField(
controller: urlController,
decoration:
InputDecoration(label: Text(loc.streamURL)),
textInputAction: TextInputAction.done,
onFieldSubmitted: (_) => _finish(),
validator: (value) {
if (value == null || value.isEmpty) {
return loc.streamNameRequired;
} else if (Uri.tryParse(value) == null) {
return loc.streamURLNotValid;
}

return null;
},
),
),
],
),
]),
),
if (settings.betaMatrixedZoomEnabled) ...[
const SizedBox(height: 16.0),
Text('Matrix type', style: theme.textTheme.labelMedium),
Text('Matrix type', style: theme.textTheme.headlineSmall),
const SizedBox(height: 6.0),
Center(
child: ToggleButtons(
Expand Down Expand Up @@ -216,6 +233,64 @@ class _AddExternalStreamDialogState extends State<AddExternalStreamDialog> {
),
),
],
if (overlays.isNotEmpty) ...[
const SizedBox(height: 16.0),
Text('Overlays', style: theme.textTheme.headlineSmall),
for (final overlay in overlays) ...[
const SizedBox(height: 6.0),
Row(children: [
Tooltip(
message: 'Visible',
child: Transform.scale(
scale: 0.9,
child: Checkbox(
value: overlay.visible,
onChanged: (v) {
setState(() {
overlays[overlays.indexOf(overlay)] =
overlay.copyWith(visible: v!);
});
},
materialTapTargetSize:
MaterialTapTargetSize.shrinkWrap,
visualDensity: VisualDensity.compact,
),
),
),
const SizedBox(width: 6.0),
Text(
'Overlay ${overlays.indexOf(overlay) + 1}',
style: theme.textTheme.labelLarge,
),
const Spacer(),
Text(
'Position (x: ${overlay.position.dx}, y: ${overlay.position.dy})',
style: theme.textTheme.labelSmall!
.copyWith(fontWeight: FontWeight.normal),
),
]),
const SizedBox(height: 2.0),
TextField(
controller: TextEditingController(text: overlay.text),
style: theme.textTheme.bodyLarge!
.copyWith(shadows: outlinedText())
.merge(overlay.textStyle),
onChanged: (text) {
setState(() {
overlays[overlays.indexOf(overlay)] =
overlay.copyWith(text: text);
});
},
decoration: const InputDecoration(
contentPadding: EdgeInsets.zero,
border: InputBorder.none,
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
),
),
const SizedBox(height: 4.0),
],
],
],
),
),
Expand Down Expand Up @@ -244,6 +319,7 @@ class _AddExternalStreamDialogState extends State<AddExternalStreamDialog> {
urlController.text,
name: nameController.text,
matrixType: matrixType,
overlays: overlays,
);

Navigator.of(context).pop();
Expand Down
2 changes: 1 addition & 1 deletion lib/widgets/device_grid/desktop/multicast_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ class _MulticastViewportState extends State<MulticastViewport> {
child: IgnorePointer(
child: Text(
overlay.text,
style: theme.textTheme.labelLarge!
style: theme.textTheme.bodyLarge!
.copyWith(shadows: outlinedText())
.merge(overlay.textStyle),
),
Expand Down

0 comments on commit 9a4772b

Please sign in to comment.