unread messages scrollposition: fix dualpane and performance issues #145
|
@ -169,7 +169,7 @@ class FlwtchState extends State<Flwtch> {
|
|||
var args = jsonDecode(call.arguments);
|
||||
var profile = profs.getProfile(args["ProfileOnion"])!;
|
||||
var convo = profile.contactList.getContact(args["Handle"])!;
|
||||
var initialIndex = convo.unreadMessages;
|
||||
Provider.of<AppState>(navKey.currentContext!, listen: false).initialScrollIndex = convo.unreadMessages;
|
||||
convo.unreadMessages = 0;
|
||||
|
||||
// single pane mode pushes; double pane mode reads AppState.selectedProfile/Conversation
|
||||
|
@ -187,7 +187,7 @@ class FlwtchState extends State<Flwtch> {
|
|||
ChangeNotifierProvider.value(value: profile),
|
||||
ChangeNotifierProvider.value(value: convo),
|
||||
],
|
||||
builder: (context, child) => MessageView(initialIndex),
|
||||
builder: (context, child) => MessageView(),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
|
@ -30,6 +30,7 @@ class AppState extends ChangeNotifier {
|
|||
String appError = "";
|
||||
String? _selectedProfile;
|
||||
String? _selectedConversation;
|
||||
int _initialScrollIndex = 0;
|
||||
int? _selectedIndex;
|
||||
bool _unreadMessagesBelow = false;
|
||||
|
||||
|
@ -67,6 +68,12 @@ class AppState extends ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
int get initialScrollIndex => _initialScrollIndex;
|
||||
set initialScrollIndex(int newVal) {
|
||||
this._initialScrollIndex = newVal;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool isLandscape(BuildContext c) => MediaQuery.of(c).size.width > MediaQuery.of(c).size.height;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,18 +23,19 @@ class ContactsView extends StatefulWidget {
|
|||
|
||||
// selectConversation can be called from anywhere to set the active conversation
|
||||
void selectConversation(BuildContext context, String handle) {
|
||||
var initialIndex = Provider.of<ProfileInfoState>(context, listen: false).contactList.getContact(handle)!.unreadMessages;
|
||||
// requery instead of using contactinfostate directly because sometimes listview gets confused about data that resorts
|
||||
var initialIndex = Provider.of<ProfileInfoState>(context, listen: false).contactList.getContact(handle)!.unreadMessages;
|
||||
Provider.of<ProfileInfoState>(context, listen: false).contactList.getContact(handle)!.unreadMessages = 0;
|
||||
// triggers update in Double/TripleColumnView
|
||||
Provider.of<AppState>(context, listen: false).initialScrollIndex = initialIndex;
|
||||
Provider.of<AppState>(context, listen: false).selectedConversation = handle;
|
||||
Provider.of<AppState>(context, listen: false).selectedIndex = null;
|
||||
// if in singlepane mode, push to the stack
|
||||
var isLandscape = Provider.of<AppState>(context, listen: false).isLandscape(context);
|
||||
if (Provider.of<Settings>(context, listen: false).uiColumns(isLandscape).length == 1) _pushMessageView(context, handle, initialIndex);
|
||||
if (Provider.of<Settings>(context, listen: false).uiColumns(isLandscape).length == 1) _pushMessageView(context, handle);
|
||||
}
|
||||
|
||||
void _pushMessageView(BuildContext context, String handle, int initialIndex) {
|
||||
void _pushMessageView(BuildContext context, String handle) {
|
||||
var profileOnion = Provider.of<ProfileInfoState>(context, listen: false).onion;
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
|
@ -47,7 +48,7 @@ void _pushMessageView(BuildContext context, String handle, int initialIndex) {
|
|||
ChangeNotifierProvider.value(value: profile),
|
||||
ChangeNotifierProvider.value(value: profile.contactList.getContact(handle)!),
|
||||
],
|
||||
builder: (context, child) => MessageView(initialIndex),
|
||||
builder: (context, child) => MessageView(),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
|
@ -17,7 +17,6 @@ class _DoubleColumnViewState extends State<DoubleColumnView> {
|
|||
Widget build(BuildContext context) {
|
||||
var flwtch = Provider.of<AppState>(context);
|
||||
var cols = Provider.of<Settings>(context).uiColumns(true);
|
||||
var initialIndex = flwtch.selectedConversation == null ? 0 : Provider.of<ProfileInfoState>(context, listen: false).contactList.getContact(flwtch.selectedConversation!)!.unreadMessages;
|
||||
return Flex(
|
||||
direction: Axis.horizontal,
|
||||
children: <Widget>[
|
||||
|
@ -36,7 +35,7 @@ class _DoubleColumnViewState extends State<DoubleColumnView> {
|
|||
ChangeNotifierProvider.value(value: Provider.of<ProfileInfoState>(context)),
|
||||
ChangeNotifierProvider.value(
|
||||
value: flwtch.selectedConversation != null ? Provider.of<ProfileInfoState>(context).contactList.getContact(flwtch.selectedConversation!)! : ContactInfoState("", "")),
|
||||
], child: Container(child: MessageView(initialIndex))),
|
||||
], child: Container(child: MessageView())),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
|
@ -22,9 +22,6 @@ import '../widgets/messagelist.dart';
|
|||
import 'groupsettingsview.dart';
|
||||
|
||||
class MessageView extends StatefulWidget {
|
||||
int initialIndex;
|
||||
MessageView(this.initialIndex);
|
||||
|
||||
@override
|
||||
_MessageViewState createState() => _MessageViewState();
|
||||
}
|
||||
|
@ -38,24 +35,31 @@ class _MessageViewState extends State<MessageView> {
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
// using "8" because "# of messages that fit on one screen" isnt trivial to calculate at this point
|
||||
if (widget.initialIndex > 8) {
|
||||
WidgetsFlutterBinding.ensureInitialized().addPostFrameCallback((timeStamp) {
|
||||
Provider.of<AppState>(context, listen: false).unreadMessagesBelow = true;
|
||||
});
|
||||
}
|
||||
|
||||
scrollListener.itemPositions.addListener(() {
|
||||
var first = scrollListener.itemPositions.value.first.index;
|
||||
var last = scrollListener.itemPositions.value.last.index;
|
||||
// sometimes these go hi->lo and sometimes they go lo->hi because [who tf knows]
|
||||
if (first == 0 || last == 0) {
|
||||
if ((first == 0 || last == 0) && Provider.of<AppState>(context, listen: false).unreadMessagesBelow == true) {
|
||||
Provider.of<AppState>(context, listen: false).initialScrollIndex = 0;
|
||||
Provider.of<AppState>(context, listen: false).unreadMessagesBelow = false;
|
||||
}
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
var appState = Provider.of<AppState>(context, listen: false);
|
||||
|
||||
// using "8" because "# of messages that fit on one screen" isnt trivial to calculate at this point
|
||||
if (appState.initialScrollIndex > 8 && appState.unreadMessagesBelow == false) {
|
||||
WidgetsFlutterBinding.ensureInitialized().addPostFrameCallback((timeStamp) {
|
||||
appState.unreadMessagesBelow = true;
|
||||
});
|
||||
}
|
||||
super.didChangeDependencies();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
focusNode.dispose();
|
||||
|
@ -107,7 +111,7 @@ class _MessageViewState extends State<MessageView> {
|
|||
onPressed: _pushContactSettings),
|
||||
],
|
||||
),
|
||||
body: Padding(padding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 108.0), child: MessageList(widget.initialIndex, scrollController, scrollListener)),
|
||||
body: Padding(padding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 108.0), child: MessageList(scrollController, scrollListener)),
|
||||
bottomSheet: _buildComposeBox(),
|
||||
));
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class _TripleColumnViewState extends State<TripleColumnView> {
|
|||
child: appState.selectedConversation == null
|
||||
? Center(child: Text(AppLocalizations.of(context)!.addContactFirst))
|
||||
: //dev
|
||||
Container(child: MessageView(0/*todo:setme*/)),
|
||||
Container(child: MessageView()),
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -9,10 +9,9 @@ import '../model.dart';
|
|||
import '../settings.dart';
|
||||
|
||||
class MessageList extends StatefulWidget {
|
||||
int initialIndex;
|
||||
ItemScrollController scrollController;
|
||||
ItemPositionsListener scrollListener;
|
||||
MessageList(this.initialIndex, this.scrollController, this.scrollListener);
|
||||
MessageList(this.scrollController, this.scrollListener);
|
||||
|
||||
@override
|
||||
_MessageListState createState() => _MessageListState();
|
||||
|
@ -21,6 +20,7 @@ class MessageList extends StatefulWidget {
|
|||
class _MessageListState extends State<MessageList> {
|
||||
@override
|
||||
Widget build(BuildContext outerContext) {
|
||||
var initi = Provider.of<AppState>(outerContext, listen: false).initialScrollIndex;
|
||||
bool isP2P = !Provider.of<ContactInfoState>(context).isGroup;
|
||||
bool isGroupAndSyncing = Provider.of<ContactInfoState>(context).isGroup == true && Provider.of<ContactInfoState>(context).status == "Authenticated";
|
||||
bool isGroupAndSynced = Provider.of<ContactInfoState>(context).isGroup && Provider.of<ContactInfoState>(context).status == "Synced";
|
||||
|
@ -72,7 +72,7 @@ class _MessageListState extends State<MessageList> {
|
|||
? ScrollablePositionedList.builder(
|
||||
itemPositionsListener: widget.scrollListener,
|
||||
itemScrollController: widget.scrollController,
|
||||
initialScrollIndex: widget.initialIndex,
|
||||
initialScrollIndex: Provider.of<AppState>(outerContext, listen: false).initialScrollIndex,
|
||||
itemCount: Provider.of<ContactInfoState>(outerContext).totalMessages,
|
||||
reverse: true, // NOTE: There seems to be a bug in flutter that corrects the mouse wheel scroll, but not the drag direction...
|
||||
itemBuilder: (itemBuilderContext, index) {
|
||||
|
|
Loading…
Reference in New Issue