Merge branch 'trunk' of git.openprivacy.ca:flutter/flutter_app into androidservice

This commit is contained in:
erinn 2021-06-02 13:21:27 -07:00
commit 89507a8aa6
16 changed files with 127 additions and 74 deletions

View File

@ -1 +1 @@
v0.0.2-45-g4f625c7-2021-05-31-23-30
v0.0.2-49-g6a0e839-2021-06-02-19-40

View File

@ -26,6 +26,7 @@ import io.flutter.plugin.common.EventChannel
import kotlin.concurrent.thread
import org.json.JSONObject
import java.io.File
class MainActivity: FlutterActivity() {
@ -60,6 +61,7 @@ class MainActivity: FlutterActivity() {
val ainfo = this.applicationContext.packageManager.getApplicationInfo(
"im.cwtch.flwtch", // Must be app name
PackageManager.GET_SHARED_LIBRARY_FILES)
return ainfo.nativeLibraryDir
}

View File

@ -2,3 +2,4 @@ org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
android.enableR8=true
android.bundle.enableUncompressedNativeLibs=false

View File

@ -82,6 +82,7 @@ class CwtchFfi implements Cwtch {
Map<String, String> envVars = Platform.environment;
if (Platform.isLinux) {
home = (envVars['HOME'])!;
bundledTor = "./tor";
} else if (Platform.isWindows) {
home = (envVars['UserProfile'])!;
bundledTor = "Tor\\Tor\\tor.exe";

View File

@ -456,7 +456,6 @@ class MessageState extends ChangeNotifier {
} else {
var parts = message['d'].toString().split("||");
if (parts.length == 2) {
print("jsondecoding: " + utf8.fuse(base64).decode(parts[1].substring(5)));
var jsonObj = jsonDecode(utf8.fuse(base64).decode(parts[1].substring(5)));
this._inviteTarget = jsonObj['GroupID'];
this._inviteNick = jsonObj['GroupName'];

View File

@ -16,11 +16,10 @@ class NullNotificationsManager implements NotificationsManager {
// the standard dbus-powered linux desktop notifications.
class LinuxNotificationsManager implements NotificationsManager {
int previous_id = 0;
final NotificationsClient client = NotificationsClient();
LinuxNotificationsManager() {}
Future<void> notify(String message) async {
var client = NotificationsClient();
var icon_path = Uri.file(path.join(path.current, "cwtch.png"));
client.notify('New Message from Peer!', appName: "cwtch", appIcon: icon_path.toString(), replacesId: this.previous_id).then((Notification value) => previous_id = value.id);
client.close();
}
}

View File

@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:io';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:cwtch/opaque.dart';
@ -89,7 +90,8 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
Provider.of<FlwtchState>(context).columns = [1];
}
},
items: ["Single", "Double (1:2)", "Double (1:4)"].map<DropdownMenuItem<String>>((String value) {
// TODO: Only allow in landscape?
items: (Platform.isAndroid ? ["Single"] : ["Single", "Double (1:2)", "Double (1:4)"]).map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),

View File

@ -46,11 +46,10 @@ class _MessageViewState extends State<MessageView> {
appBar: AppBar(
title: Text(Provider.of<ContactInfoState>(context).nickname),
actions: [
IconButton(icon: Icon(Icons.chat), onPressed: _pushContactSettings),
IconButton(icon: Icon(Icons.list), onPressed: _pushContactSettings),
IconButton(icon: Icon(Icons.push_pin), onPressed: _pushContactSettings),
IconButton(icon: Icon(Icons.settings), onPressed: _pushContactSettings),
IconButton(icon: Icon(Icons.bug_report_outlined), onPressed: _debugResetContact),
//IconButton(icon: Icon(Icons.chat), onPressed: _pushContactSettings),
//IconButton(icon: Icon(Icons.list), onPressed: _pushContactSettings),
//IconButton(icon: Icon(Icons.push_pin), onPressed: _pushContactSettings),
IconButton(icon: Icon(Icons.settings), tooltip: AppLocalizations.of(context)!.conversationSettings, onPressed: _pushContactSettings),
],
),
body: Padding(padding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 108.0), child: MessageList()),

View File

@ -132,6 +132,6 @@ class _ContactRowState extends State<ContactRow> {
return DateFormat.yMd().format(date.toLocal());
}
// Otherwise just state the time.
return DateFormat.Hms().format(date.toLocal());
return DateFormat.Hm().format(date.toLocal());
}
}

View File

@ -4,7 +4,6 @@ import '../settings.dart';
// Provides a styled Label
// Callers must provide a label text
// TODO: Integrate this with a settings "zoom" / accessibility setting
class CwtchLabel extends StatefulWidget {
CwtchLabel({required this.label});
final String label;

View File

@ -8,6 +8,7 @@ import 'package:intl/intl.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import '../settings.dart';
import 'messagebubbledecorations.dart';
// Like MessageBubble but for displaying chat overlay 100/101 invitations
// Offers the user an accept/reject button if they don't have a matching contact already
@ -52,48 +53,14 @@ class InvitationBubbleState extends State<InvitationBubble> {
style: TextStyle(fontSize: 9.0, color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor() : Provider.of<Settings>(context).theme.messageFromOtherTextColor())));
// todo: translations
var messageStr = "";
if (fromMe) {
//todo: get group name?
messageStr = "You sent an invitation for " + (isGroup ? "a group" : Provider.of<MessageState>(context).message ?? "");
} else {
String joinGroup = AppLocalizations.of(context)!.inviteToGroup;
messageStr = (isGroup ? joinGroup + (Provider.of<MessageState>(context).inviteNick ?? "") : "This is a contact suggestion for:") + "\n" + (Provider.of<MessageState>(context).inviteTarget ?? "");
}
var wdgMessage = Center(
widthFactor: 1,
child: SelectableText(
messageStr + '\u202F',
key: Key(myKey),
focusNode: _focus,
style: TextStyle(
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor() : Provider.of<Settings>(context).theme.messageFromOtherTextColor(),
),
textAlign: TextAlign.left,
textWidthBasis: TextWidthBasis.longestLine,
));
var wdgMessage = fromMe
? senderInviteChrome("You sent an invitation for", isGroup ? "a group" : Provider.of<MessageState>(context).message, myKey)
: inviteChrome(isGroup ? AppLocalizations.of(context)!.inviteToGroup : "This is a contact suggestion for:", Provider.of<MessageState>(context).inviteNick,
Provider.of<MessageState>(context).inviteTarget, myKey);
Widget wdgDecorations;
if (fromMe) {
wdgDecorations = Center(
widthFactor: 1.0,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(prettyDate,
style: TextStyle(fontSize: 9.0, color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor() : Provider.of<Settings>(context).theme.messageFromOtherTextColor()),
textAlign: fromMe ? TextAlign.right : TextAlign.left),
!fromMe
? SizedBox(width: 1, height: 1)
: Padding(
padding: EdgeInsets.all(1.0),
child: Provider.of<MessageState>(context).ackd == true
? Icon(Icons.check_circle_outline, color: Provider.of<Settings>(context).theme.messageFromMeTextColor(), size: 16)
: (Provider.of<MessageState>(context).error == true
? Icon(Icons.error_outline, color: Provider.of<Settings>(context).theme.messageFromMeTextColor(), size: 16)
: Icon(Icons.hourglass_bottom_outlined, color: Provider.of<Settings>(context).theme.messageFromMeTextColor(), size: 16)))
],
));
wdgDecorations = MessageBubbleDecoration(ackd: Provider.of<MessageState>(context).ackd, errored: Provider.of<MessageState>(context).error, fromMe: fromMe, prettyDate: prettyDate);
} else if (isAccepted) {
wdgDecorations = Text("Accepted!");
} else if (this.rejected) {
@ -158,4 +125,58 @@ class InvitationBubbleState extends State<InvitationBubble> {
Provider.of<FlwtchState>(context, listen: false).cwtch.ImportBundle(profileOnion, Provider.of<MessageState>(context, listen: false).message);
}
}
// Construct an invite chrome for the sender
Widget senderInviteChrome(String chrome, String targetName, String myKey) {
return Center(
widthFactor: 1,
child: Row(children: [
SelectableText(
chrome,
key: Key(myKey),
focusNode: _focus,
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromMeTextColor(),
),
textAlign: TextAlign.left,
textWidthBasis: TextWidthBasis.longestLine,
),
SelectableText(
targetName + '\u202F',
key: Key(myKey),
focusNode: _focus,
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromMeTextColor(),
),
textAlign: TextAlign.left,
textWidthBasis: TextWidthBasis.longestLine,
)
]));
}
// Construct an invite chrome
Widget inviteChrome(String chrome, String targetName, String targetId, String myKey) {
return Center(
widthFactor: 1,
child: Row(children: [
SelectableText(
chrome,
key: Key(myKey),
focusNode: _focus,
style: TextStyle(
color: Provider.of<Settings>(context).theme.messageFromOtherTextColor(),
),
textAlign: TextAlign.left,
textWidthBasis: TextWidthBasis.longestLine,
),
SelectableText(
targetName,
key: Key(myKey),
focusNode: _focus,
style: TextStyle(color: Provider.of<Settings>(context).theme.messageFromOtherTextColor()),
textAlign: TextAlign.left,
textWidthBasis: TextWidthBasis.longestLine,
)
]));
}
}

