forked from cwtch.im/cwtch-ui
parent
3a34044f8e
commit
c1aee0d128
|
@ -98,7 +98,7 @@ class CwtchFfi implements Cwtch {
|
|||
Map<String, String> envVars = Platform.environment;
|
||||
String cwtchDir = "";
|
||||
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()) {
|
||||
bundledTor = "linux/tor";
|
||||
} 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");
|
||||
} else {
|
||||
var splitPath = path.split(dirname(Platform.script.path));
|
||||
if (splitPath[0] == "/" && splitPath[1] == "Applications"){
|
||||
if (splitPath[0] == "/" && splitPath[1] == "Applications") {
|
||||
var appName = splitPath[2];
|
||||
print("We're running in /Applications in a non standard app name: $appName");
|
||||
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
|
||||
// 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
|
||||
// copy dev profile to release profile
|
||||
// if macOs and release build and no profile and is dev profile
|
||||
// copy dev profile to release profile
|
||||
if (Platform.isMacOS && EnvironmentConfig.BUILD_VER != dev_version) {
|
||||
var devProfileExists = await Directory(path.join(cwtchDir, "dev", "profiles")).exists();
|
||||
var releaseProfileExists = await Directory(path.join(cwtchDir, "profiles")).exists();
|
||||
|
@ -448,7 +448,6 @@ class CwtchFfi implements Cwtch {
|
|||
malloc.free(u2);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
// ignore: non_constant_identifier_names
|
||||
void UpdateMessageFlags(String profile, String handle, int index, int flags) {
|
||||
|
|
|
@ -31,6 +31,7 @@ class AppState extends ChangeNotifier {
|
|||
String? _selectedProfile;
|
||||
String? _selectedConversation;
|
||||
int _initialScrollIndex = 0;
|
||||
int _hoveredIndex = -1;
|
||||
int? _selectedIndex;
|
||||
bool _unreadMessagesBelow = false;
|
||||
|
||||
|
@ -62,6 +63,14 @@ class AppState extends ChangeNotifier {
|
|||
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;
|
||||
set unreadMessagesBelow(bool newVal) {
|
||||
this._unreadMessagesBelow = newVal;
|
||||
|
@ -381,21 +390,18 @@ class ContactInfoState extends ChangeNotifier {
|
|||
String? _server;
|
||||
late bool _archived;
|
||||
|
||||
ContactInfoState(
|
||||
this.profileOnion,
|
||||
this.onion, {
|
||||
nickname = "",
|
||||
isGroup = false,
|
||||
authorization = ContactAuthorization.unknown,
|
||||
status = "",
|
||||
imagePath = "",
|
||||
savePeerHistory = "DeleteHistoryConfirmed",
|
||||
numMessages = 0,
|
||||
numUnread = 0,
|
||||
lastMessageTime,
|
||||
server,
|
||||
archived = false
|
||||
}) {
|
||||
ContactInfoState(this.profileOnion, this.onion,
|
||||
{nickname = "",
|
||||
isGroup = false,
|
||||
authorization = ContactAuthorization.unknown,
|
||||
status = "",
|
||||
imagePath = "",
|
||||
savePeerHistory = "DeleteHistoryConfirmed",
|
||||
numMessages = 0,
|
||||
numUnread = 0,
|
||||
lastMessageTime,
|
||||
server,
|
||||
archived = false}) {
|
||||
this._nickname = nickname;
|
||||
this._isGroup = isGroup;
|
||||
this._authorization = authorization;
|
||||
|
@ -421,8 +427,8 @@ class ContactInfoState extends ChangeNotifier {
|
|||
this._archived = archived;
|
||||
notifyListeners();
|
||||
}
|
||||
bool get isArchived => this._archived;
|
||||
|
||||
bool get isArchived => this._archived;
|
||||
|
||||
set savePeerHistory(String newVal) {
|
||||
this._savePeerHistory = newVal;
|
||||
|
|
|
@ -30,6 +30,7 @@ void selectConversation(BuildContext context, String handle) {
|
|||
Provider.of<AppState>(context, listen: false).initialScrollIndex = initialIndex;
|
||||
Provider.of<AppState>(context, listen: false).selectedConversation = handle;
|
||||
Provider.of<AppState>(context, listen: false).selectedIndex = null;
|
||||
Provider.of<AppState>(context, listen: false).hoveredIndex = -1;
|
||||
// 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);
|
||||
|
|
|
@ -142,7 +142,7 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
|||
subtitle: Text(AppLocalizations.of(context)!.descriptionStreamerMode),
|
||||
value: settings.streamerMode,
|
||||
onChanged: (bool value) {
|
||||
settings.setStreamerMode(value);
|
||||
settings.setStreamerMode(value);
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
|
|
|
@ -162,11 +162,12 @@ class _GroupSettingsViewState extends State<GroupSettingsView> {
|
|||
onPressed: () {
|
||||
showAlertDialog(context);
|
||||
},
|
||||
style: ButtonStyle (
|
||||
backgroundColor: MaterialStateProperty.all(Colors.transparent)
|
||||
),
|
||||
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.transparent)),
|
||||
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),
|
||||
),
|
||||
))
|
||||
])
|
||||
])
|
||||
|
|
|
@ -257,18 +257,27 @@ class _MessageViewState extends State<MessageView> {
|
|||
color: message.getMetadata().senderHandle != Provider.of<AppState>(context).selectedProfile
|
||||
? Provider.of<Settings>(context).theme.messageFromOtherBackgroundColor()
|
||||
: Provider.of<Settings>(context).theme.messageFromMeBackgroundColor(),
|
||||
child: Wrap(runAlignment: WrapAlignment.spaceEvenly, alignment: WrapAlignment.spaceEvenly, runSpacing: 1.0, crossAxisAlignment: WrapCrossAlignment.center, children: [
|
||||
Center(widthFactor: 1, child: Padding(padding: EdgeInsets.all(10.0), child: Icon(Icons.reply, size: 32))),
|
||||
Center(widthFactor: 1.0, child: message.getPreviewWidget(context)),
|
||||
Center(
|
||||
widthFactor: 1.0,
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.highlight_remove),
|
||||
tooltip: AppLocalizations.of(context)!.tooltipRemoveThisQuotedMessage,
|
||||
onPressed: () {
|
||||
Provider.of<AppState>(context, listen: false).selectedIndex = null;
|
||||
},
|
||||
))
|
||||
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Stack(children: [
|
||||
Align(
|
||||
alignment: Alignment.topRight,
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.highlight_remove),
|
||||
tooltip: AppLocalizations.of(context)!.tooltipRemoveThisQuotedMessage,
|
||||
onPressed: () {
|
||||
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 {
|
||||
return MessageLoadingBubble();
|
||||
|
|
|
@ -65,11 +65,12 @@ class _ContactRowState extends State<ContactRow> {
|
|||
child: LinearProgressIndicator(
|
||||
color: Provider.of<Settings>(context).theme.defaultButtonActiveColor(),
|
||||
)),
|
||||
Visibility(
|
||||
visible: !Provider.of<Settings>(context).streamerMode,
|
||||
child: Text(contact.onion,
|
||||
style: TextStyle(color: contact.isBlocked ? Provider.of<Settings>(context).theme.portraitBlockedTextColor() : Provider.of<Settings>(context).theme.mainTextColor())),
|
||||
)],
|
||||
Visibility(
|
||||
visible: !Provider.of<Settings>(context).streamerMode,
|
||||
child: Text(contact.onion,
|
||||
style: TextStyle(color: contact.isBlocked ? Provider.of<Settings>(context).theme.portraitBlockedTextColor() : Provider.of<Settings>(context).theme.mainTextColor())),
|
||||
)
|
||||
],
|
||||
))),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(5.0),
|
||||
|
|
|
@ -56,44 +56,44 @@ class _MessageListState extends State<MessageList> {
|
|||
Text("")),
|
||||
))),
|
||||
Expanded(
|
||||
child: Container(
|
||||
// Only show broken heart is the contact is offline...
|
||||
decoration: BoxDecoration(
|
||||
image: Provider.of<ContactInfoState>(outerContext).isOnline()
|
||||
? null
|
||||
: DecorationImage(
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: Alignment.center,
|
||||
image: AssetImage("assets/core/negative_heart_512px.png"),
|
||||
colorFilter: ColorFilter.mode(Provider.of<Settings>(context).theme.hilightElementTextColor(), BlendMode.srcIn))),
|
||||
// Don't load messages for syncing server...
|
||||
child: loadMessages
|
||||
? ScrollablePositionedList.builder(
|
||||
itemPositionsListener: widget.scrollListener,
|
||||
itemScrollController: widget.scrollController,
|
||||
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) {
|
||||
var profileOnion = Provider.of<ProfileInfoState>(outerContext, listen: false).onion;
|
||||
var contactHandle = Provider.of<ContactInfoState>(outerContext, listen: false).onion;
|
||||
var messageIndex = Provider.of<ContactInfoState>(outerContext).totalMessages - index - 1;
|
||||
child: Container(
|
||||
// Only show broken heart is the contact is offline...
|
||||
decoration: BoxDecoration(
|
||||
image: Provider.of<ContactInfoState>(outerContext).isOnline()
|
||||
? null
|
||||
: DecorationImage(
|
||||
fit: BoxFit.scaleDown,
|
||||
alignment: Alignment.center,
|
||||
image: AssetImage("assets/core/negative_heart_512px.png"),
|
||||
colorFilter: ColorFilter.mode(Provider.of<Settings>(context).theme.hilightElementTextColor(), BlendMode.srcIn))),
|
||||
// Don't load messages for syncing server...
|
||||
child: loadMessages
|
||||
? ScrollablePositionedList.builder(
|
||||
itemPositionsListener: widget.scrollListener,
|
||||
itemScrollController: widget.scrollController,
|
||||
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) {
|
||||
var profileOnion = Provider.of<ProfileInfoState>(outerContext, listen: false).onion;
|
||||
var contactHandle = Provider.of<ContactInfoState>(outerContext, listen: false).onion;
|
||||
var messageIndex = Provider.of<ContactInfoState>(outerContext).totalMessages - index - 1;
|
||||
|
||||
return FutureBuilder(
|
||||
future: messageHandler(outerContext, profileOnion, contactHandle, messageIndex),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
var message = snapshot.data as Message;
|
||||
// Already includes MessageRow,,
|
||||
return message.getWidget(context);
|
||||
} else {
|
||||
return MessageLoadingBubble();
|
||||
}
|
||||
},
|
||||
);
|
||||
return FutureBuilder(
|
||||
future: messageHandler(outerContext, profileOnion, contactHandle, messageIndex),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) {
|
||||
var message = snapshot.data as Message;
|
||||
// Already includes MessageRow,,
|
||||
return message.getWidget(context);
|
||||
} else {
|
||||
return MessageLoadingBubble();
|
||||
}
|
||||
},
|
||||
)
|
||||
: null))
|
||||
);
|
||||
},
|
||||
)
|
||||
: null))
|
||||
])));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ class MessageRow extends StatefulWidget {
|
|||
}
|
||||
|
||||
class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMixin {
|
||||
bool showMenu = false;
|
||||
bool showBlockedMessage = false;
|
||||
late AnimationController _controller;
|
||||
late Animation<Alignment> _animation;
|
||||
|
@ -70,7 +69,7 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
|
|||
}
|
||||
|
||||
Widget wdgIcons = Visibility(
|
||||
visible: this.showMenu,
|
||||
visible: Provider.of<AppState>(context).hoveredIndex == Provider.of<MessageMetadata>(context).messageIndex,
|
||||
maintainSize: true,
|
||||
maintainAnimation: true,
|
||||
maintainState: true,
|
||||
|
@ -164,12 +163,12 @@ class MessageRowState extends State<MessageRow> with SingleTickerProviderStateMi
|
|||
// For desktop...
|
||||
onHover: (event) {
|
||||
setState(() {
|
||||
this.showMenu = true;
|
||||
Provider.of<AppState>(context, listen: false).hoveredIndex = Provider.of<MessageMetadata>(context).messageIndex;
|
||||
});
|
||||
},
|
||||
onExit: (event) {
|
||||
setState(() {
|
||||
this.showMenu = false;
|
||||
Provider.of<AppState>(context, listen: false).hoveredIndex = -1;
|
||||
});
|
||||
},
|
||||
child: GestureDetector(
|
||||
|
|
|
@ -47,13 +47,13 @@ class _ProfileRowState extends State<ProfileRow> {
|
|||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Visibility(
|
||||
visible: !Provider.of<Settings>(context).streamerMode,
|
||||
visible: !Provider.of<Settings>(context).streamerMode,
|
||||
child: ExcludeSemantics(
|
||||
child: Text(
|
||||
profile.onion,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)))
|
||||
child: Text(
|
||||
profile.onion,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)))
|
||||
],
|
||||
)),
|
||||
IconButton(
|
||||
|
|
Loading…
Reference in New Issue