Merge branch 'trunk' of git.openprivacy.ca:flutter/flutter_app into androidservice
This commit is contained in:
commit
89507a8aa6
|
@ -1 +1 @@
|
|||
v0.0.2-45-g4f625c7-2021-05-31-23-30
|
||||
v0.0.2-49-g6a0e839-2021-06-02-19-40
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -2,3 +2,4 @@ org.gradle.jvmargs=-Xmx1536M
|
|||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
android.enableR8=true
|
||||
android.bundle.enableUncompressedNativeLibs=false
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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'];
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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))))
|
||||
],
|
||||
));
|
||||
;
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue