updates and cleanup

This commit is contained in:
Christien Rioux 2025-03-17 22:00:26 -04:00
parent 6bd60207d8
commit ef1ded4494
11 changed files with 142 additions and 108 deletions

View File

@ -100,7 +100,8 @@
"yes": "Yes",
"no": "No",
"update": "Update",
"waiting_for_network": "Waiting For Network"
"waiting_for_network": "Waiting For Network",
"chat": "Chat"
},
"toast": {
"error": "Error",
@ -127,7 +128,7 @@
"contacts": "Contacts",
"edit_contact": "Edit Contact",
"invitations": "Invitations",
"no_contact_selected": "Double-click a contact to edit it",
"no_contact_selected": "Select a contact to view or edit",
"new_chat": "Open Chat",
"close_contact": "Close Contact"
},

View File

@ -50,8 +50,11 @@ class ChatComponentCubit extends Cubit<ChatComponentState> {
messageWindow: const AsyncLoading(),
title: '',
)) {
// Immediate Init
_init();
// Async Init
_initWait.add(_init);
_initWait.add(_initAsync);
}
factory ChatComponentCubit.singleContact(
@ -68,7 +71,7 @@ class ChatComponentCubit extends Cubit<ChatComponentState> {
messagesCubit: messagesCubit,
);
Future<void> _init(Completer<void> _cancel) async {
void _init() {
// Get local user info and account record cubit
_localUserIdentityKey = _accountInfo.identityTypedPublicKey;
@ -77,9 +80,6 @@ class ChatComponentCubit extends Cubit<ChatComponentState> {
_accountRecordCubit.stream.listen(_onChangedAccountRecord);
_onChangedAccountRecord(_accountRecordCubit.state);
// Subscribe to remote user info
await _updateConversationSubscriptions();
// Subscribe to messages
_messagesSubscription = _messagesCubit.stream.listen(_onChangedMessages);
_onChangedMessages(_messagesCubit.state);
@ -90,6 +90,11 @@ class ChatComponentCubit extends Cubit<ChatComponentState> {
_onChangedContacts(_contactListCubit.state);
}
Future<void> _initAsync(Completer<void> _cancel) async {
// Subscribe to remote user info
await _updateConversationSubscriptions();
}
@override
Future<void> close() async {
await _initWait();

View File

@ -68,15 +68,27 @@ class ContactItemWidget extends StatelessWidget {
: () => singleFuture<void>((this, _kOnTap), () async {
await _onTap(_contact);
}),
endActions: [
startActions: [
if (_onDoubleTap != null)
SliderTileAction(
//icon: Icons.edit,
label: translate('button.chat'),
actionScale: ScaleKind.secondary,
onPressed: (_context) =>
singleFuture<void>((this, _kOnTap), () async {
await _onDoubleTap(_contact);
}),
),
],
endActions: [
if (_onTap != null)
SliderTileAction(
//icon: Icons.edit,
label: translate('button.edit'),
actionScale: ScaleKind.secondary,
onPressed: (_context) =>
singleFuture<void>((this, _kOnTap), () async {
await _onDoubleTap(_contact);
await _onTap(_contact);
}),
),
if (_onDelete != null)

View File

@ -39,14 +39,14 @@ class ContactsBrowserElement {
class ContactsBrowser extends StatefulWidget {
const ContactsBrowser(
{required this.onContactSelected,
required this.onChatStarted,
required this.onStartChat,
this.selectedContactRecordKey,
super.key});
@override
State<ContactsBrowser> createState() => _ContactsBrowserState();
final Future<void> Function(proto.Contact? contact) onContactSelected;
final Future<void> Function(proto.Contact contact) onChatStarted;
final Future<void> Function(proto.Contact contact) onStartChat;
final TypedKey? selectedContactRecordKey;
@override
@ -60,7 +60,7 @@ class ContactsBrowser extends StatefulWidget {
'onContactSelected', onContactSelected))
..add(
ObjectFlagProperty<Future<void> Function(proto.Contact contact)>.has(
'onChatStarted', onChatStarted));
'onStartChat', onStartChat));
}
}
@ -238,8 +238,8 @@ class _ContactsBrowserState extends State<ContactsBrowser>
selected: widget.selectedContactRecordKey ==
contact.localConversationRecordKey.toVeilid(),
disabled: false,
onDoubleTap: _onTapContact,
onTap: _onStartChat,
onDoubleTap: _onStartChat,
onTap: _onSelectContact,
onDelete: _onDeleteContact)
.paddingLTRB(0, 4, 0, 0);
case ContactsBrowserElementKind.invitation:
@ -293,12 +293,12 @@ class _ContactsBrowserState extends State<ContactsBrowser>
]);
}
Future<void> _onTapContact(proto.Contact contact) async {
Future<void> _onSelectContact(proto.Contact contact) async {
await widget.onContactSelected(contact);
}
Future<void> _onStartChat(proto.Contact contact) async {
await widget.onChatStarted(contact);
await widget.onStartChat(contact);
}
Future<void> _onDeleteContact(proto.Contact contact) async {

View File

@ -135,7 +135,7 @@ class _ContactsDialogState extends State<ContactsDialog> {
?.localConversationRecordKey
.toVeilid(),
onContactSelected: _onContactSelected,
onChatStarted: _onChatStarted,
onStartChat: _onChatStarted,
).paddingLTRB(8, 0, 8, 8)))),
if (enableRight && enableLeft)
Container(

View File

@ -31,34 +31,42 @@ class SettingsPageState extends State<SettingsPage> {
@override
Widget build(BuildContext context) =>
AsyncBlocBuilder<PreferencesCubit, Preferences>(
builder: (context, state) => StyledScaffold(
appBar: DefaultAppBar(
title: Text(translate('settings_page.titlebar')),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => GoRouterHelper(context).pop(),
),
actions: <Widget>[
const SignalStrengthMeterWidget().paddingLTRB(16, 0, 16, 0),
]),
body: ThemeSwitchingArea(
child: FormBuilder(
key: _formKey,
child: ListView(
padding: const EdgeInsets.all(8),
children: [
buildSettingsPageColorPreferences(
builder: (context, state) => ThemeSwitcher.withTheme(
builder: (_, switcher, theme) => StyledScaffold(
appBar: DefaultAppBar(
title: Text(translate('settings_page.titlebar')),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => GoRouterHelper(context).pop(),
),
actions: <Widget>[
const SignalStrengthMeterWidget()
.paddingLTRB(16, 0, 16, 0),
]),
body: ThemeSwitchingArea(
child: FormBuilder(
key: _formKey,
child: ListView(
padding: const EdgeInsets.all(8),
children: [
buildSettingsPageColorPreferences(
context: context,
switcher: switcher,
onChanged: () => setState(() {}))
.paddingLTRB(0, 8, 0, 0),
buildSettingsPageBrightnessPreferences(
context: context,
onChanged: () => setState(() {}))
.paddingLTRB(0, 8, 0, 0),
buildSettingsPageBrightnessPreferences(
context: context, onChanged: () => setState(() {})),
buildSettingsPageWallpaperPreferences(
context: context, onChanged: () => setState(() {})),
buildSettingsPageNotificationPreferences(
context: context, onChanged: () => setState(() {})),
].map((x) => x.paddingLTRB(0, 0, 0, 8)).toList(),
),
).paddingSymmetric(horizontal: 8, vertical: 8),
)));
switcher: switcher,
onChanged: () => setState(() {})),
buildSettingsPageWallpaperPreferences(
context: context,
switcher: switcher,
onChanged: () => setState(() {})),
buildSettingsPageNotificationPreferences(
context: context,
onChanged: () => setState(() {})),
].map((x) => x.paddingLTRB(0, 0, 0, 8)).toList(),
),
).paddingSymmetric(horizontal: 8, vertical: 8),
))));
}

