Skip to content

Commit

Permalink
feat: ui review
Browse files Browse the repository at this point in the history
  • Loading branch information
bdlukaa committed Dec 8, 2023
1 parent a281dee commit b665bbe
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 153 deletions.
3 changes: 2 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@
"directCamera": "Direct Camera",
"addServer": "Add Server",
"settings": "Settings",
"noServersAdded": "No servers added",
"noServersAdded": "You haven't added any servers yet :/",
"howToAddServer": "Go to the \"Add Server\" screen to add a server.",
"editServerInfo": "Edit server info",
"editServer": "Edit server {serverName}",
"@editServer": {
Expand Down
1 change: 1 addition & 0 deletions lib/l10n/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
"addServer": "Ajouter serveur",
"settings": "Paramètres",
"noServersAdded": "Aucun serveur ajouté",
"howToAddServer": "Go to the \"Add Server\" screen to add a server.",
"editServerInfo": "Modifier les info serveur",
"editServer": "Modifier le serveur {serverName}",
"@editServer": {
Expand Down
1 change: 1 addition & 0 deletions lib/l10n/app_pl.arb
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
"addServer": "Dodaj serwer",
"settings": "Ustawienia",
"noServersAdded": "Nie dodano serwerów",
"howToAddServer": "Go to the \"Add Server\" screen to add a server.",
"editServerInfo": "Modyfikuj informację serwera",
"editServer": "Modyfikuj serwer {serverName}",
"@editServer": {
Expand Down
3 changes: 2 additions & 1 deletion lib/l10n/app_pt.arb
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@
"directCamera": "Câmera específica",
"addServer": "Adicionar servidor",
"settings": "Configurações",
"noServersAdded": "Nenhum servidor adicionado",
"noServersAdded": "Você ainda não adicionou nenhum servidor :/",
"howToAddServer": "Vá à \"Adicionar Servidor\" para adicionar um servidor.",
"editServerInfo": "Editar informações do servidor",
"editServer": "Editar servidor {serverName}",
"@editServer": {
Expand Down
324 changes: 181 additions & 143 deletions lib/widgets/device_grid/desktop/desktop_sidebar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,154 +43,192 @@ class _DesktopSidebarState extends State<DesktopSidebar> {
final servers = context.watch<ServersProvider>();
final view = context.watch<DesktopViewProvider>();

return Material(
color: theme.canvasColor,
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
LayoutManager(collapseButton: widget.collapseButton),
Expanded(
child: MouseRegion(
onEnter: (e) => setState(() => isSidebarHovering = true),
onExit: (e) => setState(() => isSidebarHovering = false),
// Add another material here because its descendants must be clipped.
child: Material(
type: MaterialType.transparency,
child: CustomScrollView(slivers: [
for (final server in servers.servers)
() {
final devices = server.devices.sorted();
final isLoading = servers.isServerLoading(server);

/// Whether all the online devices are in the current view.
final isAllInView = devices
.where((d) => d.status)
.every((d) => view.currentLayout.devices.contains(d));

return MultiSliver(pushPinnedChildren: true, children: [
SliverPinnedHeader(
child: SubHeader(
server.name,
materialType: MaterialType.canvas,
subtext: server.online
? loc.nDevices(devices.length)
: loc.offline,
subtextStyle: TextStyle(
color:
!server.online ? theme.colorScheme.error : null,
return SafeArea(
top: false,
right: false,
child: Material(
color: theme.canvasColor,
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
LayoutManager(collapseButton: widget.collapseButton),
if (servers.servers.isEmpty)
const Expanded(child: NoServers())
else
Expanded(
child: MouseRegion(
onEnter: (e) => setState(() => isSidebarHovering = true),
onExit: (e) => setState(() => isSidebarHovering = false),
// Add another material here because its descendants must be clipped.
child: Material(
type: MaterialType.transparency,
child: CustomScrollView(slivers: [
for (final server in servers.servers)
() {
final devices = server.devices.sorted();
final isLoading = servers.isServerLoading(server);

/// Whether all the online devices are in the current view.
final isAllInView = devices
.where((d) => d.status)
.every(
(d) => view.currentLayout.devices.contains(d));

return MultiSliver(pushPinnedChildren: true, children: [
SliverPinnedHeader(
child: SubHeader(
server.name,
materialType: MaterialType.canvas,
subtext: server.online
? loc.nDevices(devices.length)
: loc.offline,
subtextStyle: TextStyle(
color: !server.online
? theme.colorScheme.error
: null,
),
trailing: Builder(builder: (context) {
if (isLoading) {
// wrap in an icon button to ensure ui consistency
return const SquaredIconButton(
onPressed: null,
icon: SizedBox(
height: 16.0,
width: 16.0,
child: CircularProgressIndicator.adaptive(
strokeWidth: 1.5,
),
),
);
} else if (!server.online &&
isSidebarHovering) {
return SquaredIconButton(
icon: const Icon(Icons.refresh),
tooltip: loc.refreshServer,
onPressed: () => servers
.refreshDevices(ids: [server.id]),
);
} else if (isSidebarHovering &&
devices.isNotEmpty) {
return SquaredIconButton(
icon: Icon(
isAllInView
? Icons.playlist_remove
: Icons.playlist_add,
),
tooltip: isAllInView
? loc.removeAllFromView
: loc.addAllToView,
onPressed: () {
if (isAllInView) {
view.removeDevicesFromCurrentLayout(
devices);
} else {
for (final device in devices) {
if (device.status &&
!view.currentLayout.devices
.contains(device)) {
view.add(device);
}
}
}
},
);
} else {
return const SizedBox.shrink();
}
}),
),
),
trailing: Builder(builder: (context) {
if (isLoading) {
// wrap in an icon button to ensure ui consistency
return const SquaredIconButton(
onPressed: null,
icon: SizedBox(
height: 16.0,
width: 16.0,
child: CircularProgressIndicator.adaptive(
strokeWidth: 1.5,
if (server.online && !isLoading)
SliverList.builder(
itemCount: devices.length,
itemBuilder: (context, index) {
final device = devices[index];
final selected =
view.currentLayout.devices.contains(device);

final tile = DesktopDeviceSelectorTile(
device: device,
selected: selected,
);

if (selected || !device.status) return tile;

final isBlocked = view.currentLayout.type ==
DesktopLayoutType.singleView &&
view.currentLayout.devices.isNotEmpty;

return Draggable<Device>(
data: device,
feedback: Card(
child: SizedBox(
height: kDeviceSelectorTileHeight,
width: kSidebarConstraints.maxWidth,
child: Row(children: [
Expanded(child: tile),
if (isBlocked)
Icon(
Icons.block,
color: theme.colorScheme.error,
size: 18.0,
),
const SizedBox(width: 16.0),
]),
),
),
),
);
} else if (!server.online && isSidebarHovering) {
return SquaredIconButton(
icon: const Icon(Icons.refresh),
tooltip: loc.refreshServer,
onPressed: () =>
servers.refreshDevices(ids: [server.id]),
);
} else if (isSidebarHovering &&
devices.isNotEmpty) {
return SquaredIconButton(
icon: Icon(
isAllInView
? Icons.playlist_remove
: Icons.playlist_add,
),
tooltip: isAllInView
? loc.removeAllFromView
: loc.addAllToView,
onPressed: () {
if (isAllInView) {
view.removeDevicesFromCurrentLayout(
devices);
} else {
for (final device in devices) {
if (device.status &&
!view.currentLayout.devices
.contains(device)) {
view.add(device);
}
}
}
},
);
} else {
return const SizedBox.shrink();
}
}),
),
),
if (server.online && !isLoading)
SliverList.builder(
itemCount: devices.length,
itemBuilder: (context, index) {
final device = devices[index];
final selected =
view.currentLayout.devices.contains(device);

final tile = DesktopDeviceSelectorTile(
device: device,
selected: selected,
);

if (selected || !device.status) return tile;

final isBlocked = view.currentLayout.type ==
DesktopLayoutType.singleView &&
view.currentLayout.devices.isNotEmpty;

return Draggable<Device>(
data: device,
feedback: Card(
child: SizedBox(
height: kDeviceSelectorTileHeight,
width: kSidebarConstraints.maxWidth,
child: Row(children: [
Expanded(child: tile),
if (isBlocked)
Icon(
Icons.block,
color: theme.colorScheme.error,
size: 18.0,
),
const SizedBox(width: 16.0),
]),
),
),
child: tile,
);
},
),
]);
}(),
const SliverToBoxAdapter(child: Divider()),
SliverToBoxAdapter(
child: ListTile(
dense: true,
trailing: const Icon(Icons.camera_outdoor, size: 20.0),
title: Text(loc.addExternalStream),
onTap: () => AddExternalStreamDialog.show(context),
),
),
SliverPadding(
padding: EdgeInsetsDirectional.only(
bottom: MediaQuery.viewPaddingOf(context).bottom,
),
child: tile,
);
},
),
]);
}(),
]),
),
]),
),
),
const Divider(),
ListTile(
dense: true,
trailing: const Icon(Icons.camera_outdoor, size: 20.0),
title: Text(loc.addExternalStream),
onTap: () => AddExternalStreamDialog.show(context),
),
),
]),
]),
),
);
}
}

class NoServers extends StatelessWidget {
const NoServers({super.key});

@override
Widget build(BuildContext context) {
final loc = AppLocalizations.of(context);
final home = context.watch<HomeProvider>();
return Padding(
padding: const EdgeInsetsDirectional.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.dns,
size: 48.0,
),
const SizedBox(height: 6.0),
Text(loc.noServersAdded, textAlign: TextAlign.center),
Text.rich(
TextSpan(
text: loc.howToAddServer,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () => home.setTab(UnityTab.addServer, context),
),
textAlign: TextAlign.center,
),
],
),
);
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/widgets/device_grid/device_grid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import 'package:auto_size_text/auto_size_text.dart';
import 'package:bluecherry_client/models/device.dart';
import 'package:bluecherry_client/models/layout.dart';
import 'package:bluecherry_client/providers/desktop_view_provider.dart';
import 'package:bluecherry_client/providers/home_provider.dart';
import 'package:bluecherry_client/providers/mobile_view_provider.dart';
import 'package:bluecherry_client/providers/server_provider.dart';
import 'package:bluecherry_client/providers/settings_provider.dart';
Expand Down
Loading

0 comments on commit b665bbe

Please sign in to comment.