feat: finalize app icon status

This commit is contained in:
Tien Do Nam
2024-09-17 01:31:02 +09:00
parent 3b1ce0756a
commit dbedac1464
6 changed files with 67 additions and 20 deletions
+1
View File
@@ -6,6 +6,7 @@
- feat(macos): drag-and-drop files and text into menu bar icon (@ShlomoCode)
- feat(macos): drag-and-drop text into the app icon (@ShlomoCode)
- feat(macos): include LocalSend as a share target in the share menu (@ShlomoCode)
- feat(macos): show error and success state in the app icon (@ShlomoCode, @Tienisto)
## 1.15.4 (2024-08-20)
+11 -2
View File
@@ -49,6 +49,7 @@ class _ProgressPageState extends State<ProgressPage> with Refena {
String? _remainingTime;
List<FileDto> _files = []; // also contains declined files (files without token)
Set<String> _selectedFiles = {};
SessionStatus? _lastStatus;
// If [autoFinish] is enabled, we wait a few seconds before automatically closing the session.
int _finishCounter = 3;
@@ -169,12 +170,20 @@ class _ProgressPageState extends State<ProgressPage> with Refena {
final currBytes = _files.fold<int>(
0, (prev, curr) => prev + ((progressNotifier.getProgress(sessionId: widget.sessionId, fileId: curr.id) * curr.size).round()));
unawaited(TaskbarHelper.setProgressBar(currBytes, _totalBytes));
final receiveSession = ref.watch(serverProvider.select((s) => s?.session));
final sendSession = ref.watch(sendProvider)[widget.sessionId];
final SessionStatus? status = receiveSession?.status ?? sendSession?.status;
if (status == SessionStatus.sending) {
// ignore: discarded_futures
TaskbarHelper.setProgressBar(currBytes, _totalBytes);
} else if (status != _lastStatus) {
_lastStatus = status;
// ignore: discarded_futures
TaskbarHelper.visualizeStatus(status);
}
if (status == null) {
return Scaffold(
body: Container(),
+7 -7
View File
@@ -22,7 +22,6 @@ import 'package:localsend_app/widget/responsive_list_view.dart';
import 'package:refena_flutter/refena_flutter.dart';
import 'package:routerino/routerino.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:windows_taskbar/windows_taskbar.dart';
class ReceivePage extends StatefulWidget {
const ReceivePage({super.key});
@@ -40,7 +39,13 @@ class _ReceivePageState extends State<ReceivePage> with Refena {
@override
Widget build(BuildContext context) {
final vm = context.watch(receivePageControllerProvider);
final vm = context.watch(receivePageControllerProvider, listener: (prev, next) {
if (prev.status != next.status) {
// ignore: discarded_futures
TaskbarHelper.visualizeStatus(next.status);
}
});
if (vm.status == null && vm.message == null) {
return const Scaffold(
body: SizedBox(),
@@ -48,11 +53,6 @@ class _ReceivePageState extends State<ReceivePage> with Refena {
}
final senderFavoriteEntry = ref.watch(favoritesProvider.select((state) => state.findDevice(vm.sender)));
if (vm.status == SessionStatus.canceledBySender) {
unawaited(TaskbarHelper.setProgressBarMode(TaskbarProgressMode.error));
} else {
unawaited(TaskbarHelper.setProgressBarMode(TaskbarProgressMode.indeterminate));
}
return WillPopScope(
onWillPop: () async {
+8 -8
View File
@@ -17,7 +17,6 @@ import 'package:localsend_app/widget/list_tile/device_list_tile.dart';
import 'package:localsend_app/widget/responsive_list_view.dart';
import 'package:refena_flutter/refena_flutter.dart';
import 'package:routerino/routerino.dart';
import 'package:windows_taskbar/windows_taskbar.dart';
class SendPage extends StatefulWidget {
final bool showAppBar;
@@ -61,7 +60,14 @@ class _SendPageState extends State<SendPage> with Refena {
@override
Widget build(BuildContext context) {
final sendState = ref.watch(sendProvider)[widget.sessionId];
final sendState = ref.watch(sendProvider.select((state) => state[widget.sessionId]), listener: (prev, next) {
final prevStatus = prev[widget.sessionId]?.status;
final nextStatus = next[widget.sessionId]?.status;
if (prevStatus != nextStatus) {
// ignore: discarded_futures
TaskbarHelper.visualizeStatus(nextStatus);
}
});
if (sendState == null && _myDevice == null && _targetDevice == null) {
return Scaffold(
body: Container(),
@@ -72,12 +78,6 @@ class _SendPageState extends State<SendPage> with Refena {
final targetFavoriteEntry = ref.watch(favoritesProvider.select((state) => state.findDevice(targetDevice)));
final waiting = sendState?.status == SessionStatus.waiting;
if (sendState?.status == SessionStatus.declined || sendState?.status == SessionStatus.finishedWithErrors) {
unawaited(TaskbarHelper.setProgressBarMode(TaskbarProgressMode.error));
} else {
unawaited(TaskbarHelper.setProgressBarMode(TaskbarProgressMode.indeterminate));
}
return WillPopScope(
onWillPop: () async {
if (widget.closeSessionOnClose) {
+37 -1
View File
@@ -1,3 +1,4 @@
import 'package:common/model/session_status.dart';
import 'package:flutter/material.dart';
import 'package:localsend_app/util/native/macos_channel.dart';
import 'package:localsend_app/util/native/platform_check.dart';
@@ -25,6 +26,7 @@ class TaskbarHelper {
if (_isWindows) {
await WindowsTaskbar.setProgress(digestedProgress, digestedTotal);
} else if (_isMacos) {
print(progress);
await updateDockProgress(progress / total);
}
} else {
@@ -40,11 +42,45 @@ class TaskbarHelper {
}
}
Future<void> setTaskbarIcon(TaskbarIcon icon) async {
static Future<void> setTaskbarIcon(TaskbarIcon icon) async {
if (_isMacos) {
await setDockIcon(icon);
}
}
static Future<void> visualizeStatus(SessionStatus? status) async {
// macOS handling
switch (status) {
case SessionStatus.finished:
await TaskbarHelper.setTaskbarIcon(TaskbarIcon.success);
break;
case SessionStatus.declined:
case SessionStatus.recipientBusy:
case SessionStatus.finishedWithErrors:
case SessionStatus.canceledBySender:
case SessionStatus.canceledByReceiver:
await TaskbarHelper.setTaskbarIcon(TaskbarIcon.error);
break;
default:
await TaskbarHelper.setTaskbarIcon(TaskbarIcon.regular);
}
// Windows handling
switch (status) {
case SessionStatus.waiting:
await TaskbarHelper.setProgressBarMode(TaskbarProgressMode.indeterminate);
break;
case SessionStatus.declined:
case SessionStatus.recipientBusy:
case SessionStatus.finishedWithErrors:
case SessionStatus.canceledBySender:
case SessionStatus.canceledByReceiver:
await TaskbarHelper.setProgressBarMode(TaskbarProgressMode.error);
break;
default:
await TaskbarHelper.setProgressBarMode(TaskbarProgressMode.normal);
}
}
}
(int, int) _scaleRange(int progress, int total) {
+3 -2
View File
@@ -3,7 +3,7 @@ import FlutterMacOS
import Defaults
import DockProgress
enum DockIcon {
enum DockIcon: CaseIterable {
case regular
case error
case success
@@ -150,7 +150,8 @@ class AppDelegate: FlutterAppDelegate {
DockProgress.progress = progress
result(nil)
case "setDockIcon":
let newIcon = call.arguments as! DockIcon
let newIconIndex = call.arguments as! Int
let newIcon = DockIcon.allCases[newIconIndex]
setDockIcon(icon: newIcon)
default:
result(FlutterMethodNotImplemented)