View File

@ -22,24 +22,25 @@ List<DropdownMenuItem<dynamic>> _getBrightnessDropdownItems() {
}
Widget buildSettingsPageBrightnessPreferences(
{required BuildContext context, required void Function() onChanged}) {
{required BuildContext context,
required void Function() onChanged,
required ThemeSwitcherState switcher}) {
final preferencesRepository = PreferencesRepository.instance;
final themePreferences = preferencesRepository.value.themePreference;
return ThemeSwitcher.withTheme(
builder: (_, switcher, theme) => FormBuilderDropdown(
name: formFieldBrightness,
decoration: InputDecoration(
label: Text(translate('settings_page.brightness_mode'))),
items: _getBrightnessDropdownItems(),
initialValue: themePreferences.brightnessPreference,
onChanged: (value) async {
final newThemePrefs = themePreferences.copyWith(
brightnessPreference: value as BrightnessPreference);
final newPrefs = preferencesRepository.value
.copyWith(themePreference: newThemePrefs);
return FormBuilderDropdown(
name: formFieldBrightness,
decoration: InputDecoration(
label: Text(translate('settings_page.brightness_mode'))),
items: _getBrightnessDropdownItems(),
initialValue: themePreferences.brightnessPreference,
onChanged: (value) async {
final newThemePrefs = themePreferences.copyWith(
brightnessPreference: value as BrightnessPreference);
final newPrefs = preferencesRepository.value
.copyWith(themePreference: newThemePrefs);
await preferencesRepository.set(newPrefs);
switcher.changeTheme(theme: newThemePrefs.themeData());
onChanged();
}));
await preferencesRepository.set(newPrefs);
switcher.changeTheme(theme: newThemePrefs.themeData());
onChanged();
});
}

