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

Release beta18 #263

Merged
merged 11 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ jobs:
with:
token: ${{ secrets.GITHUB_TOKEN }}
submodules: recursive
# We need to enforce java 17 because newer Flutter packages are
# requiring this Java Version.
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '17'
cache: 'gradle'
check-latest: true
- uses: subosito/[email protected]
with:
channel: "stable"
Expand Down
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ lib

packages
├───unity_multi_window [multi-window support for desktop platforms.]
├───unity_multi_window [multi-window support for desktop platforms.]
├───unity_video_player
│ ├───unity_video_player [the core video player logic.]
Expand All @@ -165,6 +165,22 @@ packages

Feel free to send any pull-requests to add any features you wish or fix any bugs you notice.

### Video Rendering

We support multiple platforms and each platform uses its own rendering backend.

| Platform | Rendering Backend | Flutter Package |
| ------------ | ----------------- | --------------- |
| Android | MPV | media_kit |
| iOS | MPV | media_kit |
| Windows | MPV | media_kit |
| MacOS | MPV | media_kit |
| Web | HTML5 | fvp |
| Linux | MDK | fvp |
| Raspberry Pi | MDK | fvp |

MDK is used for Linux and Raspberry Pi because MPV has shown to be unstable on these platforms, causing crashes. Additionally, `fvp` doesn't require the user to install any additional dependencies.

### Build

