mirror of
https://github.com/localsend/localsend.git
synced 2026-08-07 07:14:52 +00:00
refactor: make ReceiveTab stateful
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:localsend_app/gen/strings.g.dart';
|
||||
import 'package:localsend_app/model/state/server/server_state.dart';
|
||||
import 'package:localsend_app/pages/home_page.dart';
|
||||
import 'package:localsend_app/pages/home_page_controller.dart';
|
||||
import 'package:localsend_app/pages/receive_history_page.dart';
|
||||
import 'package:localsend_app/pages/tabs/receive_tab_vm.dart';
|
||||
import 'package:localsend_app/pages/web_share_page.dart';
|
||||
import 'package:localsend_app/provider/animation_provider.dart';
|
||||
import 'package:localsend_app/provider/local_ip_provider.dart';
|
||||
import 'package:localsend_app/provider/network/server/server_provider.dart';
|
||||
import 'package:localsend_app/provider/settings_provider.dart';
|
||||
import 'package:localsend_app/util/ip_helper.dart';
|
||||
import 'package:localsend_app/widget/animations/initial_fade_transition.dart';
|
||||
import 'package:localsend_app/widget/column_list_view.dart';
|
||||
@@ -13,16 +16,46 @@ import 'package:localsend_app/widget/custom_icon_button.dart';
|
||||
import 'package:localsend_app/widget/local_send_logo.dart';
|
||||
import 'package:localsend_app/widget/responsive_list_view.dart';
|
||||
import 'package:localsend_app/widget/rotating_widget.dart';
|
||||
import 'package:localsend_isolates/util/sleep.dart';
|
||||
import 'package:refena_flutter/addons.dart';
|
||||
import 'package:refena_flutter/refena_flutter.dart';
|
||||
import 'package:routerino/routerino.dart';
|
||||
|
||||
class ReceiveTab extends StatelessWidget {
|
||||
class ReceiveTab extends StatefulWidget {
|
||||
const ReceiveTab();
|
||||
|
||||
@override
|
||||
State<ReceiveTab> createState() => _ReceiveTabState();
|
||||
}
|
||||
|
||||
class _ReceiveTabState extends State<ReceiveTab> {
|
||||
/// Whether the advanced network info is shown
|
||||
bool _showAdvanced = false;
|
||||
|
||||
/// Whether the history button is shown
|
||||
/// This extra boolean is needed to delay the animation
|
||||
bool _showHistoryButton = true;
|
||||
|
||||
Future<void> _toggleAdvanced() async {
|
||||
if (_showAdvanced) {
|
||||
setState(() => _showAdvanced = false);
|
||||
await sleepAsync(200);
|
||||
if (mounted) {
|
||||
setState(() => _showHistoryButton = true);
|
||||
}
|
||||
} else {
|
||||
setState(() {
|
||||
_showAdvanced = true;
|
||||
_showHistoryButton = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final vm = context.watch(receiveTabVmProvider);
|
||||
final alias = context.watch(settingsProvider.select((s) => s.alias));
|
||||
final serverState = context.watch(serverProvider);
|
||||
final localIps = context.watch(localIpProvider.select((s) => s.localIps));
|
||||
|
||||
return Stack(
|
||||
children: [
|
||||
@@ -47,7 +80,7 @@ class ReceiveTab extends StatelessWidget {
|
||||
final activeTab = ref.watch(homePageControllerProvider.select((state) => state.currentTab));
|
||||
return RotatingWidget(
|
||||
duration: const Duration(seconds: 15),
|
||||
spinning: vm.serverState != null && animations && activeTab == HomeTab.receive,
|
||||
spinning: serverState != null && animations && activeTab == HomeTab.receive,
|
||||
child: const LocalSendLogo(withText: false),
|
||||
);
|
||||
},
|
||||
@@ -55,13 +88,13 @@ class ReceiveTab extends StatelessWidget {
|
||||
),
|
||||
FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
child: Text(vm.serverState?.alias ?? vm.aliasSettings, style: const TextStyle(fontSize: 48)),
|
||||
child: Text(serverState?.alias ?? alias, style: const TextStyle(fontSize: 48)),
|
||||
),
|
||||
InitialFadeTransition(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
delay: const Duration(milliseconds: 500),
|
||||
child: Text(
|
||||
vm.serverState == null ? t.general.offline : vm.localIps.map((ip) => '#${ip.visualId}').toSet().join(' '),
|
||||
serverState == null ? t.general.offline : localIps.map((ip) => '#${ip.visualId}').toSet().join(' '),
|
||||
style: const TextStyle(fontSize: 24),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
@@ -87,11 +120,15 @@ class ReceiveTab extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
_InfoBox(vm),
|
||||
_InfoBox(
|
||||
serverState: serverState,
|
||||
localIps: localIps,
|
||||
showAdvanced: _showAdvanced,
|
||||
),
|
||||
_CornerButtons(
|
||||
showAdvanced: vm.showAdvanced,
|
||||
showHistoryButton: vm.showHistoryButton,
|
||||
toggleAdvanced: vm.toggleAdvanced,
|
||||
showAdvanced: _showAdvanced,
|
||||
showHistoryButton: _showHistoryButton,
|
||||
toggleAdvanced: _toggleAdvanced,
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -142,14 +179,20 @@ class _CornerButtons extends StatelessWidget {
|
||||
}
|
||||
|
||||
class _InfoBox extends StatelessWidget {
|
||||
final ReceiveTabVm vm;
|
||||
final ServerState? serverState;
|
||||
final List<String> localIps;
|
||||
final bool showAdvanced;
|
||||
|
||||
const _InfoBox(this.vm);
|
||||
const _InfoBox({
|
||||
required this.serverState,
|
||||
required this.localIps,
|
||||
required this.showAdvanced,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnimatedCrossFade(
|
||||
crossFadeState: vm.showAdvanced ? CrossFadeState.showSecond : CrossFadeState.showFirst,
|
||||
crossFadeState: showAdvanced ? CrossFadeState.showSecond : CrossFadeState.showFirst,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
firstChild: Container(),
|
||||
secondChild: Align(
|
||||
@@ -172,7 +215,7 @@ class _InfoBox extends StatelessWidget {
|
||||
const SizedBox(width: 10),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 30),
|
||||
child: SelectableText(vm.serverState?.alias ?? '-'),
|
||||
child: SelectableText(serverState?.alias ?? '-'),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -183,8 +226,8 @@ class _InfoBox extends StatelessWidget {
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (vm.localIps.isEmpty) Text(t.general.unknown),
|
||||
...vm.localIps.map((ip) => SelectableText(ip)),
|
||||
if (localIps.isEmpty) Text(t.general.unknown),
|
||||
...localIps.map((ip) => SelectableText(ip)),
|
||||
],
|
||||
),
|
||||
],
|
||||
@@ -193,7 +236,7 @@ class _InfoBox extends StatelessWidget {
|
||||
children: [
|
||||
Text(t.receiveTab.infoBox.port),
|
||||
const SizedBox(width: 10),
|
||||
SelectableText(vm.serverState?.port.toString() ?? '-'),
|
||||
SelectableText(serverState?.port.toString() ?? '-'),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:localsend_app/model/state/server/server_state.dart';
|
||||
import 'package:localsend_app/provider/local_ip_provider.dart';
|
||||
import 'package:localsend_app/provider/network/server/server_provider.dart';
|
||||
import 'package:localsend_app/provider/settings_provider.dart';
|
||||
import 'package:localsend_app/widget/dialogs/quick_save_from_favorites_notice.dart';
|
||||
import 'package:localsend_app/widget/dialogs/quick_save_notice.dart';
|
||||
import 'package:localsend_isolates/util/sleep.dart';
|
||||
import 'package:refena_flutter/refena_flutter.dart';
|
||||
|
||||
/// Whether the advanced network info is shown
|
||||
final _showAdvancedProvider = StateProvider<bool>((ref) => false, debugLabel: '_showAdvancedProvider');
|
||||
|
||||
/// Whether the history button is shown
|
||||
/// This extra boolean is needed to delay the animation
|
||||
final _showHistoryButtonProvider = StateProvider<bool>((ref) => true, debugLabel: '_showHistoryButtonProvider');
|
||||
|
||||
class ReceiveTabVm {
|
||||
final String aliasSettings;
|
||||
final bool quickSaveSettings;
|
||||
final bool quickSaveFromFavoritesSettings;
|
||||
final ServerState? serverState;
|
||||
final List<String> localIps;
|
||||
final bool showAdvanced;
|
||||
final bool showHistoryButton;
|
||||
final Future<void> Function() toggleAdvanced;
|
||||
final Future<void> Function(BuildContext context, bool enable) onSetQuickSave;
|
||||
final Future<void> Function(BuildContext context, bool enable) onSetQuickSaveFromFavorites;
|
||||
|
||||
const ReceiveTabVm({
|
||||
required this.aliasSettings,
|
||||
required this.quickSaveSettings,
|
||||
required this.quickSaveFromFavoritesSettings,
|
||||
required this.serverState,
|
||||
required this.localIps,
|
||||
required this.showAdvanced,
|
||||
required this.showHistoryButton,
|
||||
required this.toggleAdvanced,
|
||||
required this.onSetQuickSave,
|
||||
required this.onSetQuickSaveFromFavorites,
|
||||
});
|
||||
}
|
||||
|
||||
final receiveTabVmProvider = ViewProvider((ref) {
|
||||
final (alias, quickSave, quickSaveFromFavorites) = ref.watch(settingsProvider.select((s) => (s.alias, s.quickSave, s.quickSaveFromFavorites)));
|
||||
final networkInfo = ref.watch(localIpProvider).localIps;
|
||||
final serverState = ref.watch(serverProvider);
|
||||
final showAdvanced = ref.watch(_showAdvancedProvider);
|
||||
final showHistoryButton = ref.watch(_showHistoryButtonProvider);
|
||||
|
||||
return ReceiveTabVm(
|
||||
aliasSettings: alias,
|
||||
quickSaveSettings: quickSave,
|
||||
quickSaveFromFavoritesSettings: quickSaveFromFavorites,
|
||||
serverState: serverState,
|
||||
localIps: networkInfo,
|
||||
showAdvanced: showAdvanced,
|
||||
showHistoryButton: showHistoryButton,
|
||||
toggleAdvanced: () async {
|
||||
if (showAdvanced) {
|
||||
ref.notifier(_showAdvancedProvider).setState((_) => false);
|
||||
await sleepAsync(200);
|
||||
ref.notifier(_showHistoryButtonProvider).setState((_) => true);
|
||||
} else {
|
||||
ref.notifier(_showAdvancedProvider).setState((_) => true);
|
||||
ref.notifier(_showHistoryButtonProvider).setState((_) => false);
|
||||
}
|
||||
},
|
||||
onSetQuickSave: (context, enable) async {
|
||||
await ref.notifier(settingsProvider).setQuickSave(enable);
|
||||
if (enable && context.mounted) {
|
||||
await QuickSaveNotice.open(context);
|
||||
}
|
||||
},
|
||||
onSetQuickSaveFromFavorites: (context, enable) async {
|
||||
await ref.notifier(settingsProvider).setQuickSaveFromFavorites(enable);
|
||||
if (enable && context.mounted) {
|
||||
await QuickSaveFromFavoritesNotice.open(context);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user