diff --git a/.woodpecker/workflow.yaml b/.woodpecker/workflow.yaml
new file mode 100644
index 0000000..088760e
--- /dev/null
+++ b/.woodpecker/workflow.yaml
@@ -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"
\ No newline at end of file
diff --git a/README.md b/README.md
index 594b1d8..42c9798 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-
+
## OpenContacts
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 363d486..5f9ed7a 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -9,7 +9,7 @@
+ android:icon="@mipmap/launcher_icon">
with AutomaticKee
Widget build(BuildContext context) {
super.build(context);
return AppBar(
- title: const Text("OpenContacts"),
+ title: const Text("Contacts"),
actions: [
Consumer(builder: (context, client, _) {
return PopupMenuButton(
@@ -84,7 +84,7 @@ class _FriendsListAppBarState extends State with AutomaticKee
await itemDef.onTap();
},
itemBuilder: (BuildContext context) => [
- MenuItemDefinition(
+ /*MenuItemDefinition(
name: "Add Users",
icon: Icons.person_add,
onTap: () async {
@@ -98,7 +98,8 @@ class _FriendsListAppBarState extends State with AutomaticKee
),
);
},
- ),
+ ),*/
+ //TODO: Add users API
MenuItemDefinition(
name: "My Profile",
icon: Icons.person,
diff --git a/lib/widgets/friends/user_list_tile.dart b/lib/widgets/friends/user_list_tile.dart
index 2e4f881..cad769a 100644
--- a/lib/widgets/friends/user_list_tile.dart
+++ b/lib/widgets/friends/user_list_tile.dart
@@ -28,13 +28,13 @@ class _UserListTileState extends State {
.of(context)
.colorScheme;
final style = _localAdded ? IconButton.styleFrom(
- foregroundColor: colorScheme.onBackground,
+ foregroundColor: colorScheme.onSurface,
side: BorderSide(
color: colorScheme.error,
width: 2
),
) : IconButton.styleFrom(
- foregroundColor: colorScheme.onBackground,
+ foregroundColor: colorScheme.onSurface,
side: BorderSide(
color: colorScheme.primary,
width: 2
@@ -50,7 +50,7 @@ class _UserListTileState extends State {
icon: _localAdded ? const Icon(Icons.person_remove) : const Icon(Icons.person_add),
style: style,
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;
setState(() {
_loading = true;
diff --git a/lib/widgets/homepage.dart b/lib/widgets/homepage.dart
index 81420cd..4d900d2 100644
--- a/lib/widgets/homepage.dart
+++ b/lib/widgets/homepage.dart
@@ -65,8 +65,8 @@ class _HomeState extends State {
label: "Sessions",
),
NavigationDestination(
- icon: Icon(Icons.message),
- label: "Chat",
+ icon: Icon(Icons.contacts),
+ label: "Contacts",
),
NavigationDestination(
icon: Icon(Icons.inventory),
diff --git a/lib/widgets/inventory/inventory_browser.dart b/lib/widgets/inventory/inventory_browser.dart
index cf05849..13c1bbb 100644
--- a/lib/widgets/inventory/inventory_browser.dart
+++ b/lib/widgets/inventory/inventory_browser.dart
@@ -192,12 +192,18 @@ class _InventoryBrowserState extends State with AutomaticKeepA
: () async {
await Navigator.push(
context,
- MaterialPageRoute(
- builder: (context) => PhotoView(
- minScale: PhotoViewComputedScale.contained,
- imageProvider:
- CachedNetworkImageProvider(Aux.resdbToHttp(record.thumbnailUri)),
- heroAttributes: PhotoViewHeroAttributes(tag: record.id),
+ MaterialPageRoute(
+ builder: (context) => Scaffold(
+ appBar: AppBar(
+ title: Text(record.formattedName.toString()),
+ ),
+ body: Center (
+ child: CachedNetworkImage(
+ imageUrl: (Aux.resdbToHttp(record.thumbnailUri)),
+ placeholder: (context, url) => const CircularProgressIndicator(),
+ errorWidget: (context, url, error) => const Icon(Icons.error),
+ ),
+ ),
),
),
);
diff --git a/lib/widgets/login_screen.dart b/lib/widgets/login_screen.dart
index d6fbd3a..621312a 100644
--- a/lib/widgets/login_screen.dart
+++ b/lib/widgets/login_screen.dart
@@ -27,7 +27,6 @@ class _LoginScreenState extends State {
late final FocusNode _totpFocusNode;
bool _isLoading = false;
- bool _isEmailResetSend = false;
String _error = "";
bool _needsTotp = false;
@@ -47,13 +46,6 @@ class _LoginScreenState extends State {
_totpFocusNode.dispose();
super.dispose();
}
- RegExp emailReg = RegExp(
- r"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$",
-
- caseSensitive: false,
- multiLine: false,
-
- );
Future submit() async {
if (_usernameController.text.isEmpty || _passwordController.text.isEmpty) {
@@ -111,69 +103,7 @@ class _LoginScreenState extends State {
});
}
}
- Future 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 loginSuccessful(AuthenticationData authData) async {
final settingsClient = ClientHolder.of(context).settingsClient;
final notificationManager = FlutterLocalNotificationsPlugin();
@@ -297,16 +227,6 @@ class _LoginScreenState extends State {
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(
child: AnimatedOpacity(
opacity: _errorOpacity,
diff --git a/lib/widgets/my_profile_dialog.dart b/lib/widgets/my_profile_dialog.dart
index db19418..9d79318 100644
--- a/lib/widgets/my_profile_dialog.dart
+++ b/lib/widgets/my_profile_dialog.dart
@@ -6,6 +6,7 @@ import 'package:OpenContacts/client_holder.dart';
import 'package:OpenContacts/models/personal_profile.dart';
import 'package:OpenContacts/widgets/default_error_widget.dart';
import 'package:OpenContacts/widgets/generic_avatar.dart';
+import 'package:OpenContacts/models/users/friend.dart';
class MyProfileDialog extends StatefulWidget {
const MyProfileDialog({super.key});
@@ -30,7 +31,7 @@ class _MyProfileDialogState extends State {
_storageQuotaFuture = UserApi.getStorageQuota(apiClient);
}
}
-
+
@override
Widget build(BuildContext context) {
final tt = Theme.of(context).textTheme;
diff --git a/lib/widgets/sessions/session_list.dart b/lib/widgets/sessions/session_list.dart
index f4a6c1c..7759b30 100644
--- a/lib/widgets/sessions/session_list.dart
+++ b/lib/widgets/sessions/session_list.dart
@@ -7,6 +7,7 @@ import 'package:OpenContacts/widgets/formatted_text.dart';
import 'package:OpenContacts/widgets/sessions/session_view.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
+import 'package:flutter/services.dart';
class SessionList extends StatefulWidget {
const SessionList({super.key});
@@ -14,6 +15,11 @@ class SessionList extends StatefulWidget {
@override
State createState() => _SessionListState();
}
+class onKeyIntent extends Intent{
+ const onKeyIntent();
+}
+
+const onKey = SingleActivator(LogicalKeyboardKey.f5);
class _SessionListState extends State with AutomaticKeepAliveClientMixin {
@override
@@ -53,7 +59,7 @@ class _SessionListState extends State with AutomaticKeepAliveClient
? const DefaultErrorWidget(
title: "No Sessions Found",
message: "Try to adjust your filters",
- iconOverride: Icons.public_off,
+ iconOverride: Icons.question_mark,
)
: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
@@ -63,7 +69,7 @@ class _SessionListState extends State with AutomaticKeepAliveClient
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 256,
crossAxisSpacing: 4,
- mainAxisSpacing: 4,
+ mainAxisSpacing: 1,
childAspectRatio: .8,
),
itemBuilder: (context, index) {
@@ -126,7 +132,24 @@ class _SessionListState extends State with AutomaticKeepAliveClient
],
),
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(
children: [
diff --git a/lib/widgets/sessions/session_view.dart b/lib/widgets/sessions/session_view.dart
index 8f20525..b6a9eae 100644
--- a/lib/widgets/sessions/session_view.dart
+++ b/lib/widgets/sessions/session_view.dart
@@ -1,3 +1,4 @@
+import 'package:OpenContacts/models/users/user.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:OpenContacts/apis/session_api.dart';
import 'package:OpenContacts/auxiliary.dart';
@@ -16,7 +17,6 @@ class SessionView extends StatefulWidget {
@override
State createState() => _SessionViewState();
}
-
class _SessionViewState extends State {
Future? _sessionFuture;
@@ -159,22 +159,6 @@ class _SessionViewState extends State {
],
),
),
- 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(
leadingText: "Users",
trailingText:
@@ -188,6 +172,11 @@ class _SessionViewState extends State {
session.sessionUsers
.map((user) => ListTile(
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(
user.username,
textAlign: TextAlign.start,
@@ -195,6 +184,9 @@ class _SessionViewState extends State {
subtitle: Text(
user.isPresent ? "Active" : "Inactive",
textAlign: TextAlign.start,
+ style: TextStyle(
+ color: user.isPresent ? Color.fromARGB(255, 89, 235, 91) : Color.fromARGB(255, 255, 118, 118),
+ )
),
))
.toList(),
diff --git a/lib/widgets/update_notifier.dart b/lib/widgets/update_notifier.dart
index f07ad32..c0f5fc5 100644
--- a/lib/widgets/update_notifier.dart
+++ b/lib/widgets/update_notifier.dart
@@ -38,7 +38,7 @@ class UpdateNotifier extends StatelessWidget {
children: [
TextButton.icon(
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,
);
},
diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt
index d199e8b..9a7e1a2 100644
--- a/linux/CMakeLists.txt
+++ b/linux/CMakeLists.txt
@@ -4,7 +4,7 @@ project(runner LANGUAGES CXX)
# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
-set(BINARY_NAME "recon")
+set(BINARY_NAME "OpenContacts")
# The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "de.tojcklguy.opencontacts")
diff --git a/linux/my_application.cc b/linux/my_application.cc
index dbd4e93..75d4da3 100644
--- a/linux/my_application.cc
+++ b/linux/my_application.cc
@@ -40,11 +40,11 @@ static void my_application_activate(GApplication* application) {
if (use_header_bar) {
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
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_window_set_titlebar(window, GTK_WIDGET(header_bar));
} else {
- gtk_window_set_title(window, "recon");
+ gtk_window_set_title(window, "OpenContacts");
}
gtk_window_set_default_size(window, 480, 900);
diff --git a/pubspec.lock b/pubspec.lock
index ceb58c1..dd4857d 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1,6 +1,14 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
+ archive:
+ dependency: transitive
+ description:
+ name: archive
+ sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.6.1"
args:
dependency: transitive
description:
@@ -278,6 +286,14 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: "direct dev"
description:
@@ -424,6 +440,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.2"
+ image:
+ dependency: transitive
+ description:
+ name: image
+ sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.3.0"
image_picker:
dependency: "direct main"
description:
@@ -1093,6 +1117,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.3.0"
+ yaml:
+ dependency: transitive
+ description:
+ name: yaml
+ sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.2"
sdks:
dart: ">=3.3.0 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54"
diff --git a/pubspec.yaml b/pubspec.yaml
index e729211..3edfd87 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -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
# 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.
-version: 0.0.1-alpha+2
+version: 0.0.3
environment:
sdk: ">=3.0.1"
@@ -69,6 +69,7 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
+ flutter_launcher_icons: "^0.9.2"
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
@@ -91,6 +92,7 @@ flutter:
assets:
- assets/images/
+
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
@@ -116,3 +118,7 @@ flutter:
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
+flutter_icons:
+ android: "launcher_icon"
+ ios: true
+ image_path: "assets/images/logo.png"
\ No newline at end of file
diff --git a/web/manifest.json b/web/manifest.json
index b2d225b..2a7081d 100644
--- a/web/manifest.json
+++ b/web/manifest.json
@@ -1,6 +1,6 @@
{
- "name": "recon",
- "short_name": "recon",
+ "name": "OpenContacts",
+ "short_name": "opc",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
diff --git a/windows/flutter/CMakeLists.txt b/windows/flutter/CMakeLists.txt
index 930d207..903f489 100644
--- a/windows/flutter/CMakeLists.txt
+++ b/windows/flutter/CMakeLists.txt
@@ -10,6 +10,11 @@ include(${EPHEMERAL_DIR}/generated_config.cmake)
# https://github.com/flutter/flutter/issues/57146.
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 ===
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
@@ -92,7 +97,7 @@ add_custom_command(
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
- windows-x64 $
+ ${FLUTTER_TARGET_PLATFORM} $
VERBATIM
)
add_custom_target(flutter_assemble DEPENDS
diff --git a/windows/runner/main.cpp b/windows/runner/main.cpp
index d97c34f..75a7078 100644
--- a/windows/runner/main.cpp
+++ b/windows/runner/main.cpp
@@ -27,7 +27,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FlutterWindow window(project);
Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720);
- if (!window.Create(L"recon", origin, size)) {
+ if (!window.Create(L"OpenContacts", origin, size)) {
return EXIT_FAILURE;
}
window.SetQuitOnClose(true);