View File

@ -5,6 +5,7 @@ import '../model.dart';
import 'package:intl/intl.dart';
import '../settings.dart';
import 'messagebubbledecorations.dart';
class MessageBubble extends StatefulWidget {
@override
@ -51,28 +52,7 @@ class MessageBubbleState extends State<MessageBubble> {
textWidthBasis: TextWidthBasis.longestLine,
);
var wdgDecorations = Center(
widthFactor: 1.0,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(prettyDate,
style: TextStyle(
fontSize: 9.0,
color: fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor() : Provider.of<Settings>(context).theme.messageFromOtherTextColor(),
),
textAlign: fromMe ? TextAlign.right : TextAlign.left),
!fromMe
? SizedBox(width: 1, height: 1)
: Padding(
padding: EdgeInsets.all(1.0),
child: Provider.of<MessageState>(context).ackd == true
? Icon(Icons.check_circle_outline, color: Provider.of<Settings>(context).theme.messageFromMeTextColor(), size: 16)
: (Provider.of<MessageState>(context).error == true
? Icon(Icons.error_outline, color: Provider.of<Settings>(context).theme.messageFromMeTextColor(), size: 16)
: Icon(Icons.hourglass_bottom_outlined, color: Provider.of<Settings>(context).theme.messageFromMeTextColor(), size: 16)))
],
));
var wdgDecorations = MessageBubbleDecoration(ackd: Provider.of<MessageState>(context).ackd, errored: Provider.of<MessageState>(context).error, fromMe: fromMe, prettyDate: prettyDate);
var error = Provider.of<MessageState>(context).error;

