Compare commits

..

33 commits

Author SHA1 Message Date
c0be7552d5 Gramatical error 2024-10-17 21:25:58 -04:00
0a6473aa83 Update README.md 2024-10-17 21:25:23 -04:00
c02c314725 Update README.md 2024-10-17 21:25:04 -04:00
695a85b20d Update README.md 2024-10-17 21:23:53 -04:00
558a2e0507 Updated due to issue 2024-10-17 20:57:24 -04:00
7bd329ebef Merge pull request 'Release 0.0.3 Main Merge' (#3) from dev into main
Reviewed-on: #3
We need to work on woodpecker
2024-10-17 18:43:25 -04:00
74a6f811e0 Release
Some checks failed
ci/woodpecker/push/workflow Pipeline failed
2024-10-17 18:39:13 -04:00
3dda4297d4 Changed a string
Some checks failed
ci/woodpecker/push/workflow Pipeline failed
2024-10-17 18:22:52 -04:00
1e2731bd5a Icons 2024-10-17 18:14:03 -04:00
9d42581bbf Changed image in readme
Some checks failed
ci/woodpecker/push/workflow Pipeline failed
2024-10-17 17:53:54 -04:00
c3f205ae42 New logo
Some checks failed
ci/woodpecker/push/workflow Pipeline failed
2024-10-17 17:49:33 -04:00
6c27121258 AAA
Some checks failed
ci/woodpecker/push/workflow Pipeline failed
2024-10-14 18:42:18 -04:00
24672ec104 Test 4 2024-10-14 18:41:56 -04:00
6b88d5b409 Test 3 2024-10-14 18:40:52 -04:00
32d06ed3d7 Test 2
All checks were successful
ci/woodpecker/push/workflow Pipeline was successful
2024-10-14 18:39:00 -04:00
731ff7c915 test
Some checks failed
ci/woodpecker/push/workflow Pipeline failed
2024-10-14 18:28:05 -04:00
e5b847002f test
Some checks failed
ci/woodpecker/push/workflow Pipeline failed
2024-10-14 18:27:12 -04:00
cf3c45f222 Again
Some checks failed
ci/woodpecker/push/workflow Pipeline failed
2024-10-14 18:21:31 -04:00
8653092804 Test again
Some checks failed
ci/woodpecker/push/workflow Pipeline failed
2024-10-14 18:20:19 -04:00
dd4a189409 Test
Some checks failed
ci/woodpecker/push/workflow Pipeline failed
2024-10-14 18:18:19 -04:00
ee9bc2aec0 Fixed issue
Some checks failed
ci/woodpecker/push/workflow Pipeline failed
2024-10-14 18:11:37 -04:00
fbdad99200 1st Pipeline test 2024-10-14 18:00:33 -04:00
9fac523327 testing woodpecker 2024-10-14 15:48:43 -04:00
72742d3fe3 Changed it back 2024-10-13 23:57:11 -04:00
0032153056 Changed to testing 2024-10-13 23:54:28 -04:00
69659c5336 Testing 2024-10-11 15:19:07 -04:00
a691f04de6 Chnaged some compile stuff 2024-10-11 15:17:13 -04:00
3c04c7a7f3 Added Icons and removed some details 2024-10-11 14:50:25 -04:00
60e8e428e8 Added an app bar for images 2024-10-11 11:10:34 -04:00
38a277348f Test 2024-10-11 10:12:34 -04:00
8b6f5bc00c Fixed several issues 2024-07-30 14:54:38 -04:00
de0021b144 Merge branch 'dev' of https://git.mrdab.vore.media/ThatOneJackalGuy/OpenContacts into dev 2024-07-25 17:02:59 -04:00
b1fbc4b46d Made some changes 2024-07-25 17:02:29 -04:00
46 changed files with 151 additions and 134 deletions

15
.woodpecker/workflow.yaml Normal file
View file

@ -0,0 +1,15 @@
when:
- event: push
branch: dev
steps:
- name: build
image: instrumentisto/flutter
commands:
- cd OpenContacts
- echo "Starting to build..."
- flutter build --debug
- name: Deploy
image: debian
commands:
- echo "Hello World"

View file

@ -1,14 +1,17 @@
<img src="https://git.mrdab.vore.media/ThatOneJackalGuy/OpenContacts/raw/branch/dev/assets/images/testingIcon512.png" width="200"/> <img src="https://raw.githubusercontent.com/Mrdabup/OpenContacts/refs/heads/dev/assets/images/logo512.png" width="200"/>
## OpenContacts # OpenContacts
A Resonite Contacts App, based on Nutcake's Recon. A Resonite Contacts App, based on Nutcake's Recon.
[Get the latest version of OpenContacts here](https://git.mrdab.vore.media/ThatOneJackalGuy/OpenContacts) [Get the latest version of OpenContacts here](https://git.mrdab.vore.media/ThatOneJackalGuy/OpenContacts/releases)
[Available on github too!](https://github.com/Mrdabup/OpenContacts/releases)
[Get ReCon here](https://github.com/Nutcake/ReCon) [Get ReCon here](https://github.com/Nutcake/ReCon)
# Building
## Building
This is a standard Flutter application, refer to the [Flutter docs](https://docs.flutter.dev/get-started/install) on how to build it. This is a standard Flutter application, refer to the [Flutter docs](https://docs.flutter.dev/get-started/install) on how to build it.
@ -17,7 +20,7 @@ Currently only Android is fully supported.
The app works on other platforms, though not every feature will be functional. The app works on other platforms, though not every feature will be functional.
For example, notifications are currently not supported on non-android builds. For example, notifications are currently not supported on non-android builds.
# Screenshots ### Screenshots
TODO: Screenshots! TODO: Screenshots!
<!--<img src="https://github.com/Nutcake/ReCon/assets/10452593/a46ccf8a-0a9f-4518-98e6-84fad2d7bf26" width=198/> <img src="https://github.com/Nutcake/ReCon/assets/10452593/5d158f58-cd27-4a68-abf3-9068e92b6a82" width=198/> <img src="https://github.com/Nutcake/ReCon/assets/10452593/f2ce95ef-e513-46cb-9654-31e74cdc7c09" width=198/> <img src="https://github.com/Nutcake/ReCon/assets/10452593/58ef5e5e-1b53-4a47-92f8-bcbcba7a1e86" width=198/>--> <!--<img src="https://github.com/Nutcake/ReCon/assets/10452593/a46ccf8a-0a9f-4518-98e6-84fad2d7bf26" width=198/> <img src="https://github.com/Nutcake/ReCon/assets/10452593/5d158f58-cd27-4a68-abf3-9068e92b6a82" width=198/> <img src="https://github.com/Nutcake/ReCon/assets/10452593/f2ce95ef-e513-46cb-9654-31e74cdc7c09" width=198/> <img src="https://github.com/Nutcake/ReCon/assets/10452593/58ef5e5e-1b53-4a47-92f8-bcbcba7a1e86" width=198/>-->

View file

@ -9,7 +9,7 @@
<application <application
android:label="OpenContacts" android:label="OpenContacts"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/launcher_icon">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View file

@ -765,4 +765,4 @@
/* End XCConfigurationList section */ /* End XCConfigurationList section */
}; };
rootObject = 97C146E61CF9000F007C117D /* Project object */; rootObject = 97C146E61CF9000F007C117D /* Project object */;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 991 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -131,6 +131,7 @@ class Session {
enum SessionAccessLevel { enum SessionAccessLevel {
unknown, unknown,
private, private,
lan,
contacts, contacts,
contactsPlus, contactsPlus,
registeredUsers, registeredUsers,
@ -139,6 +140,7 @@ enum SessionAccessLevel {
static const _readableNamesMap = { static const _readableNamesMap = {
SessionAccessLevel.unknown: "Unknown", SessionAccessLevel.unknown: "Unknown",
SessionAccessLevel.private: "Private", SessionAccessLevel.private: "Private",
SessionAccessLevel.lan: "LAN",
SessionAccessLevel.contacts: "Contacts only", SessionAccessLevel.contacts: "Contacts only",
SessionAccessLevel.contactsPlus: "Contacts+", SessionAccessLevel.contactsPlus: "Contacts+",
SessionAccessLevel.registeredUsers: "Registered users", SessionAccessLevel.registeredUsers: "Registered users",

View file

@ -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();
},
);
}
); );
} }
} }