View File

@ -1,4 +1,5 @@
import 'package:animated_theme_switcher/animated_theme_switcher.dart';
import 'package:async_tools/async_tools.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:flutter_translate/flutter_translate.dart';
@ -7,6 +8,7 @@ import '../../settings/settings.dart';
import '../models/models.dart';
const String formFieldTheme = 'theme';
const String _kSwitchTheme = 'switchTheme';
List<DropdownMenuItem<dynamic>> _getThemeDropdownItems() {
const colorPrefs = ColorPreference.values;
@ -32,24 +34,27 @@ List<DropdownMenuItem<dynamic>> _getThemeDropdownItems() {
}
Widget buildSettingsPageColorPreferences(
{required BuildContext context, required void Function() onChanged}) {
{required BuildContext context,
required void Function() onChanged,
required ThemeSwitcherState switcher}) {
final preferencesRepository = PreferencesRepository.instance;
final themePreferences = preferencesRepository.value.themePreference;
return ThemeSwitcher.withTheme(
builder: (_, switcher, theme) => FormBuilderDropdown(
name: formFieldTheme,
decoration: InputDecoration(
label: Text(translate('settings_page.color_theme'))),
items: _getThemeDropdownItems(),
initialValue: themePreferences.colorPreference,
onChanged: (value) async {
final newThemePrefs = themePreferences.copyWith(
colorPreference: value as ColorPreference);
final newPrefs = preferencesRepository.value
.copyWith(themePreference: newThemePrefs);
return FormBuilderDropdown(
name: formFieldTheme,
decoration:
InputDecoration(label: Text(translate('settings_page.color_theme'))),
items: _getThemeDropdownItems(),
initialValue: themePreferences.colorPreference,
onChanged: (value) {
singleFuture(_kSwitchTheme, () async {
final newThemePrefs = themePreferences.copyWith(
colorPreference: value as ColorPreference);
final newPrefs = preferencesRepository.value
.copyWith(themePreference: newThemePrefs);
await preferencesRepository.set(newPrefs);
switcher.changeTheme(theme: newThemePrefs.themeData());
onChanged();
}));
await preferencesRepository.set(newPrefs);
switcher.changeTheme(theme: newThemePrefs.themeData());
onChanged();
});
});
}

View File

@ -9,24 +9,25 @@ import '../models/models.dart';
const String formFieldEnableWallpaper = 'enable_wallpaper';
Widget buildSettingsPageWallpaperPreferences(
{required BuildContext context, required void Function() onChanged}) {
{required BuildContext context,
required void Function() onChanged,
required ThemeSwitcherState switcher}) {
final preferencesRepository = PreferencesRepository.instance;
final themePreferences = preferencesRepository.value.themePreference;
return ThemeSwitcher.withTheme(
builder: (_, switcher, theme) => FormBuilderCheckbox(
name: formFieldEnableWallpaper,
title: Text(translate('settings_page.enable_wallpaper')),
initialValue: themePreferences.enableWallpaper,
onChanged: (value) async {
if (value != null) {
final newThemePrefs =
themePreferences.copyWith(enableWallpaper: value);
final newPrefs = preferencesRepository.value
.copyWith(themePreference: newThemePrefs);
return FormBuilderCheckbox(
name: formFieldEnableWallpaper,
title: Text(translate('settings_page.enable_wallpaper')),
initialValue: themePreferences.enableWallpaper,
onChanged: (value) async {
if (value != null) {
final newThemePrefs =
themePreferences.copyWith(enableWallpaper: value);
final newPrefs = preferencesRepository.value
.copyWith(themePreference: newThemePrefs);
await preferencesRepository.set(newPrefs);
switcher.changeTheme(theme: newThemePrefs.themeData());
onChanged();
}
}));
await preferencesRepository.set(newPrefs);
switcher.changeTheme(theme: newThemePrefs.themeData());
onChanged();
}
});
}

View File

@ -92,10 +92,11 @@ packages:
async_tools:
dependency: "direct main"
description:
path: "../dart_async_tools"
relative: true
source: path
version: "0.1.7"
name: async_tools
sha256: a258558160d6adc18612d0c635ce0d18ceabc022f7933ce78ca4806075d79578
url: "https://pub.dev"
source: hosted
version: "0.1.8"
auto_size_text:
dependency: "direct main"
description:
@ -156,10 +157,10 @@ packages:
dependency: "direct main"
description:
name: bloc_advanced_tools
sha256: d8a680d8a0469456399fb26bae9f7a1d2a1420b5bdf75e204e0fadab9edb0811
sha256: "977f3c7e3f9a19aec2f2c734ae99c8f0799c1b78f9fd7e4dce91a2dbf773e11b"
url: "https://pub.dev"
source: hosted
version: "0.1.8"
version: "0.1.9"
blurry_modal_progress_hud:
dependency: "direct main"
description:

View File

@ -15,13 +15,13 @@ dependencies:
animated_theme_switcher: ^2.0.10
ansicolor: ^2.0.3
archive: ^4.0.4
async_tools: ^0.1.7
async_tools: ^0.1.8
auto_size_text: ^3.0.0
awesome_extensions: ^2.0.21
badges: ^3.1.2
basic_utils: ^5.8.2
bloc: ^8.1.4
bloc_advanced_tools: ^0.1.8
bloc_advanced_tools: ^0.1.9
blurry_modal_progress_hud: ^1.1.1
change_case: ^2.2.0
charcode: ^1.4.0
@ -112,9 +112,9 @@ dependencies:
xterm: ^4.0.0
zxing2: ^0.2.3
dependency_overrides:
async_tools:
path: ../dart_async_tools
#dependency_overrides:
# async_tools:
# path: ../dart_async_tools
# bloc_advanced_tools:
# path: ../bloc_advanced_tools
# searchable_listview: