Fix #163
continuous-integration/drone/pr Build is running Details

Also make quoted messages nicer
This commit is contained in:
Sarah Jamie Lewis 2021-09-17 13:38:10 -07:00
parent 3a34044f8e
commit c1aee0d128
10 changed files with 105 additions and 89 deletions

View File

@ -98,7 +98,7 @@ class CwtchFfi implements Cwtch {
Map<String, String> envVars = Platform.environment; Map<String, String> envVars = Platform.environment;
String cwtchDir = ""; String cwtchDir = "";
if (Platform.isLinux) { if (Platform.isLinux) {
cwtchDir = envVars['CWTCH_HOME'] ?? path.join(envVars['HOME']!, ".cwtch"); cwtchDir = envVars['CWTCH_HOME'] ?? path.join(envVars['HOME']!, ".cwtch");
if (await File("linux/tor").exists()) { if (await File("linux/tor").exists()) {
bundledTor = "linux/tor"; bundledTor = "linux/tor";
} else if (await File("lib/tor").exists()) { } else if (await File("lib/tor").exists()) {
@ -126,7 +126,7 @@ class CwtchFfi implements Cwtch {
print("We couldn't find Tor in the Cwtch app directory, however we can fall back to the Tor Browser binary"); print("We couldn't find Tor in the Cwtch app directory, however we can fall back to the Tor Browser binary");
} else { } else {
var splitPath = path.split(dirname(Platform.script.path)); var splitPath = path.split(dirname(Platform.script.path));
if (splitPath[0] == "/" && splitPath[1] == "Applications"){ if (splitPath[0] == "/" && splitPath[1] == "Applications") {
var appName = splitPath[2]; var appName = splitPath[2];
print("We're running in /Applications in a non standard app name: $appName"); print("We're running in /Applications in a non standard app name: $appName");
if (await File("/Applications/$appName/Contents/MacOS/Tor/tor.real").exists()) { if (await File("/Applications/$appName/Contents/MacOS/Tor/tor.real").exists()) {
@ -138,8 +138,8 @@ class CwtchFfi implements Cwtch {
// the first Cwtch MacOS release (1.2) accidently was a dev build // the first Cwtch MacOS release (1.2) accidently was a dev build
// we need to temporarily remedy this for a release or two then delete // we need to temporarily remedy this for a release or two then delete
// if macOs and release build and no profile and is dev profile // if macOs and release build and no profile and is dev profile
// copy dev profile to release profile // copy dev profile to release profile
if (Platform.isMacOS && EnvironmentConfig.BUILD_VER != dev_version) { if (Platform.isMacOS && EnvironmentConfig.BUILD_VER != dev_version) {
var devProfileExists = await Directory(path.join(cwtchDir, "dev", "profiles")).exists(); var devProfileExists = await Directory(path.join(cwtchDir, "dev", "profiles")).exists();
var releaseProfileExists = await Directory(path.join(cwtchDir, "profiles")).exists(); var releaseProfileExists = await Directory(path.join(cwtchDir, "profiles")).exists();
@ -448,7 +448,6 @@ class CwtchFfi implements Cwtch {
malloc.free(u2); malloc.free(u2);
} }
@override @override
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
void UpdateMessageFlags(String profile, String handle, int index, int flags) { void UpdateMessageFlags(String profile, String handle, int index, int flags) {

View File

@ -31,6 +31,7 @@ class AppState extends ChangeNotifier {
String? _selectedProfile; String? _selectedProfile;
String? _selectedConversation; String? _selectedConversation;
int _initialScrollIndex = 0; int _initialScrollIndex = 0;
int _hoveredIndex = -1;
int? _selectedIndex; int? _selectedIndex;
bool _unreadMessagesBelow = false; bool _unreadMessagesBelow = false;
@ -62,6 +63,14 @@ class AppState extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
// Never use this for message lookup - can be a non-indexed value
// e.g. -1
int get hoveredIndex => _hoveredIndex;
set hoveredIndex(int newVal) {
this._hoveredIndex = newVal;
notifyListeners();
}
bool get unreadMessagesBelow => _unreadMessagesBelow; bool get unreadMessagesBelow => _unreadMessagesBelow;
set unreadMessagesBelow(bool newVal) { set unreadMessagesBelow(bool newVal) {
this._unreadMessagesBelow = newVal; this._unreadMessagesBelow = newVal;
@ -381,21 +390,18 @@ class ContactInfoState extends ChangeNotifier {
String? _server; String? _server;
late bool _archived; late bool _archived;
ContactInfoState( ContactInfoState(this.profileOnion, this.onion,
this.profileOnion, {nickname = "",
this.onion, { isGroup = false,
nickname = "", authorization = ContactAuthorization.unknown,
isGroup = false, status = "",
authorization = ContactAuthorization.unknown, imagePath = "",
status = "", savePeerHistory = "DeleteHistoryConfirmed",
imagePath = "", numMessages = 0,
savePeerHistory = "DeleteHistoryConfirmed", numUnread = 0,
numMessages = 0, lastMessageTime,
numUnread = 0, server,
lastMessageTime, archived = false}) {
server,
archived = false
}) {
this._nickname = nickname; this._nickname = nickname;
this._isGroup = isGroup; this._isGroup = isGroup;
this._authorization = authorization; this._authorization = authorization;
@ -421,8 +427,8 @@ class ContactInfoState extends ChangeNotifier {
this._archived = archived; this._archived = archived;
notifyListeners(); notifyListeners();
} }
bool get isArchived => this._archived;
bool get isArchived => this._archived;
set savePeerHistory(String newVal) { set savePeerHistory(String newVal) {
this._savePeerHistory = newVal; this._savePeerHistory = newVal;

View File

@ -30,6 +30,7 @@ void selectConversation(BuildContext context, String handle) {
Provider.of<AppState>(context, listen: false).initialScrollIndex = initialIndex; Provider.of<AppState>(context, listen: false).initialScrollIndex = initialIndex;
Provider.of<AppState>(context, listen: false).selectedConversation = handle; Provider.of<AppState>(context, listen: false).selectedConversation = handle;
Provider.of<AppState>(context, listen: false).selectedIndex = null; Provider.of<AppState>(context, listen: false).selectedIndex = null;
Provider.of<AppState>(context, listen: false).hoveredIndex = -1;
// if in singlepane mode, push to the stack // if in singlepane mode, push to the stack
var isLandscape = Provider.of<AppState>(context, listen: false).isLandscape(context); var isLandscape = Provider.of<AppState>(context, listen: false).isLandscape(context);
if (Provider.of<Settings>(context, listen: false).uiColumns(isLandscape).length == 1) _pushMessageView(context, handle); if (Provider.of<Settings>(context, listen: false).uiColumns(isLandscape).length == 1) _pushMessageView(context, handle);

View File

@ -142,7 +142,7 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
subtitle: Text(AppLocalizations.of(context)!.descriptionStreamerMode), subtitle: Text(AppLocalizations.of(context)!.descriptionStreamerMode),
value: settings.streamerMode, value: settings.streamerMode,
onChanged: (bool value) { onChanged: (bool value) {
settings.setStreamerMode(value); settings.setStreamerMode(value);
// Save Settings... // Save Settings...
saveSettings(context); saveSettings(context);
}, },

View File

@ -162,11 +162,12 @@ class _GroupSettingsViewState extends State<GroupSettingsView> {
onPressed: () { onPressed: () {
showAlertDialog(context); showAlertDialog(context);
}, },
style: ButtonStyle ( style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.transparent)),
backgroundColor: MaterialStateProperty.all(Colors.transparent)
),
icon: Icon(CwtchIcons.leave_group), icon: Icon(CwtchIcons.leave_group),
label: Text(AppLocalizations.of(context)!.leaveGroup, style: TextStyle(decoration: TextDecoration.underline),), label: Text(
AppLocalizations.of(context)!.leaveGroup,
style: TextStyle(decoration: TextDecoration.underline),
),
)) ))
]) ])
]) ])

View File

@ -257,18 +257,27 @@ class _MessageViewState extends State<MessageView> {
color: message.getMetadata().senderHandle != Provider.of<AppState>(context).selectedProfile color: message.getMetadata().senderHandle != Provider.of<AppState>(context).selectedProfile
? Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor() ? Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor()
: Provider.of<Settings>(context).theme.messageFromMeBackgroundColor(), : Provider.of<Settings>(context).theme.messageFromMeBackgroundColor(),
child: Wrap(runAlignment: WrapAlignment.spaceEvenly, alignment: WrapAlignment.spaceEvenly, runSpacing: 1.0, crossAxisAlignment: WrapCrossAlignment.center, children: [ child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Center(widthFactor: 1, child: Padding(padding: EdgeInsets.all(10.0), child: Icon(Icons.reply, size: 32))), Stack(children: [
Center(widthFactor: 1.0, child: message.getPreviewWidget(context)), Align(
Center( alignment: Alignment.topRight,
widthFactor: 1.0, child: IconButton(
child: IconButton( icon: Icon(Icons.highlight_remove),
icon: Icon(Icons.highlight_remove), tooltip: AppLocalizations.of(context)!.tooltipRemoveThisQuotedMessage,
tooltip: AppLocalizations.of(context)!.tooltipRemoveThisQuotedMessage, onPressed: () {
onPressed: () { Provider.of<AppState>(context, listen: false).selectedIndex = null;
Provider.of<AppState>(context, listen: false).selectedIndex = null; },
}, )),
)) Align(
alignment: Alignment.topLeft,
child: Padding(padding: EdgeInsets.all(2.0), child: Icon(Icons.reply)),
)
]),
Wrap(
runAlignment: WrapAlignment.spaceEvenly,
alignment: WrapAlignment.center,
runSpacing: 1.0,
children: [Center(widthFactor: 1.0, child: Padding(padding: EdgeInsets.all(10.0), child: message.getPreviewWidget(context)))]),
])); ]));
} else { } else {
return MessageLoadingBubble(); return MessageLoadingBubble();

View File

@ -65,11 +65,12 @@ class _ContactRowState extends State<ContactRow> {
child: LinearProgressIndicator( child: LinearProgressIndicator(
color: Provider.of<Settings>(context).theme.defaultButtonActiveColor(), color: Provider.of<Settings>(context).theme.defaultButtonActiveColor(),
)), )),
Visibility( Visibility(
visible: !Provider.of<Settings>(context).streamerMode, visible: !Provider.of<Settings>(context).streamerMode,
child: Text(contact.onion, child: Text(contact.onion,
style: TextStyle(color: contact.isBlocked ? Provider.of<Settings>(context).theme.portraitBlockedTextColor() : Provider.of<Settings>(context).theme.mainTextColor())), style: TextStyle(color: contact.isBlocked ? Provider.of<Settings>(context).theme.portraitBlockedTextColor() : Provider.of<Settings>(context).theme.mainTextColor())),
)], )
],
))), ))),
Padding( Padding(
padding: const EdgeInsets.all(5.0), padding: const EdgeInsets.all(5.0),

View File

@ -56,44 +56,44 @@ class _MessageListState extends State<MessageList> {
Text("")), Text("")),
))), ))),
Expanded( Expanded(
child: Container( child: Container(
// Only show broken heart is the contact is offline... // Only show broken heart is the contact is offline...
decoration: BoxDecoration( decoration: BoxDecoration(
image: Provider.of<ContactInfoState>(outerContext).isOnline() image: Provider.of<ContactInfoState>(outerContext).isOnline()
? null ? null
: DecorationImage( : DecorationImage(
fit: BoxFit.scaleDown, fit: BoxFit.scaleDown,
alignment: Alignment.center, alignment: Alignment.center,
image: AssetImage("assets/core/negative_heart_512px.png"), image: AssetImage("assets/core/negative_heart_512px.png"),
colorFilter: ColorFilter.mode(Provider.of<Settings>(context).theme.hilightElementTextColor(), BlendMode.srcIn))), colorFilter: ColorFilter.mode(Provider.of<Settings>(context).theme.hilightElementTextColor(), BlendMode.srcIn))),
// Don't load messages for syncing server... // Don't load messages for syncing server...
child: loadMessages child: loadMessages
? ScrollablePositionedList.builder( ? ScrollablePositionedList.builder(
itemPositionsListener: widget.scrollListener, itemPositionsListener: widget.scrollListener,
itemScrollController: widget.scrollController, itemScrollController: widget.scrollController,
initialScrollIndex: Provider.of<AppState>(outerContext, listen: false).initialScrollIndex, initialScrollIndex: Provider.of<AppState>(outerContext, listen: false).initialScrollIndex,
itemCount: Provider.of<ContactInfoState>(outerContext).totalMessages, 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... 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) { itemBuilder: (itemBuilderContext, index) {
var profileOnion = Provider.of<ProfileInfoState>(outerContext, listen: false).onion; var profileOnion = Provider.of<ProfileInfoState>(outerContext, listen: false).onion;
var contactHandle = Provider.of<ContactInfoState>(outerContext, listen: false).onion; var contactHandle = Provider.of<ContactInfoState>(outerContext, listen: false).onion;
var messageIndex = Provider.of<ContactInfoState>(outerContext).totalMessages - index - 1; var messageIndex = Provider.of<ContactInfoState>(outerContext).totalMessages - index - 1;
return FutureBuilder( return FutureBuilder(
future: messageHandler(outerContext, profileOnion, contactHandle, messageIndex), future: messageHandler(outerContext, profileOnion, contactHandle, messageIndex),
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasData) { if (snapshot.hasData) {
var message = snapshot.data as Message; var message = snapshot.data as Message;
// Already includes MessageRow,, // Already includes MessageRow,,
return message.getWidget(context); return message.getWidget(context);
} else { } else {
return MessageLoadingBubble(); return MessageLoadingBubble();
} }
},
);
}, },
) );
: null)) },
)
: null))
]))); ])));
} }
} }

