Merge pull request 'Fix Debug Errors + Implement Scroll To on DM' (#481) from fix_308 into trunk

Reviewed-on: cwtch.im/cwtch-ui#481
This commit is contained in:
Dan Ballard 2022-06-20 19:10:32 +00:00
commit a83b357f0f
7 changed files with 73 additions and 35 deletions

7
.gitignore vendored
View File

@ -40,10 +40,17 @@ app.*.symbols
# Obfuscation related
app.*.map.json
# Tor
data-dir*
# Compiled Libs
linux/tor
linux/libCwtch.so
android/cwtch/cwtch.aar
android/app/src/main/jniLibs/*/libtor.so
libCwtch.dylib
coverage
test/failures
.gradle

View File

@ -21,7 +21,7 @@ class ContactListState extends ChangeNotifier {
}
List<ContactInfoState> filteredList() {
if (!isFiltered) return contacts;
if (!isFiltered) return _contacts;
return _contacts.where((ContactInfoState c) => c.onion.toLowerCase().startsWith(_filter) || (c.nickname.toLowerCase().contains(_filter))).toList();
}

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:cwtch/models/remoteserver.dart';
import 'package:flutter/widgets.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'contact.dart';
import 'contactlist.dart';
@ -20,7 +21,7 @@ class ProfileInfoState extends ChangeNotifier {
bool _online = false;
Map<String, FileDownloadProgress> _downloads = Map<String, FileDownloadProgress>();
Map<String, int> _downloadTriggers = Map<String, int>();
ItemScrollController contactListScrollController = new ItemScrollController();
// assume profiles are encrypted...this will be set to false
// in the constructor if the profile is encrypted with the defacto password.
bool _encrypted = true;

View File

@ -12,6 +12,7 @@ import 'package:cwtch/widgets/profileimage.dart';
import 'package:cwtch/widgets/textfield.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import '../main.dart';
import '../settings.dart';
import 'addcontactview.dart';
@ -35,6 +36,7 @@ void selectConversation(BuildContext context, int handle) {
Provider.of<ProfileInfoState>(context, listen: false).contactList.getContact(previouslySelected)!.unselected();
}
Provider.of<ProfileInfoState>(context, listen: false).contactList.getContact(handle)!.selected();
// triggers update in Double/TripleColumnView
Provider.of<AppState>(context, listen: false).initialScrollIndex = unread;
Provider.of<AppState>(context, listen: false).selectedConversation = handle;
@ -86,29 +88,35 @@ class _ContactsViewState extends State<ContactsView> {
endDrawerEnableOpenDragGesture: false,
drawerEnableOpenDragGesture: false,
appBar: AppBar(
leading: Row(children: [
IconButton(
icon: Icon(Icons.arrow_back),
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
onPressed: () {
Provider.of<ProfileInfoState>(context, listen: false).recountUnread();
Provider.of<AppState>(context, listen: false).selectedProfile = "";
Navigator.of(context).pop();
},
),
StreamBuilder<bool>(
stream: Provider.of<AppState>(context).getUnreadProfileNotifyStream(),
builder: (BuildContext context, AsyncSnapshot<bool> unreadCountSnapshot) {
int unreadCount = Provider.of<ProfileListState>(context).generateUnreadCount(Provider.of<AppState>(context).selectedProfile ?? "");
leading: Stack(children: [
Align(
alignment: Alignment.center,
child: IconButton(
icon: Icon(Icons.arrow_back),
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
onPressed: () {
Provider.of<ProfileInfoState>(context, listen: false).recountUnread();
Provider.of<AppState>(context, listen: false).selectedProfile = "";
Navigator.of(context).pop();
},
)),
Positioned(
bottom: 5.0,
right: 5.0,
child: StreamBuilder<bool>(
stream: Provider.of<AppState>(context).getUnreadProfileNotifyStream(),
builder: (BuildContext context, AsyncSnapshot<bool> unreadCountSnapshot) {
int unreadCount = Provider.of<ProfileListState>(context).generateUnreadCount(Provider.of<AppState>(context).selectedProfile ?? "");
return Visibility(
visible: unreadCount > 0,
child: CircleAvatar(
radius: 10.0,
backgroundColor: Provider.of<Settings>(context).theme.portraitProfileBadgeColor,
child: Text(unreadCount > 99 ? "99+" : unreadCount.toString(), style: TextStyle(color: Provider.of<Settings>(context).theme.portraitProfileBadgeTextColor, fontSize: 8.0)),
));
}),
return Visibility(
visible: unreadCount > 0,
child: CircleAvatar(
radius: 10.0,
backgroundColor: Provider.of<Settings>(context).theme.portraitProfileBadgeColor,
child: Text(unreadCount > 99 ? "99+" : unreadCount.toString(), style: TextStyle(color: Provider.of<Settings>(context).theme.portraitProfileBadgeTextColor, fontSize: 8.0)),
));
}),
)
]),
title: RepaintBoundary(
child: Row(children: [
@ -207,11 +215,28 @@ class _ContactsViewState extends State<ContactsView> {
);
});
final divided = ListTile.divideTiles(
context: context,
tiles: tiles,
).toList();
return RepaintBoundary(child: ListView(children: divided));
var initialScroll =
Provider.of<ProfileInfoState>(context, listen: false).contactList.filteredList().indexWhere((element) => element.identifier == Provider.of<AppState>(context).selectedConversation);
if (initialScroll < 0) {
initialScroll = 0;
}
var contactList = ScrollablePositionedList.separated(
itemScrollController: Provider.of<ProfileInfoState>(context).contactListScrollController,
itemCount: Provider.of<ContactListState>(context).num,
initialScrollIndex: initialScroll,
shrinkWrap: true,
physics: BouncingScrollPhysics(),
semanticChildCount: Provider.of<ContactListState>(context).num,
itemBuilder: (context, index) {
return tiles.elementAt(index);
},
separatorBuilder: (BuildContext context, int index) {
return Divider(height: 1);
},
);
return RepaintBoundary(child: contactList);
}
void _pushAddContact(bool newGroup) {

View File

@ -144,7 +144,7 @@ class _MessageViewState extends State<MessageView> {
onPressed: () {
Provider.of<AppState>(context, listen: false).initialScrollIndex = 0;
Provider.of<AppState>(context, listen: false).unreadMessagesBelow = false;
Provider.of<ContactInfoState>(context).messageScrollController.scrollTo(index: 0, duration: Duration(milliseconds: 600));
Provider.of<ContactInfoState>(context, listen: false).messageScrollController.scrollTo(index: 0, duration: Duration(milliseconds: 600));
})
: null,
appBar: AppBar(
@ -233,7 +233,7 @@ class _MessageViewState extends State<MessageView> {
ctrlrCompose.value = TextEditingValue(text: messageWithoutNewLine, selection: TextSelection.fromPosition(TextPosition(offset: messageWithoutNewLine.length)));
// Do this after we trim to preserve enter-behaviour...
bool isOffline = Provider.of<ContactInfoState>(context).isOnline() == false;
bool isOffline = Provider.of<ContactInfoState>(context, listen: false).isOnline() == false;
if (isOffline) {
return;
}

View File

@ -12,6 +12,7 @@ import 'package:cwtch/widgets/profileimage.dart';
import 'package:flutter/physics.dart';
import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import '../main.dart';
import '../settings.dart';
@ -274,6 +275,8 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
// Can't happen
} else {
selectConversation(context, id);
var contactIndex = Provider.of<ProfileInfoState>(context, listen: false).contactList.filteredList().indexWhere((element) => element.identifier == id);
Provider.of<ProfileInfoState>(context, listen: false).contactListScrollController.jumpTo(index: contactIndex);
}
}

View File

@ -96,17 +96,19 @@ class QuotedMessageBubbleState extends State<QuotedMessageBubble> {
margin: EdgeInsets.all(5),
padding: EdgeInsets.all(5),
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(),
decoration: BoxDecoration(
color: fromMe ? Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor : Provider.of<Settings>(context).theme.messageFromMeBackgroundColor,
),
height: 75,
color: fromMe ? Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor : Provider.of<Settings>(context).theme.messageFromMeBackgroundColor,
child: Row(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.start, children: [
Padding(padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 10.0), child: Icon(Icons.reply, size: 32, color: qTextColor)),
DefaultTextStyle(
Flexible(
child: DefaultTextStyle(
textWidthBasis: TextWidthBasis.parent,
child: qMessage.getPreviewWidget(context),
style: TextStyle(color: qTextColor),
overflow: TextOverflow.fade,
)
))
]))));
} catch (e) {
print(e);