mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-18 15:54:35 +01:00
opt.: split single list into multiples on desktop (#524)
This commit is contained in:
@@ -30,18 +30,22 @@ class BackupPage extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _buildBody(BuildContext context) {
|
||||
return ListView(
|
||||
padding: const EdgeInsets.all(13),
|
||||
return MultiList(
|
||||
widthDivider: 2,
|
||||
children: [
|
||||
_buildTip(),
|
||||
CenterGreyTitle(libL10n.sync),
|
||||
if (isMacOS || isIOS) _buildIcloud(context),
|
||||
_buildWebdav(context),
|
||||
_buildFile(context),
|
||||
_buildClipboard(context),
|
||||
CenterGreyTitle(libL10n.import),
|
||||
_buildBulkImportServers(context),
|
||||
_buildImportSnippet(context),
|
||||
[
|
||||
CenterGreyTitle(libL10n.sync),
|
||||
_buildTip(),
|
||||
if (isMacOS || isIOS) _buildIcloud(context),
|
||||
_buildWebdav(context),
|
||||
_buildFile(context),
|
||||
_buildClipboard(context),
|
||||
],
|
||||
[
|
||||
CenterGreyTitle(libL10n.import),
|
||||
_buildBulkImportServers(context),
|
||||
_buildImportSnippet(context),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import 'package:server_box/core/extension/context/locale.dart';
|
||||
import 'package:server_box/data/res/rebuild.dart';
|
||||
import 'package:server_box/data/res/store.dart';
|
||||
import 'package:server_box/data/res/url.dart';
|
||||
import 'package:server_box/view/page/setting/platform/platform_pub.dart';
|
||||
|
||||
import '../../../core/route.dart';
|
||||
import '../../../data/model/app/net_view.dart';
|
||||
@@ -54,27 +53,28 @@ class _SettingPageState extends State<SettingPage> {
|
||||
),
|
||||
],
|
||||
),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17),
|
||||
body: MultiList(
|
||||
widthDivider: 2.3,
|
||||
thumbVisibility: true,
|
||||
children: [
|
||||
const CenterGreyTitle('App'),
|
||||
_buildApp(),
|
||||
CenterGreyTitle(l10n.server),
|
||||
_buildServer(),
|
||||
CenterGreyTitle(l10n.container),
|
||||
_buildContainer(),
|
||||
const CenterGreyTitle('SSH'),
|
||||
_buildSSH(),
|
||||
const CenterGreyTitle('SFTP'),
|
||||
_buildSFTP(),
|
||||
CenterGreyTitle(l10n.editor),
|
||||
_buildEditor(),
|
||||
[const CenterGreyTitle('App'), _buildApp()],
|
||||
[CenterGreyTitle(l10n.server), _buildServer()],
|
||||
[
|
||||
const CenterGreyTitle('SSH'),
|
||||
_buildSSH(),
|
||||
const CenterGreyTitle('SFTP'),
|
||||
_buildSFTP()
|
||||
],
|
||||
[
|
||||
CenterGreyTitle(l10n.container),
|
||||
_buildContainer(),
|
||||
CenterGreyTitle(l10n.editor),
|
||||
_buildEditor(),
|
||||
],
|
||||
|
||||
/// Fullscreen Mode is designed for old mobile phone which can be
|
||||
/// used as a status screen.
|
||||
if (isMobile) CenterGreyTitle(l10n.fullScreen),
|
||||
if (isMobile) _buildFullScreen(),
|
||||
const SizedBox(height: 37),
|
||||
if (isMobile) [CenterGreyTitle(l10n.fullScreen), _buildFullScreen()],
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -948,6 +948,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
return ExpandTile(
|
||||
leading: const Icon(MingCute.more_3_fill),
|
||||
title: Text(l10n.more),
|
||||
initiallyExpanded: isDesktop,
|
||||
children: [
|
||||
_buildRememberPwdInMem(),
|
||||
_buildTextScaler(),
|
||||
@@ -1010,13 +1011,13 @@ class _SettingPageState extends State<SettingPage> {
|
||||
return ExpandTile(
|
||||
leading: const Icon(MingCute.more_3_fill),
|
||||
title: Text(l10n.more),
|
||||
initiallyExpanded: isDesktop,
|
||||
children: [
|
||||
_buildBeta(),
|
||||
if (isMobile) _buildWakeLock(),
|
||||
_buildCollapseUI(),
|
||||
_buildCupertinoRoute(),
|
||||
if (isDesktop) _buildHideTitleBar(),
|
||||
if (isDesktop) PlatformPublicSettings.buildSaveWindowSize(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import 'package:fl_lib/fl_lib.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:server_box/core/extension/context/locale.dart';
|
||||
import 'package:server_box/data/res/store.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
abstract final class PlatformPublicSettings {
|
||||
static Widget buildBioAuth() {
|
||||
@@ -46,49 +44,4 @@ abstract final class PlatformPublicSettings {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static Widget buildSaveWindowSize() {
|
||||
final isBusy = false.vn;
|
||||
// Only show [FadeIn] when previous state is busy.
|
||||
var lastIsBusy = false;
|
||||
final prop = Stores.setting.windowSize;
|
||||
|
||||
return ListTile(
|
||||
title: Text(l10n.rememberWindowSize),
|
||||
|
||||
/// Copied from `fl_build/view/store_switch`
|
||||
trailing: ValBuilder(
|
||||
listenable: isBusy,
|
||||
builder: (busy) {
|
||||
return ValBuilder(
|
||||
listenable: prop.listenable(),
|
||||
builder: (value) {
|
||||
if (busy) {
|
||||
lastIsBusy = true;
|
||||
return UIs.centerSizedLoadingSmall.paddingOnly(right: 17);
|
||||
}
|
||||
|
||||
final switcher = Switch(
|
||||
value: value.isNotEmpty,
|
||||
onChanged: (value) async {
|
||||
isBusy.value = true;
|
||||
final size = await windowManager.getSize();
|
||||
isBusy.value = false;
|
||||
prop.put(size.toIntStr());
|
||||
},
|
||||
);
|
||||
|
||||
if (lastIsBusy) {
|
||||
final ret = FadeIn(child: switcher);
|
||||
lastIsBusy = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return switcher;
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ final class _TabBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 5),
|
||||
itemCount: names.length,
|
||||
itemBuilder: (_, idx) => _buillItem(idx),
|
||||
itemBuilder: (_, idx) => _buildItem(idx),
|
||||
separatorBuilder: (_, __) => Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 17),
|
||||
child: Container(
|
||||
@@ -234,7 +234,10 @@ final class _TabBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buillItem(int idx) {
|
||||
static const kWideWidth = 90.0;
|
||||
static const kNarrowWidth = 60.0;
|
||||
|
||||
Widget _buildItem(int idx) {
|
||||
final name = names[idx];
|
||||
final selected = idxVN.value == idx;
|
||||
final color = selected ? null : Colors.grey;
|
||||
@@ -255,31 +258,28 @@ final class _TabBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
textAlign: TextAlign.center,
|
||||
textWidthBasis: TextWidthBasis.parent,
|
||||
);
|
||||
final Widget btn;
|
||||
if (selected) {
|
||||
btn = Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
Btn.icon(
|
||||
icon: Icon(MingCute.close_circle_fill, color: color, size: 17),
|
||||
onTap: () => onClose(name),
|
||||
padding: null,
|
||||
),
|
||||
SizedBox(width: kNarrowWidth - 10, child: text),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
btn = Center(child: text);
|
||||
}
|
||||
child = AnimatedContainer(
|
||||
width: selected ? 90 : 57,
|
||||
width: selected ? kWideWidth : kNarrowWidth,
|
||||
duration: Durations.medium3,
|
||||
padding: selected ? const EdgeInsets.symmetric(horizontal: 7) : null,
|
||||
curve: Curves.fastEaseInToSlowEaseOut,
|
||||
child: switch (selected) {
|
||||
true => Row(
|
||||
children: [
|
||||
if (selected)
|
||||
FadeIn(
|
||||
child: Btn.icon(
|
||||
icon: Icon(
|
||||
MingCute.close_circle_fill,
|
||||
color: color,
|
||||
size: 17,
|
||||
),
|
||||
onTap: () => onClose(name),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
SizedBox(width: 50, child: text),
|
||||
],
|
||||
),
|
||||
false => Center(child: text),
|
||||
},
|
||||
child: btn,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user