View File

@ -22,7 +22,6 @@ class MessageRow extends StatefulWidget {
} }
class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMixin { class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMixin {
bool showMenu = false;
bool showBlockedMessage = false; bool showBlockedMessage = false;
late AnimationController _controller; late AnimationController _controller;
late Animation<Alignment> _animation; late Animation<Alignment> _animation;
@ -70,7 +69,7 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
} }
Widget wdgIcons = Visibility( Widget wdgIcons = Visibility(
visible: this.showMenu, visible: Provider.of<AppState>(context).hoveredIndex == Provider.of<MessageMetadata>(context).messageIndex,
maintainSize: true, maintainSize: true,
maintainAnimation: true, maintainAnimation: true,
maintainState: true, maintainState: true,
@ -164,12 +163,12 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
// For desktop... // For desktop...
onHover: (event) { onHover: (event) {
setState(() { setState(() {
this.showMenu = true; Provider.of<AppState>(context, listen: false).hoveredIndex = Provider.of<MessageMetadata>(context).messageIndex;
}); });
}, },
onExit: (event) { onExit: (event) {
setState(() { setState(() {
this.showMenu = false; Provider.of<AppState>(context, listen: false).hoveredIndex = -1;
}); });
}, },
child: GestureDetector( child: GestureDetector(

View File

@ -47,13 +47,13 @@ class _ProfileRowState extends State<ProfileRow> {
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
Visibility( Visibility(
visible: !Provider.of<Settings>(context).streamerMode, visible: !Provider.of<Settings>(context).streamerMode,
child: ExcludeSemantics( child: ExcludeSemantics(
child: Text( child: Text(
profile.onion, profile.onion,
softWrap: true, softWrap: true,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
))) )))
], ],
)), )),
IconButton( IconButton(