View file

@ -12,7 +12,7 @@ class FriendOnlineStatusIndicator extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final UserStatus userStatus = friend.userStatus; final UserStatus userStatus = friend.userStatus;
final OnlineStatus onlineStatus = userStatus.onlineStatus; final OnlineStatus onlineStatus = userStatus.onlineStatus;
return userStatus.appVersion.contains("recon") && friend.isOnline return userStatus.appVersion.contains("OpenContacts") && friend.isOnline
? SizedBox.square( ? SizedBox.square(
dimension: 10, dimension: 10,
child: Image.asset( child: Image.asset(
@ -29,3 +29,4 @@ class FriendOnlineStatusIndicator extends StatelessWidget {
); );
} }
} }
// TODO: Re-invent the fucking wheel aparently

View file

@ -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>(
@ -84,7 +84,7 @@ class _FriendsListAppBarState extends State<FriendsListAppBar> with AutomaticKee
await itemDef.onTap(); await itemDef.onTap();
}, },
itemBuilder: (BuildContext context) => [ itemBuilder: (BuildContext context) => [
MenuItemDefinition( /*MenuItemDefinition(
name: "Add Users", name: "Add Users",
icon: Icons.person_add, icon: Icons.person_add,
onTap: () async { onTap: () async {
@ -98,7 +98,8 @@ class _FriendsListAppBarState extends State<FriendsListAppBar> with AutomaticKee
), ),
); );
}, },
), ),*/
//TODO: Add users API
MenuItemDefinition( MenuItemDefinition(
name: "My Profile", name: "My Profile",
icon: Icons.person, icon: Icons.person,

View file

@ -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
@ -50,7 +50,7 @@ class _UserListTileState extends State<UserListTile> {
icon: _localAdded ? const Icon(Icons.person_remove) : const Icon(Icons.person_add), icon: _localAdded ? const Icon(Icons.person_remove) : const Icon(Icons.person_add),
style: style, style: style,
onPressed: _loading ? null : () async { onPressed: _loading ? null : () async {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Sorry, this feature is not yet available"))); ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Sorry, this feature is unavailable.")));
return; return;
setState(() { setState(() {
_loading = true; _loading = true;

View file

@ -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),

View file

@ -192,12 +192,18 @@ class _InventoryBrowserState extends State<InventoryBrowser> with AutomaticKeepA
: () async { : () async {
await Navigator.push( await Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => PhotoView( builder: (context) => Scaffold(
minScale: PhotoViewComputedScale.contained, appBar: AppBar(
imageProvider: title: Text(record.formattedName.toString()),
CachedNetworkImageProvider(Aux.resdbToHttp(record.thumbnailUri)), ),
heroAttributes: PhotoViewHeroAttributes(tag: record.id), body: Center (
child: CachedNetworkImage(
imageUrl: (Aux.resdbToHttp(record.thumbnailUri)),
placeholder: (context, url) => const CircularProgressIndicator(),
errorWidget: (context, url, error) => const Icon(Icons.error),
),
),
), ),
), ),
); );

View file

@ -27,7 +27,6 @@ class _LoginScreenState extends State<LoginScreen> {
late final FocusNode _totpFocusNode; late final FocusNode _totpFocusNode;
bool _isLoading = false; bool _isLoading = false;
bool _isEmailResetSend = false;
String _error = ""; String _error = "";
bool _needsTotp = false; bool _needsTotp = false;
@ -47,13 +46,6 @@ class _LoginScreenState extends State<LoginScreen> {
_totpFocusNode.dispose(); _totpFocusNode.dispose();
super.dispose(); super.dispose();
} }
RegExp emailReg = RegExp(
r"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$",
caseSensitive: false,
multiLine: false,
);
Future<void> submit() async { Future<void> submit() async {
if (_usernameController.text.isEmpty || _passwordController.text.isEmpty) { if (_usernameController.text.isEmpty || _passwordController.text.isEmpty) {
@ -111,69 +103,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 +227,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,

View file

@ -6,6 +6,7 @@ import 'package:OpenContacts/client_holder.dart';
import 'package:OpenContacts/models/personal_profile.dart'; import 'package:OpenContacts/models/personal_profile.dart';
import 'package:OpenContacts/widgets/default_error_widget.dart'; import 'package:OpenContacts/widgets/default_error_widget.dart';
import 'package:OpenContacts/widgets/generic_avatar.dart'; import 'package:OpenContacts/widgets/generic_avatar.dart';
import 'package:OpenContacts/models/users/friend.dart';
class MyProfileDialog extends StatefulWidget { class MyProfileDialog extends StatefulWidget {
const MyProfileDialog({super.key}); const MyProfileDialog({super.key});
@ -30,7 +31,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;

View file

@ -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
@ -53,7 +59,7 @@ class _SessionListState extends State<SessionList> with AutomaticKeepAliveClient
? const DefaultErrorWidget( ? const DefaultErrorWidget(
title: "No Sessions Found", title: "No Sessions Found",
message: "Try to adjust your filters", message: "Try to adjust your filters",
iconOverride: Icons.public_off, iconOverride: Icons.question_mark,
) )
: Padding( : Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0), padding: const EdgeInsets.symmetric(horizontal: 8.0),
@ -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) {
@ -126,7 +132,24 @@ class _SessionListState extends State<SessionList> with AutomaticKeepAliveClient
], ],
), ),
const SizedBox( const SizedBox(
height: 4, height: 2,
),
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: 2,
), ),
Row( Row(
children: [ children: [

View file

@ -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;
@ -159,22 +159,6 @@ class _SessionViewState extends State<SessionView> {
], ],
), ),
), ),
Padding(
padding: const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Headless: ",
style: Theme.of(context).textTheme.labelLarge,
),
Text(
session.headlessHost ? "Yes" : "No",
style: Theme.of(context).textTheme.labelMedium,
),
],
),
),
ListSectionHeader( ListSectionHeader(
leadingText: "Users", leadingText: "Users",
trailingText: trailingText:
@ -188,6 +172,11 @@ class _SessionViewState extends State<SessionView> {
session.sessionUsers session.sessionUsers
.map((user) => ListTile( .map((user) => ListTile(
dense: true, dense: true,
leading: user.username == session.hostUsername && session.headlessHost
? const Icon(Icons.dns, color: Color(0xFF294D5C))
: user.username == session.hostUsername && !session.headlessHost
? const Icon(Icons.star, color: Color(0xFFE69E50))
: const Icon(Icons.person),
title: Text( title: Text(
user.username, user.username,
textAlign: TextAlign.start, textAlign: TextAlign.start,
@ -195,6 +184,9 @@ class _SessionViewState extends State<SessionView> {
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(),

View file

@ -38,7 +38,7 @@ class UpdateNotifier extends StatelessWidget {
children: [ children: [
TextButton.icon( TextButton.icon(
onPressed: () { onPressed: () {
launchUrl(Uri.parse("https://github.com/Nutcake/recon/releases/latest"), launchUrl(Uri.parse("https://git.mrdab.vore.media/ThatOneJackalGuy/OpenContacts/releases/latest"),
mode: LaunchMode.externalApplication, mode: LaunchMode.externalApplication,
); );
}, },

View file

@ -4,7 +4,7 @@ project(runner LANGUAGES CXX)
# The name of the executable created for the application. Change this to change # The name of the executable created for the application. Change this to change
# the on-disk name of your application. # the on-disk name of your application.
set(BINARY_NAME "recon") set(BINARY_NAME "OpenContacts")
# The unique GTK application identifier for this application. See: # The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID # https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "de.tojcklguy.opencontacts") set(APPLICATION_ID "de.tojcklguy.opencontacts")

View file

@ -40,11 +40,11 @@ static void my_application_activate(GApplication* application) {
if (use_header_bar) { if (use_header_bar) {
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar)); gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, "recon"); gtk_header_bar_set_title(header_bar, "OpenContacts");
gtk_header_bar_set_show_close_button(header_bar, TRUE); gtk_header_bar_set_show_close_button(header_bar, TRUE);
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
} else { } else {
gtk_window_set_title(window, "recon"); gtk_window_set_title(window, "OpenContacts");
} }
gtk_window_set_default_size(window, 480, 900); gtk_window_set_default_size(window, 480, 900);

View file

@ -1,6 +1,14 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
archive:
dependency: transitive
description:
name: archive
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
url: "https://pub.dev"
source: hosted
version: "3.6.1"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -278,6 +286,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.1.1" version: "0.1.1"
flutter_launcher_icons:
dependency: "direct dev"
description:
name: flutter_launcher_icons
sha256: "559c600f056e7c704bd843723c21e01b5fba47e8824bd02422165bcc02a5de1d"
url: "https://pub.dev"
source: hosted
version: "0.9.3"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -424,6 +440,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.2" version: "4.0.2"
image:
dependency: transitive
description:
name: image
sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6"
url: "https://pub.dev"
source: hosted
version: "3.3.0"
image_picker: image_picker:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1093,6 +1117,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.0" version: "6.3.0"
yaml:
dependency: transitive
description:
name: yaml
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
sdks: sdks:
dart: ">=3.3.0 <4.0.0" dart: ">=3.3.0 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54" flutter: ">=3.18.0-18.0.pre.54"

View file

@ -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.3
environment: environment:
sdk: ">=3.0.1" sdk: ">=3.0.1"
@ -69,6 +69,7 @@ dependencies:
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_launcher_icons: "^0.9.2"
# The "flutter_lints" package below contains a set of recommended lints to # The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is # encourage good coding practices. The lint set provided by the package is
@ -91,6 +92,7 @@ flutter:
assets: assets:
- assets/images/ - assets/images/
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware # https://flutter.dev/assets-and-images/#resolution-aware
@ -116,3 +118,7 @@ flutter:
# #
# For details regarding fonts from package dependencies, # For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages # see https://flutter.dev/custom-fonts/#from-packages
flutter_icons:
android: "launcher_icon"
ios: true
image_path: "assets/images/logo.png"

View file

@ -1,6 +1,6 @@
{ {
"name": "recon", "name": "OpenContacts",
"short_name": "recon", "short_name": "opc",
"start_url": ".", "start_url": ".",
"display": "standalone", "display": "standalone",
"background_color": "#0175C2", "background_color": "#0175C2",

View file

@ -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

View file

@ -27,7 +27,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FlutterWindow window(project); FlutterWindow window(project);
Win32Window::Point origin(10, 10); Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720); Win32Window::Size size(1280, 720);
if (!window.Create(L"recon", origin, size)) { if (!window.Create(L"OpenContacts", origin, size)) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
window.SetQuitOnClose(true); window.SetQuitOnClose(true);