.
This commit is contained in:
@@ -0,0 +1,252 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:nextcloud/webdav.dart';
|
||||
import 'package:nextcloudapp/components/file_size.dart';
|
||||
import 'package:nextcloudapp/models/files.dart';
|
||||
import 'package:nextcloudapp/provider/nextcloud_provider.dart';
|
||||
import 'package:nextcloudapp/service/snackbar_service.dart';
|
||||
import 'package:nextcloudapp/components/mime_type.dart';
|
||||
import 'package:file_icon/file_icon.dart';
|
||||
|
||||
class HomeSceen extends StatefulWidget {
|
||||
const HomeSceen({super.key});
|
||||
|
||||
@override
|
||||
State<HomeSceen> createState() => _HomeSceenState();
|
||||
}
|
||||
|
||||
class _HomeSceenState extends State<HomeSceen> {
|
||||
//
|
||||
var _deviceHeight;
|
||||
var _deviceWidth;
|
||||
var _percentage;
|
||||
var _usedMemory;
|
||||
var _totalMemory;
|
||||
var _cwd;
|
||||
|
||||
List<String> _temp = [];
|
||||
List<Files>? _data = [];
|
||||
|
||||
final MimetypeIcon _mimetypeIcon = MimetypeIcon.instance;
|
||||
final FileSize _fileSize = FileSize.instance;
|
||||
final NextcloudProvider _provider = NextcloudProvider.instance;
|
||||
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
_HomeSceenState() {
|
||||
_cwd = "";
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_deviceHeight = MediaQuery.of(context).size.height;
|
||||
_deviceWidth = MediaQuery.of(context).size.width;
|
||||
SnackBarService.instance.buildContext = context;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Container(
|
||||
height: _deviceHeight * 0.10,
|
||||
width: _deviceWidth * 0.20,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
image: DecorationImage(
|
||||
image: AssetImage('assets/images/nextcloud_logo.png'),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text("NextCloud"),
|
||||
],
|
||||
),
|
||||
),
|
||||
drawer: _appDrawerUI(),
|
||||
body: _appBodyUI(),
|
||||
floatingActionButton: _floatingButton());
|
||||
}
|
||||
|
||||
Widget _floatingButton() {
|
||||
return SpeedDial(
|
||||
closeManually: true,
|
||||
animatedIcon: AnimatedIcons.menu_arrow,
|
||||
children: [
|
||||
SpeedDialChild(
|
||||
label: "File Upload",
|
||||
child: Icon(Icons.upload),
|
||||
),
|
||||
SpeedDialChild(
|
||||
label: "Folder Upload",
|
||||
child: Icon(Icons.upload),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _appDrawerUI() {
|
||||
_totalMemory = _provider.userDetails!.quota.total;
|
||||
_usedMemory = _provider.userDetails!.quota.used;
|
||||
_percentage = (_usedMemory / _totalMemory);
|
||||
return NavigationDrawer(
|
||||
backgroundColor: Color.fromARGB(255, 72, 160, 232),
|
||||
children: [
|
||||
Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: _deviceHeight * 0.05,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Text(_provider.userDetails!.displayName),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
_provider.logout();
|
||||
},
|
||||
icon: Icon(Icons.logout_sharp),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: _deviceHeight * 0.20,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Text(
|
||||
'Memory Usage',
|
||||
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
LinearProgressIndicator(
|
||||
value: _percentage,
|
||||
backgroundColor: Colors.grey[300],
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
_percentage > 0.80 ? Colors.red : Colors.green,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Text(
|
||||
'${(_percentage * 100).toStringAsFixed(2)}% used',
|
||||
style: TextStyle(fontSize: 14),
|
||||
),
|
||||
Text(
|
||||
'${_fileSize.getFileSizeString(
|
||||
bytes: _usedMemory,
|
||||
decimals: 1,
|
||||
)} of ${_fileSize.getFileSizeString(
|
||||
bytes: _totalMemory,
|
||||
decimals: 1,
|
||||
)}',
|
||||
style: TextStyle(fontSize: 14),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _appBodyUI() {
|
||||
return SizedBox(
|
||||
height: _deviceHeight * 0.80,
|
||||
child: FutureBuilder(
|
||||
future: _provider.listDirectory(_cwd),
|
||||
builder: (context, _snapshot) {
|
||||
_data = _snapshot.data;
|
||||
if (_data != null) {
|
||||
// WidgetsBinding.instance.addPostFrameCallback(
|
||||
// (_) {
|
||||
// if (_scrollController.hasClients) {
|
||||
// _scrollController
|
||||
// .jumpTo(_scrollController.position.minScrollExtent);
|
||||
// }
|
||||
// },
|
||||
// );
|
||||
|
||||
return Scrollbar(
|
||||
controller: _scrollController,
|
||||
child: ListView.builder(
|
||||
controller: _scrollController,
|
||||
itemCount: _data!.length,
|
||||
itemBuilder: (BuildContext _context, int _index) {
|
||||
return ListTile(
|
||||
onLongPress: () {},
|
||||
onTap: () {
|
||||
setState(() {
|
||||
if (_data![_index].resourceType! == "folder") {
|
||||
if (_index == 0) {
|
||||
_temp.removeAt(_temp.length - 2);
|
||||
_cwd = _temp
|
||||
.join("/")
|
||||
.replaceAll(webdavBase.toString(), '');
|
||||
} else {
|
||||
_cwd = _data![_index]
|
||||
.path!
|
||||
.replaceAll(webdavBase.toString(), '');
|
||||
_temp = _data![_index].path!.split("/");
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
leading: _data![_index].resourceType! == 'folder'
|
||||
? Icon(_mimetypeIcon
|
||||
.getIconForMimeType(_data![_index].contentType!))
|
||||
: FileIcon(
|
||||
_data![_index].name!,
|
||||
size: 32.0,
|
||||
),
|
||||
title: Text(
|
||||
_data![_index].name!,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(fontSize: 15),
|
||||
),
|
||||
subtitle: Text(
|
||||
_index == 0
|
||||
? ''
|
||||
: DateFormat('dd MMM, yyyy hh:mm a')
|
||||
.format(_data![_index].modifiedDate!),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
trailing: Text(
|
||||
_index != 0
|
||||
? _fileSize.getFileSizeString(
|
||||
bytes: _data![_index].size!,
|
||||
decimals: 2,
|
||||
)
|
||||
: '',
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
} else if (_snapshot.hasError) {
|
||||
return Align(
|
||||
child: Text("No Data"),
|
||||
);
|
||||
} else if (_snapshot.connectionState == ConnectionState.waiting) {
|
||||
return Align(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
} else {
|
||||
return Align(
|
||||
child: Text("Undecided"),
|
||||
);
|
||||
;
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
+101
-77
@@ -1,8 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:nextcloudapp/api/login_api.dart';
|
||||
import 'package:nextcloudapp/components/default_values.dart';
|
||||
import 'package:nextcloudapp/screens/welcome_screen.dart';
|
||||
import 'package:nextcloudapp/provider/nextcloud_provider.dart';
|
||||
import 'package:nextcloudapp/service/snackbar_service.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class LoginScreen extends StatefulWidget {
|
||||
const LoginScreen({super.key});
|
||||
@@ -14,44 +13,55 @@ class LoginScreen extends StatefulWidget {
|
||||
class _LoginScreenState extends State<LoginScreen> {
|
||||
var _deviceHeight;
|
||||
var _deviceWidth;
|
||||
var urlController;
|
||||
var usernameController;
|
||||
var passwordController;
|
||||
|
||||
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
||||
|
||||
var checked = false;
|
||||
var _url;
|
||||
var _username;
|
||||
var _password;
|
||||
var enableInput = true;
|
||||
var savePassword = false;
|
||||
var obscureText = true;
|
||||
|
||||
NextcloudProvider _provider = NextcloudProvider.instance;
|
||||
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SnackBarService.instance.buildContext = context;
|
||||
_deviceHeight = MediaQuery.of(context).size.height;
|
||||
_deviceWidth = MediaQuery.of(context).size.width;
|
||||
|
||||
return Scaffold(
|
||||
body: Align(
|
||||
child: Container(
|
||||
height: _deviceHeight * 0.60,
|
||||
padding: EdgeInsets.symmetric(horizontal: _deviceWidth * 0.05),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
_inputField(),
|
||||
_passwordSaveField(),
|
||||
_signInField(),
|
||||
],
|
||||
),
|
||||
child: ChangeNotifierProvider<NextcloudProvider>.value(
|
||||
value: _provider,
|
||||
child: _loginPage(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _inputField() {
|
||||
Widget _loginPage() {
|
||||
return Builder(builder: (BuildContext _context) {
|
||||
SnackBarService.instance.buildContext = _context;
|
||||
_provider = Provider.of<NextcloudProvider>(_context);
|
||||
return Container(
|
||||
height: _deviceHeight * 0.80,
|
||||
padding: EdgeInsets.symmetric(horizontal: _deviceWidth * 0.05),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
_inputForm(),
|
||||
_passwordSaveField(),
|
||||
_signInButton(_context),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _inputForm() {
|
||||
return SizedBox(
|
||||
height: _deviceHeight * 0.25,
|
||||
height: _deviceHeight * 0.27,
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
onChanged: () {
|
||||
@@ -63,64 +73,84 @@ class _LoginScreenState extends State<LoginScreen> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TextFormField(
|
||||
initialValue: "https://storage.theonasanyas.com",
|
||||
enabled: enableInput,
|
||||
keyboardType: TextInputType.url,
|
||||
textInputAction: TextInputAction.next,
|
||||
cursorColor: Colors.white,
|
||||
cursorColor: Colors.black,
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
),
|
||||
onSaved: (_input) {
|
||||
setState(() {
|
||||
urlController = _input!;
|
||||
_url = _input!;
|
||||
});
|
||||
},
|
||||
validator: (_input) {
|
||||
return null;
|
||||
return _input!.isNotEmpty ? null : "nnnns";
|
||||
},
|
||||
decoration: const InputDecoration(
|
||||
decoration: InputDecoration(
|
||||
hintText: "hosting URL",
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.white)
|
||||
),
|
||||
borderSide: BorderSide(color: Colors.white)),
|
||||
prefixIcon: Padding(
|
||||
padding: EdgeInsets.all(defaultPadding),
|
||||
padding: EdgeInsets.all(15.0),
|
||||
child: Icon(Icons.computer_outlined),
|
||||
),
|
||||
),
|
||||
),
|
||||
TextFormField(
|
||||
initialValue: "fluttertest",
|
||||
enabled: enableInput,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
textInputAction: TextInputAction.next,
|
||||
cursorColor: Colors.black,
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
),
|
||||
onSaved: (_input) {
|
||||
if (_input == null) {}
|
||||
setState(() {
|
||||
usernameController = _input!;
|
||||
_username = _input!;
|
||||
});
|
||||
},
|
||||
decoration: const InputDecoration(
|
||||
validator: (_input) {
|
||||
return _input!.isNotEmpty ? null : "nnnns";
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: "username",
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.white)),
|
||||
prefixIcon: Padding(
|
||||
padding: EdgeInsets.all(defaultPadding),
|
||||
padding: EdgeInsets.all(15.0),
|
||||
child: Icon(Icons.person),
|
||||
),
|
||||
),
|
||||
),
|
||||
TextFormField(
|
||||
initialValue: "9tWx8XAv545+ijnBxOrh",
|
||||
enabled: enableInput,
|
||||
keyboardType: TextInputType.visiblePassword,
|
||||
textInputAction: TextInputAction.done,
|
||||
cursorColor: Colors.black,
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
),
|
||||
obscureText: obscureText,
|
||||
onSaved: (_input) {
|
||||
setState(() {
|
||||
passwordController = _input!;
|
||||
_password = _input!;
|
||||
});
|
||||
},
|
||||
cursorColor: primaryColor,
|
||||
validator: (_input) {
|
||||
return _input!.isNotEmpty ? null : "nnnns";
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: "Password",
|
||||
hintText: "password",
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.white)),
|
||||
prefixIcon: const Padding(
|
||||
padding: EdgeInsets.all(defaultPadding),
|
||||
padding: EdgeInsets.all(15.0),
|
||||
child: Icon(Icons.lock),
|
||||
),
|
||||
suffixIcon: IconButton(
|
||||
@@ -146,51 +176,45 @@ class _LoginScreenState extends State<LoginScreen> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Checkbox(
|
||||
value: checked,
|
||||
value: savePassword,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
checked = value!;
|
||||
savePassword = value!;
|
||||
});
|
||||
}),
|
||||
const Text('Save Password'),
|
||||
const Text('save password'),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _signInField() {
|
||||
return ElevatedButton(
|
||||
onPressed: () {
|
||||
login(urlController.value.text, usernameController.value.text,
|
||||
passwordController.value.text)
|
||||
.then((
|
||||
status,
|
||||
) {
|
||||
if (status.startsWith('successful')) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return const WelcomeScreen();
|
||||
},
|
||||
Widget _signInButton(BuildContext _context) {
|
||||
return _provider.status == AuthStatus.authenticating
|
||||
? Align(
|
||||
alignment: Alignment.center,
|
||||
child: CircularProgressIndicator(),
|
||||
)
|
||||
: SizedBox(
|
||||
height: _deviceHeight * 0.06,
|
||||
width: _deviceWidth * 0.30,
|
||||
child: MaterialButton(
|
||||
onPressed: () async {
|
||||
enableInput = !enableInput;
|
||||
if (_formKey.currentState!.validate()) {
|
||||
//Login User
|
||||
await _provider.login(
|
||||
_url, _username, _password, savePassword);
|
||||
}
|
||||
enableInput = !enableInput;
|
||||
},
|
||||
color: Colors.grey,
|
||||
child: Text(
|
||||
'login',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
SnackBarService.instance.showSnackBarSuccess(status);
|
||||
} else {
|
||||
SnackBarService.instance.showSnackBarError(status);
|
||||
}
|
||||
});
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
"sign in".toUpperCase(),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
const Icon(Icons.login)
|
||||
],
|
||||
),
|
||||
);
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class WelcomeScreen extends StatefulWidget {
|
||||
const WelcomeScreen({super.key});
|
||||
|
||||
@override
|
||||
State<WelcomeScreen> createState() => _WelcomeScreenState();
|
||||
}
|
||||
|
||||
class _WelcomeScreenState extends State<WelcomeScreen> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Scaffold(
|
||||
body: Column(
|
||||
children: [
|
||||
|
||||
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user