Merge branch 'trunk' into nima/clickable-links

This commit is contained in:
Sarah Jamie Lewis 2021-11-11 00:22:53 +00:00
commit 4dea1e1dd4
14 changed files with 83 additions and 21 deletions

View File

@ -133,6 +133,8 @@ class CwtchNotifier {
notificationManager.notify("New Message From Peer!");
if (appState.selectedProfile != data["ProfileOnion"] || appState.selectedConversation != data["RemotePeer"]) {
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.unreadMessages++;
} else {
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.newMarker++;
}
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["RemotePeer"])!.totalMessages++;
profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageTime(data["RemotePeer"], DateTime.now());
@ -181,6 +183,8 @@ class CwtchNotifier {
//if not currently open
if (appState.selectedProfile != data["ProfileOnion"] || appState.selectedConversation != data["GroupID"]) {
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["GroupID"])!.unreadMessages++;
} else {
profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(data["GroupID"])!.newMarker++;
}
var timestampSent = DateTime.tryParse(data['TimestampSent'])!;

View File

@ -1,6 +1,7 @@
{
"@@locale": "de",
"@@last_modified": "2021-11-10T18:47:30+01:00",
"@@last_modified": "2021-11-11T01:02:08+01:00",
"newMessagesLabel": "New Messages",
"localeRU": "Russian",
"copyServerKeys": "Copy keys",
"verfiyResumeButton": "Verify\/resume",

View File

@ -1,6 +1,7 @@
{
"@@locale": "en",
"@@last_modified": "2021-11-10T18:47:30+01:00",
"@@last_modified": "2021-11-11T01:02:08+01:00",
"newMessagesLabel": "New Messages",
"localeRU": "Russian",
"copyServerKeys": "Copy keys",
"verfiyResumeButton": "Verify\/resume",

View File

@ -1,6 +1,7 @@
{
"@@locale": "es",
"@@last_modified": "2021-11-10T18:47:30+01:00",
"@@last_modified": "2021-11-11T01:02:08+01:00",
"newMessagesLabel": "New Messages",
"localeRU": "Russian",
"copyServerKeys": "Copy keys",
"verfiyResumeButton": "Verify\/resume",

View File

@ -1,6 +1,7 @@
{
"@@locale": "fr",
"@@last_modified": "2021-11-10T18:47:30+01:00",
"@@last_modified": "2021-11-11T01:02:08+01:00",
"newMessagesLabel": "New Messages",
"localeRU": "Russian",
"copyServerKeys": "Copier les clés",
"verfiyResumeButton": "Vérifier\/reprendre",

View File

@ -1,6 +1,7 @@
{
"@@locale": "it",
"@@last_modified": "2021-11-10T18:47:30+01:00",
"@@last_modified": "2021-11-11T01:02:08+01:00",
"newMessagesLabel": "New Messages",
"localeRU": "Russian",
"copyServerKeys": "Copy keys",
"verfiyResumeButton": "Verify\/resume",

View File

@ -1,6 +1,7 @@
{
"@@locale": "pl",
"@@last_modified": "2021-11-10T18:47:30+01:00",
"@@last_modified": "2021-11-11T01:02:08+01:00",
"newMessagesLabel": "New Messages",
"localeRU": "Russian",
"copyServerKeys": "Kopiuj klucze",
"verfiyResumeButton": "Zweryfikuj\/wznów",

View File

@ -1,6 +1,7 @@
{
"@@locale": "pt",
"@@last_modified": "2021-11-10T18:47:30+01:00",
"@@last_modified": "2021-11-11T01:02:08+01:00",
"newMessagesLabel": "New Messages",
"localeRU": "Russian",
"copyServerKeys": "Copy keys",
"verfiyResumeButton": "Verify\/resume",

View File

@ -507,6 +507,8 @@ class ContactInfoState extends ChangeNotifier {
late int _totalMessages = 0;
late DateTime _lastMessageTime;
late Map<String, GlobalKey<MessageRowState>> keys;
int _newMarker = 0;
DateTime _newMarkerClearAt = DateTime.now();
// todo: a nicer way to model contacts, groups and other "entities"
late bool _isGroup;
@ -587,10 +589,36 @@ class ContactInfoState extends ChangeNotifier {
int get unreadMessages => this._unreadMessages;
set unreadMessages(int newVal) {
// don't reset newMarker position when unreadMessages is being cleared
if (newVal > 0) {
this._newMarker = newVal;
} else {
this._newMarkerClearAt = DateTime.now().add(const Duration(minutes:2));
}
this._unreadMessages = newVal;
notifyListeners();
}
int get newMarker {
if (DateTime.now().isAfter(this._newMarkerClearAt)) {
// perform heresy
this._newMarker = 0;
// no need to notifyListeners() because presumably this getter is
// being called from a renderer anyway
}
return this._newMarker;
}
// what's a getter that sometimes sets without a setter
// that sometimes doesn't set
set newMarker(int newVal) {
// only unreadMessages++ can set newMarker = 1;
// avoids drawing a marker when the convo is already open
if (newVal > 1) {
this._newMarker = newVal;
notifyListeners();
}
}
int get totalMessages => this._totalMessages;
set totalMessages(int newVal) {
this._totalMessages = newVal;

View File

@ -4,7 +4,6 @@ import 'package:cwtch/views/torstatusview.dart';
import 'package:cwtch/widgets/contactrow.dart';
import 'package:cwtch/widgets/profileimage.dart';
import 'package:cwtch/widgets/textfield.dart';
import 'package:cwtch/widgets/tor_icon.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import '../main.dart';

View File

@ -35,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())),
], child: Container(key: Key(flwtch.selectedConversation??"never_this"), child: MessageView())),
),
],
);

View File

@ -40,15 +40,11 @@ class _MessageViewState extends State<MessageView> {
@override
void initState() {
scrollListener.itemPositions.addListener(() {
if (scrollListener.itemPositions.value.length == 0) {
return;
}
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) && Provider.of<AppState>(context, listen: false).unreadMessagesBelow == true) {
Provider.of<AppState>(context, listen: false).initialScrollIndex = 0;
Provider.of<AppState>(context, listen: false).unreadMessagesBelow = false;
if (scrollListener.itemPositions.value.length != 0 &&
Provider.of<AppState>(context, listen: false).unreadMessagesBelow == true &&
scrollListener.itemPositions.value.any((element) => element.index == 0)) {
Provider.of<AppState>(context, listen: false).initialScrollIndex = 0;
Provider.of<AppState>(context, listen: false).unreadMessagesBelow = false;
}
});
super.initState();
@ -59,7 +55,7 @@ class _MessageViewState extends State<MessageView> {
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) {
if (appState.initialScrollIndex > 4 && appState.unreadMessagesBelow == false) {
WidgetsFlutterBinding.ensureInitialized().addPostFrameCallback((timeStamp) {
appState.unreadMessagesBelow = true;
});
@ -111,6 +107,8 @@ class _MessageViewState extends State<MessageView> {
? FloatingActionButton(
child: Icon(Icons.arrow_downward),
onPressed: () {
Provider.of<AppState>(context, listen: false).initialScrollIndex = 0;
Provider.of<AppState>(context, listen: false).unreadMessagesBelow = false;
scrollController.scrollTo(index: 0, duration: Duration(milliseconds: 600));
})
: null,
@ -216,6 +214,7 @@ class _MessageViewState extends State<MessageView> {
focusNode.requestFocus();
Future.delayed(const Duration(milliseconds: 80), () {
Provider.of<ContactInfoState>(context, listen: false).totalMessages++;
Provider.of<ContactInfoState>(context, listen: false).newMarker++;
// Resort the contact list...
Provider.of<ProfileInfoState>(context, listen: false).contactList.updateLastMessageTime(Provider.of<ContactInfoState>(context, listen: false).onion, DateTime.now());
});

View File

@ -71,7 +71,7 @@ class _MessageListState extends State<MessageList> {
? ScrollablePositionedList.builder(
itemPositionsListener: widget.scrollListener,
itemScrollController: widget.scrollController,
initialScrollIndex: Provider.of<AppState>(outerContext, listen: false).initialScrollIndex,
initialScrollIndex: initi > 4 ? initi - 4 : 0,
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) {

View File

@ -159,7 +159,7 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
];
}
var size = MediaQuery.of(context).size;
return MouseRegion(
var mr = MouseRegion(
// For desktop...
onHover: (event) {
setState(() {
@ -197,6 +197,31 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
mainAxisAlignment: MainAxisAlignment.center,
children: widgetRow,
)))));
var mark = Provider.of<ContactInfoState>(context).newMarker;
if (mark > 0 && mark == Provider.of<ContactInfoState>(context).totalMessages - Provider.of<MessageMetadata>(context).messageIndex) {
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [Align(alignment:Alignment.center ,child:_bubbleNew()), mr]);
} else {
return mr;
}
}
Widget _bubbleNew() {
return Container(
decoration: BoxDecoration(
color: Provider.of<Settings>(context).theme.messageFromMeBackgroundColor(),
border: Border.all(
color: Provider.of<Settings>(context).theme.messageFromMeBackgroundColor(),
width: 1),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8),
topRight: Radius.circular(8),
bottomLeft: Radius.circular(8),
bottomRight: Radius.circular(8),
),
),
child: Padding(
padding: EdgeInsets.all(9.0),
child: Text(AppLocalizations.of(context)!.newMessagesLabel)));
}
void _runAnimation(Offset pixelsPerSecond, Size size) {