Fix: #308 - Scroll to Contact

Also fixes a bunch of debug-build issues (overflows / resizes).
This commit is contained in:
Sarah Jamie Lewis 2022-06-20 10:54:06 -07:00
parent 0d90219c87
commit 8570199196
5 changed files with 59 additions and 33 deletions

7
.gitignore vendored
View File

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

View File

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

View File

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

View File

@ -233,7 +233,7 @@ class _MessageViewState extends State<MessageView> {
ctrlrCompose.value = TextEditingValue(text: messageWithoutNewLine, selection: TextSelection.fromPosition(TextPosition(offset: messageWithoutNewLine.length))); ctrlrCompose.value = TextEditingValue(text: messageWithoutNewLine, selection: TextSelection.fromPosition(TextPosition(offset: messageWithoutNewLine.length)));
// Do this after we trim to preserve enter-behaviour... // 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) { if (isOffline) {
return; return;
} }

View File

@ -96,17 +96,19 @@ class QuotedMessageBubbleState extends State<QuotedMessageBubble> {
margin: EdgeInsets.all(5), margin: EdgeInsets.all(5),
padding: EdgeInsets.all(5), padding: EdgeInsets.all(5),
clipBehavior: Clip.antiAlias, clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(), decoration: BoxDecoration(
color: fromMe ? Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor : Provider.of<Settings>(context).theme.messageFromMeBackgroundColor,
),
height: 75, 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: [ 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)), 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, textWidthBasis: TextWidthBasis.parent,
child: qMessage.getPreviewWidget(context), child: qMessage.getPreviewWidget(context),
style: TextStyle(color: qTextColor), style: TextStyle(color: qTextColor),
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
) ))
])))); ]))));
} catch (e) { } catch (e) {
print(e); print(e);