This commit is contained in:
@@ -10,6 +10,7 @@ import 'package:provider/provider.dart';
|
|||||||
import 'package:repertory/constants.dart' as constants;
|
import 'package:repertory/constants.dart' as constants;
|
||||||
import 'package:repertory/models/auth.dart';
|
import 'package:repertory/models/auth.dart';
|
||||||
import 'package:repertory/models/settings.dart';
|
import 'package:repertory/models/settings.dart';
|
||||||
|
import 'package:repertory/widgets/app_dropdown.dart';
|
||||||
import 'package:repertory/widgets/aurora_sweep.dart';
|
import 'package:repertory/widgets/aurora_sweep.dart';
|
||||||
import 'package:sodium_libs/sodium_libs.dart' show SecureKey, StringX;
|
import 'package:sodium_libs/sodium_libs.dart' show SecureKey, StringX;
|
||||||
|
|
||||||
@@ -414,16 +415,12 @@ Future<String?> editMountLocation(
|
|||||||
controller: controller,
|
controller: controller,
|
||||||
onChanged: (value) => setState(() => currentLocation = value),
|
onChanged: (value) => setState(() => currentLocation = value),
|
||||||
)
|
)
|
||||||
: DropdownButton<String>(
|
: AppDropdownFormField<String>(
|
||||||
hint: const Text("Select drive"),
|
labelText: "Select drive",
|
||||||
|
labelOf: (s) => s,
|
||||||
value: currentLocation,
|
value: currentLocation,
|
||||||
onChanged: (value) => setState(() => currentLocation = value),
|
onChanged: (value) => setState(() => currentLocation = value),
|
||||||
items: available.map<DropdownMenuItem<String>>((item) {
|
values: available.toList(),
|
||||||
return DropdownMenuItem<String>(
|
|
||||||
value: item,
|
|
||||||
child: Text(item),
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
),
|
),
|
||||||
title: const Text('Mount Location', textAlign: TextAlign.center),
|
title: const Text('Mount Location', textAlign: TextAlign.center),
|
||||||
);
|
);
|
||||||
@@ -432,47 +429,49 @@ Future<String?> editMountLocation(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold createCommonScaffold(Widget child, {Widget? floatingActionButton}) =>
|
Scaffold createCommonScaffold(
|
||||||
Scaffold(
|
List<Widget> children, {
|
||||||
body: SafeArea(
|
Widget? floatingActionButton,
|
||||||
child: Stack(
|
}) => Scaffold(
|
||||||
children: [
|
body: SafeArea(
|
||||||
Container(
|
child: Stack(
|
||||||
width: double.infinity,
|
children: [
|
||||||
height: double.infinity,
|
Container(
|
||||||
decoration: const BoxDecoration(
|
width: double.infinity,
|
||||||
gradient: LinearGradient(
|
height: double.infinity,
|
||||||
begin: Alignment.topLeft,
|
decoration: const BoxDecoration(
|
||||||
end: Alignment.bottomRight,
|
gradient: LinearGradient(
|
||||||
colors: constants.gradientColors,
|
begin: Alignment.topLeft,
|
||||||
),
|
end: Alignment.bottomRight,
|
||||||
),
|
colors: constants.gradientColors,
|
||||||
),
|
),
|
||||||
Consumer<Settings>(
|
),
|
||||||
builder: (_, settings, _) =>
|
|
||||||
AuroraSweep(enabled: settings.enableAnimations),
|
|
||||||
),
|
|
||||||
Positioned.fill(
|
|
||||||
child: BackdropFilter(
|
|
||||||
filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6),
|
|
||||||
child: Container(color: Colors.black.withValues(alpha: 0.06)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child,
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
Consumer<Settings>(
|
||||||
floatingActionButton: floatingActionButton,
|
builder: (_, settings, _) =>
|
||||||
);
|
AuroraSweep(enabled: settings.enableAnimations),
|
||||||
|
),
|
||||||
|
Positioned.fill(
|
||||||
|
child: BackdropFilter(
|
||||||
|
filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6),
|
||||||
|
child: Container(color: Colors.black.withValues(alpha: 0.06)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
...children,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
floatingActionButton: floatingActionButton,
|
||||||
|
);
|
||||||
|
|
||||||
InputDecoration createCommonDecoration(
|
InputDecoration createCommonDecoration(
|
||||||
ColorScheme colorScheme,
|
ColorScheme colorScheme,
|
||||||
String label,
|
String label, {
|
||||||
IconData icon, {
|
IconData? icon,
|
||||||
bool filled = true,
|
bool filled = true,
|
||||||
}) => InputDecoration(
|
}) => InputDecoration(
|
||||||
labelText: label,
|
labelText: label,
|
||||||
prefixIcon: Icon(icon),
|
prefixIcon: icon == null ? null : Icon(icon),
|
||||||
filled: filled,
|
filled: filled,
|
||||||
fillColor: colorScheme.primary.withValues(alpha: constants.primaryAlpha),
|
fillColor: colorScheme.primary.withValues(alpha: constants.primaryAlpha),
|
||||||
border: OutlineInputBorder(
|
border: OutlineInputBorder(
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import 'package:repertory/models/auth.dart';
|
|||||||
import 'package:repertory/models/mount.dart';
|
import 'package:repertory/models/mount.dart';
|
||||||
import 'package:repertory/models/mount_list.dart';
|
import 'package:repertory/models/mount_list.dart';
|
||||||
import 'package:repertory/types/mount_config.dart';
|
import 'package:repertory/types/mount_config.dart';
|
||||||
|
import 'package:repertory/widgets/app_dropdown.dart';
|
||||||
import 'package:repertory/widgets/mount_settings.dart';
|
import 'package:repertory/widgets/mount_settings.dart';
|
||||||
|
|
||||||
class AddMountScreen extends StatefulWidget {
|
class AddMountScreen extends StatefulWidget {
|
||||||
@@ -44,7 +45,7 @@ class _AddMountScreenState extends State<AddMountScreen> {
|
|||||||
final scheme = Theme.of(context).colorScheme;
|
final scheme = Theme.of(context).colorScheme;
|
||||||
final textTheme = Theme.of(context).textTheme;
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
|
||||||
return createCommonScaffold(
|
return createCommonScaffold([
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(constants.padding),
|
padding: const EdgeInsets.all(constants.padding),
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -128,41 +129,21 @@ class _AddMountScreenState extends State<AddMountScreen> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: constants.padding),
|
const SizedBox(height: constants.padding),
|
||||||
UnconstrainedBox(
|
AppDropdownFormField<String>(
|
||||||
alignment: Alignment.centerLeft,
|
labelText: 'Provider Type',
|
||||||
child: IntrinsicWidth(
|
prefixIcon: Icons.extension,
|
||||||
stepWidth: 250.0,
|
values: constants.providerTypeList,
|
||||||
child: DropdownButtonFormField<String>(
|
value: _mountType.isEmpty ? null : _mountType,
|
||||||
initialValue: _mountType.isEmpty ? null : _mountType,
|
labelOf: (s) => s,
|
||||||
isExpanded: false,
|
onChanged: (mountType) {
|
||||||
decoration: createCommonDecoration(
|
_handleChange(
|
||||||
scheme,
|
Provider.of<Auth>(context, listen: false),
|
||||||
"Provider Type",
|
mountType ?? '',
|
||||||
Icons.storage,
|
);
|
||||||
),
|
},
|
||||||
dropdownColor: scheme.primary.withValues(alpha: 0.8),
|
constrainToIntrinsic: true,
|
||||||
style: textTheme.bodyMedium?.copyWith(
|
widthMultiplier: 2.0,
|
||||||
color: scheme.onSurface.withValues(alpha: 0.96),
|
isExpanded: false,
|
||||||
),
|
|
||||||
items: constants.providerTypeList.map((item) {
|
|
||||||
return DropdownMenuItem<String>(
|
|
||||||
value: item,
|
|
||||||
child: Text(
|
|
||||||
item,
|
|
||||||
style: textTheme.bodyMedium?.copyWith(
|
|
||||||
color: scheme.onSurface.withValues(alpha: 0.96),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
onChanged: (mountType) {
|
|
||||||
_handleChange(
|
|
||||||
Provider.of<Auth>(context, listen: false),
|
|
||||||
mountType ?? '',
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
if (_mountType.isNotEmpty && _mountType != 'Remote') ...[
|
if (_mountType.isNotEmpty && _mountType != 'Remote') ...[
|
||||||
const SizedBox(height: constants.padding),
|
const SizedBox(height: constants.padding),
|
||||||
@@ -180,7 +161,7 @@ class _AddMountScreenState extends State<AddMountScreen> {
|
|||||||
decoration: createCommonDecoration(
|
decoration: createCommonDecoration(
|
||||||
scheme,
|
scheme,
|
||||||
'Configuration Name',
|
'Configuration Name',
|
||||||
Icons.drive_file_rename_outline,
|
icon: Icons.drive_file_rename_outline,
|
||||||
).copyWith(hintText: 'Enter a unique name'),
|
).copyWith(hintText: 'Enter a unique name'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -324,7 +305,7 @@ class _AddMountScreenState extends State<AddMountScreen> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleChange(Auth auth, String mountType) {
|
void _handleChange(Auth auth, String mountType) {
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ class _AuthScreenState extends State<AuthScreen> {
|
|||||||
decoration: createCommonDecoration(
|
decoration: createCommonDecoration(
|
||||||
scheme,
|
scheme,
|
||||||
'Username',
|
'Username',
|
||||||
Icons.person,
|
icon: Icons.person,
|
||||||
),
|
),
|
||||||
validator: (v) {
|
validator: (v) {
|
||||||
if (v == null || v.trim().isEmpty) {
|
if (v == null || v.trim().isEmpty) {
|
||||||
@@ -255,7 +255,7 @@ class _AuthScreenState extends State<AuthScreen> {
|
|||||||
createCommonDecoration(
|
createCommonDecoration(
|
||||||
scheme,
|
scheme,
|
||||||
'Password',
|
'Password',
|
||||||
Icons.lock,
|
icon: Icons.lock,
|
||||||
).copyWith(
|
).copyWith(
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
tooltip: _obscure
|
tooltip: _obscure
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class _EditMountScreenState extends State<EditMountScreen> {
|
|||||||
final scheme = Theme.of(context).colorScheme;
|
final scheme = Theme.of(context).colorScheme;
|
||||||
final textTheme = Theme.of(context).textTheme;
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
|
||||||
return createCommonScaffold(
|
return createCommonScaffold([
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
@@ -215,7 +215,7 @@ class _EditMountScreenState extends State<EditMountScreen> {
|
|||||||
const SizedBox(height: constants.padding),
|
const SizedBox(height: constants.padding),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class _EditSettingsScreenState extends State<EditSettingsScreen> {
|
|||||||
final scheme = Theme.of(context).colorScheme;
|
final scheme = Theme.of(context).colorScheme;
|
||||||
final textTheme = Theme.of(context).textTheme;
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
|
||||||
return createCommonScaffold(
|
return createCommonScaffold([
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
@@ -174,7 +174,7 @@ class _EditSettingsScreenState extends State<EditSettingsScreen> {
|
|||||||
const SizedBox(height: constants.padding),
|
const SizedBox(height: constants.padding),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Map<String, dynamic>> _grabSettings() async {
|
Future<Map<String, dynamic>> _grabSettings() async {
|
||||||
|
|||||||
@@ -24,119 +24,128 @@ class _HomeScreeState extends State<HomeScreen> {
|
|||||||
final textTheme = Theme.of(context).textTheme;
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
|
||||||
return createCommonScaffold(
|
return createCommonScaffold(
|
||||||
Column(
|
[
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
Column(
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
const SizedBox(height: constants.padding),
|
children: [
|
||||||
Padding(
|
const SizedBox(height: constants.padding),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: constants.padding),
|
Padding(
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
child: Image.asset(
|
|
||||||
'assets/images/repertory.png',
|
|
||||||
fit: BoxFit.contain,
|
|
||||||
errorBuilder: (_, _, _) {
|
|
||||||
return Icon(
|
|
||||||
Icons.folder,
|
|
||||||
color: scheme.primary,
|
|
||||||
size: 32,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: constants.padding),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
widget.title,
|
|
||||||
maxLines: 1,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: textTheme.headlineSmall?.copyWith(
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
letterSpacing: 0.2,
|
|
||||||
color: scheme.onSurface.withValues(alpha: 0.96),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: constants.padding),
|
|
||||||
ClipRRect(
|
|
||||||
borderRadius: BorderRadius.circular(constants.borderRadius),
|
|
||||||
child: BackdropFilter(
|
|
||||||
filter: ImageFilter.blur(
|
|
||||||
sigmaX: constants.borderRadius,
|
|
||||||
sigmaY: constants.borderRadius,
|
|
||||||
),
|
|
||||||
child: Container(
|
|
||||||
height: 40,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: scheme.surface.withValues(alpha: 0.40),
|
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
constants.borderRadius,
|
|
||||||
),
|
|
||||||
border: Border.all(
|
|
||||||
color: scheme.outlineVariant.withValues(alpha: 0.08),
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
const Text("Auto-start"),
|
|
||||||
Consumer<Settings>(
|
|
||||||
builder: (context, settings, _) {
|
|
||||||
return IconButton(
|
|
||||||
icon: Icon(
|
|
||||||
settings.autoStart
|
|
||||||
? Icons.toggle_on
|
|
||||||
: Icons.toggle_off,
|
|
||||||
),
|
|
||||||
color: settings.autoStart
|
|
||||||
? scheme.primary
|
|
||||||
: scheme.onSurface.withValues(alpha: 0.70),
|
|
||||||
onPressed: () =>
|
|
||||||
settings.setAutoStart(!settings.autoStart),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
IconButton(
|
|
||||||
tooltip: 'Settings',
|
|
||||||
icon: const Icon(Icons.settings),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.pushNamed(context, '/settings');
|
|
||||||
},
|
|
||||||
),
|
|
||||||
Consumer<Auth>(
|
|
||||||
builder: (context, auth, _) {
|
|
||||||
return IconButton(
|
|
||||||
tooltip: 'Log out',
|
|
||||||
icon: const Icon(Icons.logout),
|
|
||||||
onPressed: () {
|
|
||||||
auth.logoff();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: constants.padding),
|
|
||||||
Expanded(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: constants.padding,
|
horizontal: constants.padding,
|
||||||
),
|
),
|
||||||
child: const MountListWidget(),
|
child: Row(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
child: Image.asset(
|
||||||
|
'assets/images/repertory.png',
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
errorBuilder: (_, _, _) {
|
||||||
|
return Icon(
|
||||||
|
Icons.folder,
|
||||||
|
color: scheme.primary,
|
||||||
|
size: 32,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: constants.padding),
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
widget.title,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: textTheme.headlineSmall?.copyWith(
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
letterSpacing: 0.2,
|
||||||
|
color: scheme.onSurface.withValues(alpha: 0.96),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: constants.padding),
|
||||||
|
ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(constants.borderRadius),
|
||||||
|
child: BackdropFilter(
|
||||||
|
filter: ImageFilter.blur(
|
||||||
|
sigmaX: constants.borderRadius,
|
||||||
|
sigmaY: constants.borderRadius,
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
|
height: 40,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 6),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: scheme.surface.withValues(alpha: 0.40),
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
constants.borderRadius,
|
||||||
|
),
|
||||||
|
border: Border.all(
|
||||||
|
color: scheme.outlineVariant.withValues(
|
||||||
|
alpha: 0.08,
|
||||||
|
),
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Text("Auto-start"),
|
||||||
|
Consumer<Settings>(
|
||||||
|
builder: (context, settings, _) {
|
||||||
|
return IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
settings.autoStart
|
||||||
|
? Icons.toggle_on
|
||||||
|
: Icons.toggle_off,
|
||||||
|
),
|
||||||
|
color: settings.autoStart
|
||||||
|
? scheme.primary
|
||||||
|
: scheme.onSurface.withValues(
|
||||||
|
alpha: 0.70,
|
||||||
|
),
|
||||||
|
onPressed: () => settings.setAutoStart(
|
||||||
|
!settings.autoStart,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
tooltip: 'Settings',
|
||||||
|
icon: const Icon(Icons.settings),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pushNamed(context, '/settings');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Consumer<Auth>(
|
||||||
|
builder: (context, auth, _) {
|
||||||
|
return IconButton(
|
||||||
|
tooltip: 'Log out',
|
||||||
|
icon: const Icon(Icons.logout),
|
||||||
|
onPressed: () {
|
||||||
|
auth.logoff();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: constants.padding),
|
||||||
],
|
Expanded(
|
||||||
),
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: constants.padding,
|
||||||
|
),
|
||||||
|
child: const MountListWidget(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
floatingActionButton: Padding(
|
floatingActionButton: Padding(
|
||||||
padding: const EdgeInsets.all(constants.padding),
|
padding: const EdgeInsets.all(constants.padding),
|
||||||
child: Hero(
|
child: Hero(
|
||||||
|
|||||||
Reference in New Issue
Block a user