Release 0.0.3 Main Merge #3

Merged
ThatOneJackalGuy merged 27 commits from dev into main 2024-10-17 18:43:25 -04:00
46 changed files with 144 additions and 130 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,4 +1,4 @@
<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

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);