View File

@ -0,0 +1,50 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';
import '../settings.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
// Provides message decorations (acks/errors/dates etc.) for generic message bubble overlays (chats, invites etc.)
class MessageBubbleDecoration extends StatefulWidget {
MessageBubbleDecoration({required this.ackd, required this.errored, required this.prettyDate, required this.fromMe});
final String prettyDate;
final bool fromMe;
final bool ackd;
final bool errored;
@override
_MessageBubbleDecoration createState() => _MessageBubbleDecoration();
}
class _MessageBubbleDecoration extends State<MessageBubbleDecoration> {
@override
Widget build(BuildContext context) {
return Center(
widthFactor: 1.0,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(widget.prettyDate,
style:
TextStyle(fontSize: 9.0, color: widget.fromMe ? Provider.of<Settings>(context).theme.messageFromMeTextColor() : Provider.of<Settings>(context).theme.messageFromOtherTextColor()),
textAlign: widget.fromMe ? TextAlign.right : TextAlign.left),
!widget.fromMe
? SizedBox(width: 1, height: 1)
: Padding(
padding: EdgeInsets.all(1.0),
child: widget.ackd == true
? Tooltip(
message: AppLocalizations.of(context)!.acknowledgedLabel,
child: Icon(Icons.check_circle_outline, color: Provider.of<Settings>(context).theme.messageFromMeTextColor(), size: 16))
: (widget.errored == true
? Tooltip(
message: AppLocalizations.of(context)!.couldNotSendMsgError,
child: Icon(Icons.error_outline, color: Provider.of<Settings>(context).theme.messageFromMeTextColor(), size: 16))
: Tooltip(
message: AppLocalizations.of(context)!.pendingLabel,
child: Icon(Icons.hourglass_bottom_outlined, color: Provider.of<Settings>(context).theme.messageFromMeTextColor(), size: 16))))
],
));
;
}
}

View File

@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
version: 1.0.0+9
environment:
sdk: ">=2.12.0 <3.0.0"