The build process is pretty straight-forward. You need to have [Flutter](https://flutter.dev/docs/get-started/install) installed on your system.
Expand Down Expand Up @@ -192,4 +208,4 @@ When running on debug, you must disable the CORS policy in your browser. Note th

```bash
flutter run -d chrome --web-browser-flag "--disable-web-security"
```
```
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ android {
ndkVersion flutter.ndkVersion

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}

kotlinOptions {
Expand Down
5 changes: 5 additions & 0 deletions bluecherry_appcast.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle">
<channel>
<title>Bluecherry - Appcast</title>
<item>
<title>Version 3.0.0-beta19</title>
<description>Linux and Timeline enhancements.</description>
<pubDate>Mon, 09 Sep 2024</pubDate>
</item>
<item>
<title>Version 3.0.0-beta18</title>
<description>Time Filter for Events; Fixed crash on newer versions of Windows.</description>
Expand Down
2 changes: 1 addition & 1 deletion installer/windows-installer.iss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "Bluecherry DVR"
#define MyAppVersion "3.0.0-beta18"
#define MyAppVersion "3.0.0-beta19"
#define MyAppPublisher "Bluecherry DVR"
#define MyAppURL "https://www.bluecherrydvr.com/"
#define MyAppExeName "bluecherry_client.exe"
Expand Down
18 changes: 9 additions & 9 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
*/

import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:bluecherry_client/api/api.dart';
Expand Down Expand Up @@ -117,12 +116,12 @@ Future<void> main(List<String> args) async {
await SettingsProvider.ensureInitialized();
await DesktopViewProvider.ensureInitialized();

final windowType = MultiWindowType.values[int.tryParse(args[1]) ?? 0];
final themeMode = ThemeMode.values[int.tryParse(args[3]) ?? 0];
final (windowType, themeMode, map) =
LayoutWindowExtension.fromArgs(args);

switch (windowType) {
case MultiWindowType.device:
final device = Device.fromJson(json.decode(args[2]));
final device = Device.fromJson(map);
configureWindowTitle(device.fullName);

runApp(AlternativeWindow(
Expand All @@ -131,7 +130,7 @@ Future<void> main(List<String> args) async {
));
break;
case MultiWindowType.layout:
final layout = Layout.fromJson(args[2]);
final layout = Layout.fromMap(map);
configureWindowTitle(layout.name);

runApp(AlternativeWindow(
Expand Down Expand Up @@ -268,10 +267,11 @@ class _UnityAppState extends State<UnityApp>
case NetworkUsage.wifiOnly:
debugPrint('Pausing all streams');
final connectionType = await Connectivity().checkConnectivity();
if (connectionType == ConnectivityResult.mobile ||
connectionType == ConnectivityResult.bluetooth) {
UnityPlayers.pauseAll();
}
if ([
ConnectivityResult.bluetooth,
ConnectivityResult.mobile,
].any(connectionType.contains)) UnityPlayers.pauseAll();

break;
case NetworkUsage.never:
break;
Expand Down
5 changes: 0 additions & 5 deletions lib/models/layout.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import 'dart:convert';
import 'dart:io';

import 'package:bluecherry_client/models/device.dart';
Expand Down Expand Up @@ -107,10 +106,6 @@ class Layout {
);
}

String toJson() => json.encode(toMap());

factory Layout.fromJson(String source) => Layout.fromMap(json.decode(source));

Layout copyWith({
String? name,
List<Device>? devices,
Expand Down
2 changes: 2 additions & 0 deletions lib/providers/desktop_view_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ class DesktopViewProvider extends UnityProvider {
return save(notifyListeners: false);
}

Iterable<Device> get allDevices => layouts.expand((layout) => layout.devices);

/// Removes all the [devices] provided
///
/// This is usually used when a server is deleted
Expand Down
42 changes: 38 additions & 4 deletions lib/providers/home_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
*/

import 'package:bluecherry_client/main.dart';
import 'package:bluecherry_client/providers/desktop_view_provider.dart';
import 'package:bluecherry_client/providers/server_provider.dart';
import 'package:bluecherry_client/providers/settings_provider.dart';
import 'package:bluecherry_client/providers/update_provider.dart';
import 'package:bluecherry_client/utils/methods.dart';
import 'package:bluecherry_client/utils/video_player.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
Expand Down Expand Up @@ -91,19 +93,51 @@ class HomeProvider extends ChangeNotifier {

List<UnityLoadingReason> loadReasons = [];

/// Stores the volume of each device.
///
/// These are filled when the user leaves the Devices tab and cleared when
/// they come back.
Map<String, double> volumes = {};

Future<void> setTab(UnityTab tab, BuildContext context) async {
if (tab == this.tab) return;

final currentTab = this.tab;
final nextTab = tab;

this.tab = tab;

if (tab != UnityTab.downloads) {
initiallyExpandedDownloadEventId = null;
}
if (nextTab != UnityTab.downloads) initiallyExpandedDownloadEventId = null;

if (tab != UnityTab.addServer) {
if (nextTab != UnityTab.addServer) {
automaticallyGoToAddServersScreen = false;
}

if (currentTab == UnityTab.deviceGrid) {
// If we're moving out of the device grid tab, we should not be able to
// hear the live feed anymore.

final devices = DesktopViewProvider.instance.allDevices;
final players = UnityPlayers.players.entries
.where((entry) => devices.any((device) => device.uuid == entry.key))
.toList();

for (final player in players) {
volumes[player.key] = player.value.volume;
player.value.setVolume(0.0);
}
} else if (nextTab == UnityTab.deviceGrid) {
// When the user comes back to the device grid, we should restore the
// volume of the devices.

for (final entry in volumes.entries) {
final player = UnityPlayers.players[entry.key];
if (player != null) player.setVolume(entry.value);
}

volumes.clear();
}

refreshDeviceOrientation(context);
updateWakelock(context);
notifyListeners();
Expand Down
2 changes: 2 additions & 0 deletions lib/screens/events_timeline/events_playback.dart
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ class _EventsPlaybackState extends EventsScreenState<EventsPlayback> {
initialPosition: switch (settings.kTimelineInitialPoint.value) {
TimelineInitialPoint.beginning => Duration.zero,
TimelineInitialPoint.firstEvent => () {
if (parsedTiles.isEmpty) return Duration.zero;

final firstEvent = parsedTiles
.map((e) {
final earliestEvent = e.events.reduce(
Expand Down
17 changes: 11 additions & 6 deletions lib/screens/layouts/desktop/layout_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -246,17 +246,22 @@ class LayoutView extends StatelessWidget {
);
}

final isAlternativeWindow = AlternativeWindow.maybeOf(context) != null;
final parent = context.findAncestorWidgetOfExactType<LargeDeviceGrid>();
final isReversed =
context.findAncestorWidgetOfExactType<LargeDeviceGrid>()!.width <=
_kReverseBreakpoint;
parent == null ? false : parent.width <= _kReverseBreakpoint;

return Material(
color: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadiusDirectional.only(
topStart: isReversed ? Radius.zero : const Radius.circular(8.0),
topEnd: isReversed ? const Radius.circular(8.0) : Radius.zero,
),
borderRadius: isAlternativeWindow
? BorderRadius.zero
: BorderRadiusDirectional.only(
topStart:
isReversed ? Radius.zero : const Radius.circular(8.0),
topEnd:
isReversed ? const Radius.circular(8.0) : Radius.zero,
),
),
child: SafeArea(
child: Column(
Expand Down
1 change: 1 addition & 0 deletions lib/screens/layouts/device_grid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import 'package:bluecherry_client/screens/layouts/desktop/external_stream.dart';
import 'package:bluecherry_client/screens/layouts/desktop/layout_manager.dart';
import 'package:bluecherry_client/screens/layouts/desktop/viewport.dart';
import 'package:bluecherry_client/screens/layouts/mobile/device_view.dart';
import 'package:bluecherry_client/screens/multi_window/window.dart';
import 'package:bluecherry_client/utils/app_links/app_links.dart' as app_links;
import 'package:bluecherry_client/utils/constants.dart';
import 'package:bluecherry_client/utils/extensions.dart';
Expand Down
2 changes: 1 addition & 1 deletion lib/utils/app_links/app_links_real.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ void listen() {
// See https://github.com/llfbandit/app_links/issues/20 for more info.
if (isDesktopPlatform && !Platform.isLinux) {
WidgetsBinding.instance.addPostFrameCallback((_) {
instance.allUriLinkStream.listen((uri) async {
instance.uriLinkStream.listen((uri) async {
debugPrint('Received URI: $uri');
await writeLogToFile('Received URI $uri');
final handleType = await _handleUri(uri);
Expand Down
14 changes: 11 additions & 3 deletions lib/utils/window.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,17 +96,25 @@ extension DeviceWindowExtension on Device {

debugPrint('Opening a new window');
final window = await MultiWindow.run([
'multi_window',
'${MultiWindowType.device.index}',
json.encode(toJson()),
'${SettingsProvider.instance.kThemeMode.value.index}',
json.encode(toJson()),
]);

debugPrint('Opened window with id ${window.windowId}');
}
}

extension LayoutWindowExtension on Layout {
static (MultiWindowType, ThemeMode, Map<String, dynamic>) fromArgs(
List<String> args,
) {
final type = MultiWindowType.values[int.parse(args[0])];
final themeMode = ThemeMode.values[int.parse(args[1])];
final map = json.decode(args[2]);
return (type, themeMode, map);
}

Future<void> openInANewWindow() async {
assert(
isDesktopPlatform,
Expand All @@ -118,8 +126,8 @@ extension LayoutWindowExtension on Layout {
debugPrint('Opening a new window');
final window = await MultiWindow.run([
'${MultiWindowType.layout.index}',
json.encode(toMap()),
'${SettingsProvider.instance.kThemeMode.value.index}',
json.encode(toMap()),
]);

debugPrint('Opened window with id ${window.windowId}');
Expand Down
2 changes: 1 addition & 1 deletion linux/debian/DEBIAN/control
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Package: bluecherrydvr
Version: 3.0.0-beta18
Version: 3.0.0-beta19
Section: base
Priority: optional
Homepage: https://www.bluecherrydvr.com/
Expand Down
1 change: 1 addition & 0 deletions linux/debian/usr/share/metainfo/bluecherry.appdata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<launchable type="desktop-id">bluecherrydvr.desktop</launchable>
<releases>
<!-- <release version="VERSION" date="YYYY-MM-DD" />| -->
<release version="3.0.0-beta19" date="2024-09-09" />|
<release version="3.0.0-beta18" date="2024-07-10" />|
<release version="3.0.0-beta17" date="2024-06-07" />|
<release version="3.0.0-beta16" date="2024-04-15" />|
Expand Down
8 changes: 0 additions & 8 deletions linux/flutter/generated_plugin_registrant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@
#include <awesome_notifications/awesome_notifications_plugin.h>
#include <fvp/fvp_plugin.h>
#include <gtk/gtk_plugin.h>
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
#include <media_kit_video/media_kit_video_plugin.h>
#include <screen_retriever/screen_retriever_plugin.h>
#include <system_date_time_format/system_date_time_format_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
#include <window_manager/window_manager_plugin.h>

Expand All @@ -26,18 +24,12 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) gtk_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin");
gtk_plugin_register_with_registrar(gtk_registrar);
g_autoptr(FlPluginRegistrar) media_kit_libs_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitLibsLinuxPlugin");
media_kit_libs_linux_plugin_register_with_registrar(media_kit_libs_linux_registrar);
g_autoptr(FlPluginRegistrar) media_kit_video_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitVideoPlugin");
media_kit_video_plugin_register_with_registrar(media_kit_video_registrar);
g_autoptr(FlPluginRegistrar) screen_retriever_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin");
screen_retriever_plugin_register_with_registrar(screen_retriever_registrar);
g_autoptr(FlPluginRegistrar) system_date_time_format_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "SystemDateTimeFormatPlugin");
system_date_time_format_plugin_register_with_registrar(system_date_time_format_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
Expand Down
2 changes: 0 additions & 2 deletions linux/flutter/generated_plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ list(APPEND FLUTTER_PLUGIN_LIST
awesome_notifications
fvp
gtk
media_kit_libs_linux
media_kit_video
screen_retriever
system_date_time_format
url_launcher_linux
window_manager
)
Expand Down
2 changes: 1 addition & 1 deletion linux/rpm/bluecherry.spec
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Name: bluecherrydvr
Version: 3.0.0_beta18
Version: 3.0.0_beta19
Release: 1
Summary: Bluecherry client written in Flutter.
License: EULA
Expand Down
Loading
Loading