ente/lib/ui/sessions_page.dart
2021-11-27 11:24:57 +05:30

206 lines
5.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:photos/core/configuration.dart';
import 'package:photos/models/sessions.dart';
import 'package:photos/services/user_service.dart';
import 'package:photos/ui/loading_widget.dart';
import 'package:photos/utils/date_time_util.dart';
import 'package:photos/utils/dialog_util.dart';
import 'package:photos/utils/toast_util.dart';
class SessionsPage extends StatefulWidget {
SessionsPage({Key key}) : super(key: key);
@override
_SessionsPageState createState() => _SessionsPageState();
}
class _SessionsPageState extends State<SessionsPage> {
Sessions _sessions;
@override
void initState() {
_fetchActiveSessions();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("active sessions"),
),
body: _getBody(),
);
}
Widget _getBody() {
if (_sessions == null) {
return Center(child: loadWidget);
}
List<Widget> rows = [];
for (final session in _sessions.sessions) {
rows.add(_getSessionWidget(session));
}
return SingleChildScrollView(
child: Column(
children: rows,
),
);
}
Widget _getSessionWidget(Session session) {
final lastUsedTime =
DateTime.fromMicrosecondsSinceEpoch(session.lastUsedTime);
return Column(
children: [
InkWell(
onTap: () async {
_showSessionTerminationDialog(session);
},
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_getUAWidget(session),
Padding(padding: EdgeInsets.all(4)),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Text(
session.ip,
style: TextStyle(
color: Colors.white.withOpacity(0.8),
fontSize: 14,
),
),
),
Padding(padding: EdgeInsets.all(8)),
Flexible(
child: Text(
getFormattedTime(lastUsedTime),
style: TextStyle(
color: Colors.white.withOpacity(0.8),
fontSize: 12,
),
),
),
],
),
],
),
),
),
Divider(),
],
);
}
Future<void> _terminateSession(Session session) async {
final dialog = createProgressDialog(context, "please wait...");
await dialog.show();
await UserService.instance.terminateSession(session.token);
await _fetchActiveSessions();
await dialog.hide();
}
Future<void> _fetchActiveSessions() async {
_sessions = await UserService.instance
.getActiveSessions()
.onError((error, stackTrace) {
showToast("failed to fetch active sessions");
throw error;
});
_sessions.sessions.sort((first, second) {
return second.lastUsedTime.compareTo(first.lastUsedTime);
});
setState(() {});
}
void _showSessionTerminationDialog(Session session) {
final isLoggingOutFromThisDevice =
session.token == Configuration.instance.getToken();
Widget text;
if (isLoggingOutFromThisDevice) {
text = Text(
"this will log you out of this device!",
);
} else {
text = SingleChildScrollView(
child: Column(
children: [
Text(
"this will log you out of the following device:",
),
Padding(padding: EdgeInsets.all(8)),
Text(
session.ua,
style: TextStyle(
color: Colors.white.withOpacity(0.7),
fontSize: 14,
),
),
],
),
);
}
AlertDialog alert = AlertDialog(
title: Text("terminate session?"),
content: text,
actions: [
TextButton(
child: Text(
"terminate",
style: TextStyle(
color: Colors.red,
),
),
onPressed: () async {
Navigator.of(context, rootNavigator: true).pop('dialog');
if (isLoggingOutFromThisDevice) {
await UserService.instance.logout(context);
} else {
_terminateSession(session);
}
},
),
TextButton(
child: Text(
"cancel",
style: TextStyle(
color: isLoggingOutFromThisDevice
? Theme.of(context).buttonColor
: Colors.white,
),
),
onPressed: () {
Navigator.of(context, rootNavigator: true).pop('dialog');
},
),
],
);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
Widget _getUAWidget(Session session) {
if (session.token == Configuration.instance.getToken()) {
return Text(
"this device",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Theme.of(context).buttonColor,
),
);
}
return Text(session.prettyUA);
}
}