Release 0.0.3 Main Merge #3
11 changed files with 69 additions and 84 deletions
|
@ -10,13 +10,15 @@ import 'package:OpenContacts/widgets/formatted_text.dart';
|
||||||
import 'package:OpenContacts/widgets/friends/friend_online_status_indicator.dart';
|
import 'package:OpenContacts/widgets/friends/friend_online_status_indicator.dart';
|
||||||
import 'package:OpenContacts/widgets/generic_avatar.dart';
|
import 'package:OpenContacts/widgets/generic_avatar.dart';
|
||||||
import 'package:OpenContacts/widgets/messages/messages_list.dart';
|
import 'package:OpenContacts/widgets/messages/messages_list.dart';
|
||||||
|
import 'package:OpenContacts/widgets/my_profile_dialog.dart';
|
||||||
|
|
||||||
class FriendListTile extends StatelessWidget {
|
class FriendListTile extends StatelessWidget {
|
||||||
const FriendListTile({required this.friend, required this.unreads, this.onTap, super.key});
|
const FriendListTile({required this.friend, required this.unreads, this.onTap, super.key, this.onLongPress});
|
||||||
|
|
||||||
final Friend friend;
|
final Friend friend;
|
||||||
final int unreads;
|
final int unreads;
|
||||||
final Function? onTap;
|
final Function? onTap;
|
||||||
|
final Function? onLongPress;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -129,6 +131,14 @@ class FriendListTile extends StatelessWidget {
|
||||||
);
|
);
|
||||||
mClient.selectedFriend = null;
|
mClient.selectedFriend = null;
|
||||||
},
|
},
|
||||||
|
onLongPress: () async {
|
||||||
|
await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return const MyProfileDialog();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ class _FriendsListAppBarState extends State<FriendsListAppBar> with AutomaticKee
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
super.build(context);
|
super.build(context);
|
||||||
return AppBar(
|
return AppBar(
|
||||||
title: const Text("OpenContacts"),
|
title: const Text("Contacts"),
|
||||||
actions: [
|
actions: [
|
||||||
Consumer<MessagingClient>(builder: (context, client, _) {
|
Consumer<MessagingClient>(builder: (context, client, _) {
|
||||||
return PopupMenuButton<OnlineStatus>(
|
return PopupMenuButton<OnlineStatus>(
|
||||||
|
|
|
@ -28,13 +28,13 @@ class _UserListTileState extends State<UserListTile> {
|
||||||
.of(context)
|
.of(context)
|
||||||
.colorScheme;
|
.colorScheme;
|
||||||
final style = _localAdded ? IconButton.styleFrom(
|
final style = _localAdded ? IconButton.styleFrom(
|
||||||
foregroundColor: colorScheme.onBackground,
|
foregroundColor: colorScheme.onSurface,
|
||||||
side: BorderSide(
|
side: BorderSide(
|
||||||
color: colorScheme.error,
|
color: colorScheme.error,
|
||||||
width: 2
|
width: 2
|
||||||
),
|
),
|
||||||
) : IconButton.styleFrom(
|
) : IconButton.styleFrom(
|
||||||
foregroundColor: colorScheme.onBackground,
|
foregroundColor: colorScheme.onSurface,
|
||||||
side: BorderSide(
|
side: BorderSide(
|
||||||
color: colorScheme.primary,
|
color: colorScheme.primary,
|
||||||
width: 2
|
width: 2
|
||||||
|
|
13
lib/widgets/friends/user_profile_dialog.dart
Normal file
13
lib/widgets/friends/user_profile_dialog.dart
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import 'package:OpenContacts/widgets/my_profile_dialog.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:OpenContacts/apis/contact_api.dart';
|
||||||
|
import 'package:OpenContacts/models/users/friend.dart';
|
||||||
|
import 'package:OpenContacts/models/users/online_status.dart';
|
||||||
|
import 'package:OpenContacts/widgets/generic_avatar.dart';
|
||||||
|
import 'package:OpenContacts/widgets/default_error_widget.dart';
|
||||||
|
import 'package:OpenContacts/auxiliary.dart';
|
||||||
|
import 'package:OpenContacts/models/users/user_status.dart';
|
||||||
|
|
||||||
|
// Will do this later
|
||||||
|
|
|
@ -65,8 +65,8 @@ class _HomeState extends State<Home> {
|
||||||
label: "Sessions",
|
label: "Sessions",
|
||||||
),
|
),
|
||||||
NavigationDestination(
|
NavigationDestination(
|
||||||
icon: Icon(Icons.message),
|
icon: Icon(Icons.contacts),
|
||||||
label: "Chat",
|
label: "Contacts",
|
||||||
),
|
),
|
||||||
NavigationDestination(
|
NavigationDestination(
|
||||||
icon: Icon(Icons.inventory),
|
icon: Icon(Icons.inventory),
|
||||||
|
|
|
@ -111,69 +111,7 @@ class _LoginScreenState extends State<LoginScreen> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Future<void> passwordResetSubmit() async {
|
|
||||||
if (_usernameController.text.isEmpty) {
|
|
||||||
setState(() {
|
|
||||||
_error = "Please provide an email on the 'Username' textbox";
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_usernameController.text.contains(emailReg)) {
|
|
||||||
setState(() {
|
|
||||||
_error = "An email to reset your password has been requested to resonite.";
|
|
||||||
_isEmailResetSend = true;
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setState(() {
|
|
||||||
_error = "";
|
|
||||||
_isEmailResetSend = true;
|
|
||||||
});
|
|
||||||
/*try {
|
|
||||||
final authData = await ApiClient.tryLogin(
|
|
||||||
username: _usernameController.text,
|
|
||||||
password: _passwordController.text,
|
|
||||||
oneTimePad: _totpController.text.isEmpty ? null : _totpController.text,
|
|
||||||
);
|
|
||||||
if (!authData.isAuthenticated) {
|
|
||||||
setState(() {
|
|
||||||
_error = "Login unsuccessful: Server sent invalid response.";
|
|
||||||
_isLoading = false;
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setState(() {
|
|
||||||
_error = "";
|
|
||||||
_isLoading = false;
|
|
||||||
});
|
|
||||||
await loginSuccessful(authData);
|
|
||||||
} catch (e, s) {
|
|
||||||
setState(() {
|
|
||||||
if (e == ApiClient.totpKey) {
|
|
||||||
if (_needsTotp == false) {
|
|
||||||
_error = "Please enter your 2FA-Code";
|
|
||||||
_totpFocusNode.requestFocus();
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
|
||||||
_scrollController.animateTo(_scrollController.position.maxScrollExtent,
|
|
||||||
duration: const Duration(milliseconds: 400), curve: Curves.easeOutCirc);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
_error = "The given 2FA code is not valid.";
|
|
||||||
}
|
|
||||||
_needsTotp = true;
|
|
||||||
} else {
|
|
||||||
_error = "Login unsuccessful: $e.";
|
|
||||||
}
|
|
||||||
if (kDebugMode) {
|
|
||||||
FlutterError.reportError(FlutterErrorDetails(
|
|
||||||
exception: e,
|
|
||||||
stack: s,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
_isLoading = false;
|
|
||||||
});
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
Future<void> loginSuccessful(AuthenticationData authData) async {
|
Future<void> loginSuccessful(AuthenticationData authData) async {
|
||||||
final settingsClient = ClientHolder.of(context).settingsClient;
|
final settingsClient = ClientHolder.of(context).settingsClient;
|
||||||
final notificationManager = FlutterLocalNotificationsPlugin();
|
final notificationManager = FlutterLocalNotificationsPlugin();
|
||||||
|
@ -297,16 +235,6 @@ class _LoginScreenState extends State<LoginScreen> {
|
||||||
label: const Text("Login"),
|
label: const Text("Login"),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
/*Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 16),
|
|
||||||
child: _isEmailResetSend
|
|
||||||
? const Center(child: CircularProgressIndicator())
|
|
||||||
: TextButton.icon(
|
|
||||||
onPressed: passwordResetSubmit,
|
|
||||||
icon: const Icon(Icons.refresh),
|
|
||||||
label: const Text("Forgot Password?"),
|
|
||||||
),
|
|
||||||
),*/ // I have to look into this feature and understand how password resseting works
|
|
||||||
Center(
|
Center(
|
||||||
child: AnimatedOpacity(
|
child: AnimatedOpacity(
|
||||||
opacity: _errorOpacity,
|
opacity: _errorOpacity,
|
||||||
|
|
|
@ -30,7 +30,7 @@ class _MyProfileDialogState extends State<MyProfileDialog> {
|
||||||
_storageQuotaFuture = UserApi.getStorageQuota(apiClient);
|
_storageQuotaFuture = UserApi.getStorageQuota(apiClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final tt = Theme.of(context).textTheme;
|
final tt = Theme.of(context).textTheme;
|
||||||
|
|
|
@ -7,6 +7,7 @@ import 'package:OpenContacts/widgets/formatted_text.dart';
|
||||||
import 'package:OpenContacts/widgets/sessions/session_view.dart';
|
import 'package:OpenContacts/widgets/sessions/session_view.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
class SessionList extends StatefulWidget {
|
class SessionList extends StatefulWidget {
|
||||||
const SessionList({super.key});
|
const SessionList({super.key});
|
||||||
|
@ -14,6 +15,11 @@ class SessionList extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
State<SessionList> createState() => _SessionListState();
|
State<SessionList> createState() => _SessionListState();
|
||||||
}
|
}
|
||||||
|
class onKeyIntent extends Intent{
|
||||||
|
const onKeyIntent();
|
||||||
|
}
|
||||||
|
|
||||||
|
const onKey = SingleActivator(LogicalKeyboardKey.f5);
|
||||||
|
|
||||||
class _SessionListState extends State<SessionList> with AutomaticKeepAliveClientMixin {
|
class _SessionListState extends State<SessionList> with AutomaticKeepAliveClientMixin {
|
||||||
@override
|
@override
|
||||||
|
@ -63,7 +69,7 @@ class _SessionListState extends State<SessionList> with AutomaticKeepAliveClient
|
||||||
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
|
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
|
||||||
maxCrossAxisExtent: 256,
|
maxCrossAxisExtent: 256,
|
||||||
crossAxisSpacing: 4,
|
crossAxisSpacing: 4,
|
||||||
mainAxisSpacing: 4,
|
mainAxisSpacing: 1,
|
||||||
childAspectRatio: .8,
|
childAspectRatio: .8,
|
||||||
),
|
),
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
|
@ -128,6 +134,23 @@ class _SessionListState extends State<SessionList> with AutomaticKeepAliveClient
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 4,
|
height: 4,
|
||||||
),
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
"Host: ${session.hostUsername}",
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||||
|
color: Color.fromARGB(234, 151, 107, 61)
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 4,
|
||||||
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:OpenContacts/models/users/user.dart';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:OpenContacts/apis/session_api.dart';
|
import 'package:OpenContacts/apis/session_api.dart';
|
||||||
import 'package:OpenContacts/auxiliary.dart';
|
import 'package:OpenContacts/auxiliary.dart';
|
||||||
|
@ -16,7 +17,6 @@ class SessionView extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
State<SessionView> createState() => _SessionViewState();
|
State<SessionView> createState() => _SessionViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SessionViewState extends State<SessionView> {
|
class _SessionViewState extends State<SessionView> {
|
||||||
Future<Session>? _sessionFuture;
|
Future<Session>? _sessionFuture;
|
||||||
|
|
||||||
|
@ -191,10 +191,16 @@ class _SessionViewState extends State<SessionView> {
|
||||||
title: Text(
|
title: Text(
|
||||||
user.username,
|
user.username,
|
||||||
textAlign: TextAlign.start,
|
textAlign: TextAlign.start,
|
||||||
|
style: TextStyle(
|
||||||
|
color: user.username == session.hostUsername ? Color.fromARGB(255, 230, 158, 80) : Color.fromARGB(255, 209, 209, 209),
|
||||||
|
)
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
user.isPresent ? "Active" : "Inactive",
|
user.isPresent ? "Active" : "Inactive",
|
||||||
textAlign: TextAlign.start,
|
textAlign: TextAlign.start,
|
||||||
|
style: TextStyle(
|
||||||
|
color: user.isPresent ? Color.fromARGB(255, 89, 235, 91) : Color.fromARGB(255, 255, 118, 118),
|
||||||
|
)
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
.toList(),
|
.toList(),
|
||||||
|
|
|
@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 0.0.1-alpha+2
|
version: 0.0.2-indev
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.0.1"
|
sdk: ">=3.0.1"
|
||||||
|
|
|
@ -10,6 +10,11 @@ include(${EPHEMERAL_DIR}/generated_config.cmake)
|
||||||
# https://github.com/flutter/flutter/issues/57146.
|
# https://github.com/flutter/flutter/issues/57146.
|
||||||
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
|
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
|
||||||
|
|
||||||
|
# Set fallback configurations for older versions of the flutter tool.
|
||||||
|
if (NOT DEFINED FLUTTER_TARGET_PLATFORM)
|
||||||
|
set(FLUTTER_TARGET_PLATFORM "windows-x64")
|
||||||
|
endif()
|
||||||
|
|
||||||
# === Flutter Library ===
|
# === Flutter Library ===
|
||||||
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
|
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
|
||||||
|
|
||||||
|
@ -92,7 +97,7 @@ add_custom_command(
|
||||||
COMMAND ${CMAKE_COMMAND} -E env
|
COMMAND ${CMAKE_COMMAND} -E env
|
||||||
${FLUTTER_TOOL_ENVIRONMENT}
|
${FLUTTER_TOOL_ENVIRONMENT}
|
||||||
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
|
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
|
||||||
windows-x64 $<CONFIG>
|
${FLUTTER_TARGET_PLATFORM} $<CONFIG>
|
||||||
VERBATIM
|
VERBATIM
|
||||||
)
|
)
|
||||||
add_custom_target(flutter_assemble DEPENDS
|
add_custom_target(flutter_assemble DEPENDS
|
||||||
|
|
Loading…
Reference in a new issue