forked from cwtch.im/cwtch-ui
Merge pull request 'notificationSettings' (#354) from notificationSettings into trunk
Reviewed-on: cwtch.im/cwtch-ui#354 Reviewed-by: Sarah Jamie Lewis <sarah@openprivacy.ca>
This commit is contained in:
commit
040ba80480
|
@ -1 +1 @@
|
|||
2022-02-08-16-19-v1.5.4-36-g4467c40
|
||||
2022-02-08-22-37-v1.5.4-41-gd0d5300
|
|
@ -1 +1 @@
|
|||
2022-02-08-21-19-v1.5.4-36-g4467c40
|
||||
2022-02-08-22-37-v1.5.4-41-gd0d5300
|
|
@ -29,6 +29,9 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
|
|||
private var notificationID: MutableMap<String, Int> = mutableMapOf()
|
||||
private var notificationIDnext: Int = 1
|
||||
|
||||
private var notificationSimple: String? = null
|
||||
private var notificationConversationInfo: String? = null
|
||||
|
||||
override suspend fun doWork(): Result {
|
||||
val method = inputData.getString(KEY_METHOD)
|
||||
?: return Result.failure()
|
||||
|
@ -67,36 +70,64 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
|
|||
val data = JSONObject(evt.Data)
|
||||
val handle = if (evt.EventType == "NewMessageFromPeer") data.getString("RemotePeer") else data.getString("GroupID");
|
||||
if (data["RemotePeer"] != data["ProfileOnion"]) {
|
||||
val channelId =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
createMessageNotificationChannel(handle, handle)
|
||||
} else {
|
||||
// If earlier version channel ID is not used
|
||||
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
||||
""
|
||||
val notification = data["notification"]
|
||||
|
||||
if (notification == "SimpleEvent") {
|
||||
val channelId =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
createMessageNotificationChannel("Cwtch", "Cwtch")
|
||||
} else {
|
||||
// If earlier version channel ID is not used
|
||||
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
||||
""
|
||||
}
|
||||
|
||||
val clickIntent = Intent(applicationContext, MainActivity::class.java).also { intent ->
|
||||
intent.action = Intent.ACTION_RUN
|
||||
intent.putExtra("EventType", "NotificationClicked")
|
||||
}
|
||||
|
||||
val loader = FlutterInjector.instance().flutterLoader()
|
||||
val key = loader.getLookupKeyForAsset("assets/" + data.getString("picture"))//"assets/profiles/001-centaur.png")
|
||||
val fh = applicationContext.assets.open(key)
|
||||
val newNotification = NotificationCompat.Builder(applicationContext, channelId)
|
||||
.setContentTitle("Cwtch")
|
||||
.setContentText(notificationSimple ?: "New Message")
|
||||
.setSmallIcon(R.mipmap.knott_transparent)
|
||||
.setContentIntent(PendingIntent.getActivity(applicationContext, 1, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT))
|
||||
.setAutoCancel(true)
|
||||
.build()
|
||||
|
||||
notificationManager.notify(getNotificationID("Cwtch", "Cwtch"), newNotification)
|
||||
} else if (notification == "ContactInfo") {
|
||||
val channelId =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
createMessageNotificationChannel(handle, handle)
|
||||
} else {
|
||||
// If earlier version channel ID is not used
|
||||
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
||||
""
|
||||
}
|
||||
val loader = FlutterInjector.instance().flutterLoader()
|
||||
val key = loader.getLookupKeyForAsset("assets/" + data.getString("Picture"))//"assets/profiles/001-centaur.png")
|
||||
val fh = applicationContext.assets.open(key)
|
||||
|
||||
val clickIntent = Intent(applicationContext, MainActivity::class.java).also { intent ->
|
||||
intent.action = Intent.ACTION_RUN
|
||||
intent.putExtra("EventType", "NotificationClicked")
|
||||
intent.putExtra("ProfileOnion", data.getString("ProfileOnion"))
|
||||
intent.putExtra("Handle", handle)
|
||||
}
|
||||
val clickIntent = Intent(applicationContext, MainActivity::class.java).also { intent ->
|
||||
intent.action = Intent.ACTION_RUN
|
||||
intent.putExtra("EventType", "NotificationClicked")
|
||||
intent.putExtra("ProfileOnion", data.getString("ProfileOnion"))
|
||||
intent.putExtra("Handle", handle)
|
||||
}
|
||||
|
||||
val newNotification = NotificationCompat.Builder(applicationContext, channelId)
|
||||
.setContentTitle(data.getString("Nick"))
|
||||
.setContentText((notificationConversationInfo ?: "New Message From %1").replace("%1", data.getString("Nick")))
|
||||
.setLargeIcon(BitmapFactory.decodeStream(fh))
|
||||
.setSmallIcon(R.mipmap.knott_transparent)
|
||||
.setContentIntent(PendingIntent.getActivity(applicationContext, 1, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT))
|
||||
.setAutoCancel(true)
|
||||
.build()
|
||||
|
||||
notificationManager.notify(getNotificationID(data.getString("ProfileOnion"), handle), newNotification)
|
||||
}
|
||||
|
||||
val newNotification = NotificationCompat.Builder(applicationContext, channelId)
|
||||
.setContentTitle(data.getString("Nick"))
|
||||
.setContentText("New message")//todo: translate
|
||||
.setLargeIcon(BitmapFactory.decodeStream(fh))
|
||||
.setSmallIcon(R.mipmap.knott_transparent)
|
||||
.setContentIntent(PendingIntent.getActivity(applicationContext, 1, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT))
|
||||
.setAutoCancel(true)
|
||||
.build()
|
||||
notificationManager.notify(getNotificationID(data.getString("ProfileOnion"), handle), newNotification)
|
||||
}
|
||||
} else if (evt.EventType == "FileDownloadProgressUpdate") {
|
||||
try {
|
||||
|
@ -363,6 +394,11 @@ class FlwtchWorker(context: Context, parameters: WorkerParameters) :
|
|||
val v = (a.get("Val") as? String) ?: ""
|
||||
Cwtch.setServerAttribute(serverOnion, key, v)
|
||||
}
|
||||
"L10nInit" -> {
|
||||
notificationSimple = (a.get("notificationSimple") as? String) ?: "New Message"
|
||||
notificationConversationInfo = (a.get("notificationConversationInfo") as? String)
|
||||
?: "New Message From "
|
||||
}
|
||||
else -> {
|
||||
Log.i("FlwtchWorker", "unknown command: " + method);
|
||||
return Result.failure()
|
||||
|
|
|
@ -105,5 +105,9 @@ abstract class Cwtch {
|
|||
// non-ffi
|
||||
String defaultDownloadPath();
|
||||
|
||||
bool isL10nInit();
|
||||
|
||||
void l10nInit(String notificationSimple, String notificationConversationInfo);
|
||||
|
||||
void dispose();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import 'package:cwtch/models/remoteserver.dart';
|
|||
import 'package:cwtch/models/servers.dart';
|
||||
import 'package:cwtch/notification_manager.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'package:cwtch/torstatus.dart';
|
||||
|
@ -28,6 +29,9 @@ class CwtchNotifier {
|
|||
late AppState appState;
|
||||
late ServerListState serverListState;
|
||||
|
||||
String? notificationSimple;
|
||||
String? notificationConversationInfo;
|
||||
|
||||
CwtchNotifier(
|
||||
ProfileListState pcn, Settings settingsCN, ErrorHandler errorCN, TorStatus torStatusCN, NotificationsManager notificationManagerP, AppState appStateCN, ServerListState serverListStateCN) {
|
||||
profileCN = pcn;
|
||||
|
@ -39,6 +43,11 @@ class CwtchNotifier {
|
|||
serverListState = serverListStateCN;
|
||||
}
|
||||
|
||||
void l10nInit(String notificationSimple, String notificationConversationInfo) {
|
||||
this.notificationSimple = notificationSimple;
|
||||
this.notificationConversationInfo = notificationConversationInfo;
|
||||
}
|
||||
|
||||
void handleMessage(String type, dynamic data) {
|
||||
//EnvironmentConfig.debugLog("NewEvent $type $data");
|
||||
switch (type) {
|
||||
|
@ -60,24 +69,22 @@ class CwtchNotifier {
|
|||
case "ContactCreated":
|
||||
EnvironmentConfig.debugLog("ContactCreated $data");
|
||||
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.add(ContactInfoState(
|
||||
data["ProfileOnion"],
|
||||
int.parse(data["ConversationID"]),
|
||||
data["RemotePeer"],
|
||||
nickname: data["nick"],
|
||||
status: data["status"],
|
||||
imagePath: data["picture"],
|
||||
defaultImagePath: data["defaultPicture"],
|
||||
blocked: data["blocked"] == "true",
|
||||
accepted: data["accepted"] == "true",
|
||||
savePeerHistory: data["saveConversationHistory"] == null ? "DeleteHistoryConfirmed" : data["saveConversationHistory"],
|
||||
numMessages: int.parse(data["numMessages"]),
|
||||
numUnread: int.parse(data["unread"]),
|
||||
isGroup: false, // by definition
|
||||
server: null,
|
||||
archived: false,
|
||||
lastMessageTime: DateTime.now(), //show at the top of the contact list even if no messages yet
|
||||
));
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.add(ContactInfoState(data["ProfileOnion"], int.parse(data["ConversationID"]), data["RemotePeer"],
|
||||
nickname: data["nick"],
|
||||
status: data["status"],
|
||||
imagePath: data["picture"],
|
||||
defaultImagePath: data["defaultPicture"],
|
||||
blocked: data["blocked"] == "true",
|
||||
accepted: data["accepted"] == "true",
|
||||
savePeerHistory: data["saveConversationHistory"] == null ? "DeleteHistoryConfirmed" : data["saveConversationHistory"],
|
||||
numMessages: int.parse(data["numMessages"]),
|
||||
numUnread: int.parse(data["unread"]),
|
||||
isGroup: false, // by definition
|
||||
server: null,
|
||||
archived: false,
|
||||
lastMessageTime: DateTime.now(), //show at the top of the contact list even if no messages yet
|
||||
notificationPolicy: data["notificationPolicy"] ?? "ConversationNotificationPolicy.Default"));
|
||||
|
||||
break;
|
||||
case "NewServer":
|
||||
EnvironmentConfig.debugLog("NewServer $data");
|
||||
|
@ -113,7 +120,9 @@ class CwtchNotifier {
|
|||
status: status,
|
||||
server: data["GroupServer"],
|
||||
isGroup: true,
|
||||
lastMessageTime: DateTime.now()));
|
||||
lastMessageTime: DateTime.now(),
|
||||
notificationPolicy: data["notificationPolicy"] ?? "ConversationNotificationPolicy.Default"));
|
||||
|
||||
profileCN.getProfile(data["ProfileOnion"])?.contactList.updateLastMessageTime(int.parse(data["ConversationID"]), DateTime.now());
|
||||
}
|
||||
break;
|
||||
|
@ -144,7 +153,6 @@ class CwtchNotifier {
|
|||
}
|
||||
break;
|
||||
case "NewMessageFromPeer":
|
||||
notificationManager.notify("New Message From Peer!");
|
||||
var identifier = int.parse(data["ConversationID"]);
|
||||
var messageID = int.parse(data["Index"]);
|
||||
var timestamp = DateTime.tryParse(data['TimestampReceived'])!;
|
||||
|
@ -154,6 +162,14 @@ class CwtchNotifier {
|
|||
String? contenthash = data['ContentHash'];
|
||||
var selectedProfile = appState.selectedProfile == data["ProfileOnion"];
|
||||
var selectedConversation = selectedProfile && appState.selectedConversation == identifier;
|
||||
var notification = data["notification"];
|
||||
|
||||
if (notification == "SimpleEvent") {
|
||||
notificationManager.notify(notificationSimple ?? "New Message");
|
||||
} else if (notification == "ContactInfo") {
|
||||
var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier);
|
||||
notificationManager.notify((notificationConversationInfo ?? "New Message from %1").replaceFirst("%1", (contact?.nickname ?? senderHandle.toString())));
|
||||
}
|
||||
|
||||
profileCN.getProfile(data["ProfileOnion"])?.newMessage(
|
||||
identifier,
|
||||
|
@ -209,6 +225,7 @@ class CwtchNotifier {
|
|||
String? contenthash = data['ContentHash'];
|
||||
var selectedProfile = appState.selectedProfile == data["ProfileOnion"];
|
||||
var selectedConversation = selectedProfile && appState.selectedConversation == identifier;
|
||||
var notification = data["notification"];
|
||||
|
||||
// Only bother to do anything if we know about the group and the provided index is greater than our current total...
|
||||
if (currentTotal != null && idx >= currentTotal) {
|
||||
|
@ -224,7 +241,12 @@ class CwtchNotifier {
|
|||
// and `local now`.
|
||||
profileCN.getProfile(data["ProfileOnion"])?.newMessage(identifier, idx, timestampSent, senderHandle, senderImage, isAuto, data["Data"], contenthash, selectedProfile, selectedConversation);
|
||||
|
||||
notificationManager.notify("New Message From Group!");
|
||||
if (notification == "SimpleEvent") {
|
||||
notificationManager.notify(notificationSimple ?? "New Message");
|
||||
} else if (notification == "ContactInfo") {
|
||||
var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.getContact(identifier);
|
||||
notificationManager.notify((notificationConversationInfo ?? "New Message from %1").replaceFirst("%1", (contact?.nickname ?? senderHandle.toString())));
|
||||
}
|
||||
appState.notifyProfileUnread();
|
||||
}
|
||||
RemoteServerInfoState? server = profileCN.getProfile(data["ProfileOnion"])?.serverList.getServer(contact.server ?? "");
|
||||
|
|
|
@ -100,6 +100,7 @@ class CwtchFfi implements Cwtch {
|
|||
late CwtchNotifier cwtchNotifier;
|
||||
late Isolate cwtchIsolate;
|
||||
ReceivePort _receivePort = ReceivePort();
|
||||
bool _isL10nInit = false;
|
||||
|
||||
static String getLibraryPath() {
|
||||
if (Platform.isWindows) {
|
||||
|
@ -744,4 +745,15 @@ class CwtchFfi implements Cwtch {
|
|||
malloc.free(utf8newpass);
|
||||
malloc.free(utf8newpasssagain);
|
||||
}
|
||||
|
||||
@override
|
||||
bool isL10nInit() {
|
||||
return _isL10nInit;
|
||||
}
|
||||
|
||||
@override
|
||||
void l10nInit(String notificationSimple, String notificationConversationInfo) {
|
||||
cwtchNotifier.l10nInit(notificationSimple, notificationConversationInfo);
|
||||
_isL10nInit = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ class CwtchGomobile implements Cwtch {
|
|||
late Future<dynamic> androidHomeDirectory;
|
||||
String androidHomeDirectoryStr = "";
|
||||
late CwtchNotifier cwtchNotifier;
|
||||
bool _isL10nInit = false;
|
||||
|
||||
CwtchGomobile(CwtchNotifier _cwtchNotifier) {
|
||||
print("gomobile.dart: CwtchGomobile()");
|
||||
|
@ -295,4 +296,16 @@ class CwtchGomobile implements Cwtch {
|
|||
void ChangePassword(String profile, String pass, String newpass, String newpassAgain) {
|
||||
cwtchPlatform.invokeMethod("ChangePassword", {"ProfileOnion": profile, "OldPass": pass, "NewPass": newpass, "NewPassAgain": newpassAgain});
|
||||
}
|
||||
|
||||
@override
|
||||
bool isL10nInit() {
|
||||
return _isL10nInit;
|
||||
}
|
||||
|
||||
@override
|
||||
void l10nInit(String notificationSimple, String notificationConversationInfo) {
|
||||
cwtchNotifier.l10nInit(notificationSimple, notificationConversationInfo);
|
||||
cwtchPlatform.invokeMethod("L10nInit", {"notificationSimple": notificationSimple, "notificationConversationInfo": notificationConversationInfo});
|
||||
_isL10nInit = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
{
|
||||
"@@locale": "de",
|
||||
"@@last_modified": "2022-02-07T21:17:01+01:00",
|
||||
"@@last_modified": "2022-02-08T20:13:50+01:00",
|
||||
"newMessageNotificationConversationInfo": "New Message From %1",
|
||||
"newMessageNotificationSimple": "New Message",
|
||||
"notificationContentContactInfo": "Conversation Information",
|
||||
"notificationContentSimpleEvent": "Plain Event",
|
||||
"conversationNotificationPolicySettingDescription": "Control this conversation's notification behaviour",
|
||||
"conversationNotificationPolicySettingLabel": "Conversation Notification Policy",
|
||||
"settingsGroupExperiments": "Experiments",
|
||||
"settingsGroupAppearance": "Appearance",
|
||||
"settingGroupBehaviour": "Behaviour",
|
||||
"notificationContentSettingDescription": "Controls the contents of conversation notifications",
|
||||
"notificationPolicySettingDescription": "Controls the default application notification behaviour",
|
||||
"notificationContentSettingLabel": "Notification Content",
|
||||
"notificationPolicySettingLabel": "Notification Policy",
|
||||
"conversationNotificationPolicyNever": "Never",
|
||||
"conversationNotificationPolicyOptIn": "Opt In",
|
||||
"conversationNotificationPolicyDefault": "Default",
|
||||
"notificationPolicyDefaultAll": "Default All",
|
||||
"notificationPolicyOptIn": "Opt In",
|
||||
"notificationPolicyMute": "Mute",
|
||||
"tooltipSelectACustomProfileImage": "Select a Custom Profile Image",
|
||||
"torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.",
|
||||
"torSettingsEnableCache": "Cache Tor Consensus",
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
{
|
||||
"@@locale": "en",
|
||||
"@@last_modified": "2022-02-07T21:17:01+01:00",
|
||||
"@@last_modified": "2022-02-08T20:13:50+01:00",
|
||||
"newMessageNotificationConversationInfo": "New Message From %1",
|
||||
"newMessageNotificationSimple": "New Message",
|
||||
"notificationContentContactInfo": "Conversation Information",
|
||||
"notificationContentSimpleEvent": "Plain Event",
|
||||
"conversationNotificationPolicySettingDescription": "Control this conversation's notification behaviour",
|
||||
"conversationNotificationPolicySettingLabel": "Conversation Notification Policy",
|
||||
"settingsGroupExperiments": "Experiments",
|
||||
"settingsGroupAppearance": "Appearance",
|
||||
"settingGroupBehaviour": "Behaviour",
|
||||
"notificationContentSettingDescription": "Controls the contents of conversation notifications",
|
||||
"notificationPolicySettingDescription": "Controls the default application notification behaviour",
|
||||
"notificationContentSettingLabel": "Notification Content",
|
||||
"notificationPolicySettingLabel": "Notification Policy",
|
||||
"conversationNotificationPolicyNever": "Never",
|
||||
"conversationNotificationPolicyOptIn": "Opt In",
|
||||
"conversationNotificationPolicyDefault": "Default",
|
||||
"notificationPolicyDefaultAll": "Default All",
|
||||
"notificationPolicyOptIn": "Opt In",
|
||||
"notificationPolicyMute": "Mute",
|
||||
"tooltipSelectACustomProfileImage": "Select a Custom Profile Image",
|
||||
"editProfile": "Edit Profile",
|
||||
"torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.",
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
{
|
||||
"@@locale": "es",
|
||||
"@@last_modified": "2022-02-07T21:17:01+01:00",
|
||||
"@@last_modified": "2022-02-08T20:13:50+01:00",
|
||||
"newMessageNotificationConversationInfo": "New Message From %1",
|
||||
"newMessageNotificationSimple": "New Message",
|
||||
"notificationContentContactInfo": "Conversation Information",
|
||||
"notificationContentSimpleEvent": "Plain Event",
|
||||
"conversationNotificationPolicySettingDescription": "Control this conversation's notification behaviour",
|
||||
"conversationNotificationPolicySettingLabel": "Conversation Notification Policy",
|
||||
"settingsGroupExperiments": "Experiments",
|
||||
"settingsGroupAppearance": "Appearance",
|
||||
"settingGroupBehaviour": "Behaviour",
|
||||
"notificationContentSettingDescription": "Controls the contents of conversation notifications",
|
||||
"notificationPolicySettingDescription": "Controls the default application notification behaviour",
|
||||
"notificationContentSettingLabel": "Notification Content",
|
||||
"notificationPolicySettingLabel": "Notification Policy",
|
||||
"conversationNotificationPolicyNever": "Never",
|
||||
"conversationNotificationPolicyOptIn": "Opt In",
|
||||
"conversationNotificationPolicyDefault": "Default",
|
||||
"notificationPolicyDefaultAll": "Default All",
|
||||
"notificationPolicyOptIn": "Opt In",
|
||||
"notificationPolicyMute": "Mute",
|
||||
"tooltipSelectACustomProfileImage": "Select a Custom Profile Image",
|
||||
"torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.",
|
||||
"torSettingsEnableCache": "Cache Tor Consensus",
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
{
|
||||
"@@locale": "fr",
|
||||
"@@last_modified": "2022-02-07T21:17:01+01:00",
|
||||
"@@last_modified": "2022-02-08T20:13:50+01:00",
|
||||
"newMessageNotificationConversationInfo": "New Message From %1",
|
||||
"newMessageNotificationSimple": "New Message",
|
||||
"notificationContentContactInfo": "Conversation Information",
|
||||
"notificationContentSimpleEvent": "Plain Event",
|
||||
"conversationNotificationPolicySettingDescription": "Control this conversation's notification behaviour",
|
||||
"conversationNotificationPolicySettingLabel": "Conversation Notification Policy",
|
||||
"settingsGroupExperiments": "Experiments",
|
||||
"settingsGroupAppearance": "Appearance",
|
||||
"settingGroupBehaviour": "Behaviour",
|
||||
"notificationContentSettingDescription": "Controls the contents of conversation notifications",
|
||||
"notificationPolicySettingDescription": "Controls the default application notification behaviour",
|
||||
"notificationContentSettingLabel": "Notification Content",
|
||||
"notificationPolicySettingLabel": "Notification Policy",
|
||||
"conversationNotificationPolicyNever": "Never",
|
||||
"conversationNotificationPolicyOptIn": "Opt In",
|
||||
"conversationNotificationPolicyDefault": "Default",
|
||||
"notificationPolicyDefaultAll": "Default All",
|
||||
"notificationPolicyOptIn": "Opt In",
|
||||
"notificationPolicyMute": "Mute",
|
||||
"tooltipSelectACustomProfileImage": "Select a Custom Profile Image",
|
||||
"editProfile": "Modifier le profil",
|
||||
"settingTheme": "Utilisez des thèmes clairs",
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
{
|
||||
"@@locale": "it",
|
||||
"@@last_modified": "2022-02-07T21:17:01+01:00",
|
||||
"@@last_modified": "2022-02-08T20:13:50+01:00",
|
||||
"newMessageNotificationConversationInfo": "New Message From %1",
|
||||
"newMessageNotificationSimple": "New Message",
|
||||
"notificationContentContactInfo": "Conversation Information",
|
||||
"notificationContentSimpleEvent": "Plain Event",
|
||||
"conversationNotificationPolicySettingDescription": "Control this conversation's notification behaviour",
|
||||
"conversationNotificationPolicySettingLabel": "Conversation Notification Policy",
|
||||
"settingsGroupExperiments": "Experiments",
|
||||
"settingsGroupAppearance": "Appearance",
|
||||
"settingGroupBehaviour": "Behaviour",
|
||||
"notificationContentSettingDescription": "Controls the contents of conversation notifications",
|
||||
"notificationPolicySettingDescription": "Controls the default application notification behaviour",
|
||||
"notificationContentSettingLabel": "Notification Content",
|
||||
"notificationPolicySettingLabel": "Notification Policy",
|
||||
"conversationNotificationPolicyNever": "Never",
|
||||
"conversationNotificationPolicyOptIn": "Opt In",
|
||||
"conversationNotificationPolicyDefault": "Default",
|
||||
"notificationPolicyDefaultAll": "Default All",
|
||||
"notificationPolicyOptIn": "Opt In",
|
||||
"notificationPolicyMute": "Mute",
|
||||
"tooltipSelectACustomProfileImage": "Select a Custom Profile Image",
|
||||
"torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.",
|
||||
"torSettingsEnableCache": "Cache Tor Consensus",
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
{
|
||||
"@@locale": "pl",
|
||||
"@@last_modified": "2022-02-07T21:17:01+01:00",
|
||||
"@@last_modified": "2022-02-08T20:13:50+01:00",
|
||||
"newMessageNotificationConversationInfo": "New Message From %1",
|
||||
"newMessageNotificationSimple": "New Message",
|
||||
"notificationContentContactInfo": "Conversation Information",
|
||||
"notificationContentSimpleEvent": "Plain Event",
|
||||
"conversationNotificationPolicySettingDescription": "Control this conversation's notification behaviour",
|
||||
"conversationNotificationPolicySettingLabel": "Conversation Notification Policy",
|
||||
"settingsGroupExperiments": "Experiments",
|
||||
"settingsGroupAppearance": "Appearance",
|
||||
"settingGroupBehaviour": "Behaviour",
|
||||
"notificationContentSettingDescription": "Controls the contents of conversation notifications",
|
||||
"notificationPolicySettingDescription": "Controls the default application notification behaviour",
|
||||
"notificationContentSettingLabel": "Notification Content",
|
||||
"notificationPolicySettingLabel": "Notification Policy",
|
||||
"conversationNotificationPolicyNever": "Never",
|
||||
"conversationNotificationPolicyOptIn": "Opt In",
|
||||
"conversationNotificationPolicyDefault": "Default",
|
||||
"notificationPolicyDefaultAll": "Default All",
|
||||
"notificationPolicyOptIn": "Opt In",
|
||||
"notificationPolicyMute": "Mute",
|
||||
"tooltipSelectACustomProfileImage": "Select a Custom Profile Image",
|
||||
"torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.",
|
||||
"torSettingsEnableCache": "Cache Tor Consensus",
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
{
|
||||
"@@locale": "pt",
|
||||
"@@last_modified": "2022-02-07T21:17:01+01:00",
|
||||
"@@last_modified": "2022-02-08T20:13:50+01:00",
|
||||
"newMessageNotificationConversationInfo": "New Message From %1",
|
||||
"newMessageNotificationSimple": "New Message",
|
||||
"notificationContentContactInfo": "Conversation Information",
|
||||
"notificationContentSimpleEvent": "Plain Event",
|
||||
"conversationNotificationPolicySettingDescription": "Control this conversation's notification behaviour",
|
||||
"conversationNotificationPolicySettingLabel": "Conversation Notification Policy",
|
||||
"settingsGroupExperiments": "Experiments",
|
||||
"settingsGroupAppearance": "Appearance",
|
||||
"settingGroupBehaviour": "Behaviour",
|
||||
"notificationContentSettingDescription": "Controls the contents of conversation notifications",
|
||||
"notificationPolicySettingDescription": "Controls the default application notification behaviour",
|
||||
"notificationContentSettingLabel": "Notification Content",
|
||||
"notificationPolicySettingLabel": "Notification Policy",
|
||||
"conversationNotificationPolicyNever": "Never",
|
||||
"conversationNotificationPolicyOptIn": "Opt In",
|
||||
"conversationNotificationPolicyDefault": "Default",
|
||||
"notificationPolicyDefaultAll": "Default All",
|
||||
"notificationPolicyOptIn": "Opt In",
|
||||
"notificationPolicyMute": "Mute",
|
||||
"tooltipSelectACustomProfileImage": "Select a Custom Profile Image",
|
||||
"torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.",
|
||||
"torSettingsEnableCache": "Cache Tor Consensus",
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
{
|
||||
"@@locale": "ru",
|
||||
"@@last_modified": "2022-02-07T21:17:01+01:00",
|
||||
"@@last_modified": "2022-02-08T20:13:50+01:00",
|
||||
"newMessageNotificationConversationInfo": "New Message From %1",
|
||||
"newMessageNotificationSimple": "New Message",
|
||||
"notificationContentContactInfo": "Conversation Information",
|
||||
"notificationContentSimpleEvent": "Plain Event",
|
||||
"conversationNotificationPolicySettingDescription": "Control this conversation's notification behaviour",
|
||||
"conversationNotificationPolicySettingLabel": "Conversation Notification Policy",
|
||||
"settingsGroupExperiments": "Experiments",
|
||||
"settingsGroupAppearance": "Appearance",
|
||||
"settingGroupBehaviour": "Behaviour",
|
||||
"notificationContentSettingDescription": "Controls the contents of conversation notifications",
|
||||
"notificationPolicySettingDescription": "Controls the default application notification behaviour",
|
||||
"notificationContentSettingLabel": "Notification Content",
|
||||
"notificationPolicySettingLabel": "Notification Policy",
|
||||
"conversationNotificationPolicyNever": "Never",
|
||||
"conversationNotificationPolicyOptIn": "Opt In",
|
||||
"conversationNotificationPolicyDefault": "Default",
|
||||
"notificationPolicyDefaultAll": "Default All",
|
||||
"notificationPolicyOptIn": "Opt In",
|
||||
"notificationPolicyMute": "Mute",
|
||||
"tooltipSelectACustomProfileImage": "Select a Custom Profile Image",
|
||||
"torSettingsEnabledCacheDescription": "Cache the current downloaded Tor consensus to reuse next time Cwtch is opened. This will allow Tor to start faster. When disabled, Cwtch will purge cached data on start up.",
|
||||
"torSettingsEnableCache": "Cache Tor Consensus",
|
||||
|
|
|
@ -37,7 +37,6 @@ Future<void> main() async {
|
|||
WidgetsFlutterBinding.ensureInitialized();
|
||||
print("runApp()");
|
||||
runApp(Flwtch());
|
||||
sleep(Duration(seconds: 1));
|
||||
}
|
||||
|
||||
class Flwtch extends StatefulWidget {
|
||||
|
|
|
@ -1,15 +1,38 @@
|
|||
import 'package:cwtch/widgets/messagerow.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
|
||||
import 'message.dart';
|
||||
import 'messagecache.dart';
|
||||
|
||||
enum ConversationNotificationPolicy {
|
||||
Default,
|
||||
OptIn,
|
||||
Never,
|
||||
}
|
||||
|
||||
extension Nameable on ConversationNotificationPolicy {
|
||||
String toName(BuildContext context) {
|
||||
switch (this) {
|
||||
case ConversationNotificationPolicy.Default:
|
||||
return AppLocalizations.of(context)!.conversationNotificationPolicyDefault;
|
||||
case ConversationNotificationPolicy.OptIn:
|
||||
return AppLocalizations.of(context)!.conversationNotificationPolicyOptIn;
|
||||
case ConversationNotificationPolicy.Never:
|
||||
return AppLocalizations.of(context)!.conversationNotificationPolicyNever;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ContactInfoState extends ChangeNotifier {
|
||||
final String profileOnion;
|
||||
final int identifier;
|
||||
final String onion;
|
||||
late String _nickname;
|
||||
|
||||
late ConversationNotificationPolicy _notificationPolicy;
|
||||
|
||||
late bool _accepted;
|
||||
late bool _blocked;
|
||||
late String _status;
|
||||
|
@ -44,7 +67,8 @@ class ContactInfoState extends ChangeNotifier {
|
|||
numUnread = 0,
|
||||
lastMessageTime,
|
||||
server,
|
||||
archived = false}) {
|
||||
archived = false,
|
||||
notificationPolicy = "ConversationNotificationPolicy.Default"}) {
|
||||
this._nickname = nickname;
|
||||
this._isGroup = isGroup;
|
||||
this._accepted = accepted;
|
||||
|
@ -58,6 +82,7 @@ class ContactInfoState extends ChangeNotifier {
|
|||
this._lastMessageTime = lastMessageTime == null ? DateTime.fromMillisecondsSinceEpoch(0) : lastMessageTime;
|
||||
this._server = server;
|
||||
this._archived = archived;
|
||||
this._notificationPolicy = notificationPolicyFromString(notificationPolicy);
|
||||
this.messageCache = new MessageCache();
|
||||
keys = Map<String, GlobalKey<MessageRowState>>();
|
||||
}
|
||||
|
@ -201,6 +226,13 @@ class ContactInfoState extends ChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
ConversationNotificationPolicy get notificationsPolicy => _notificationPolicy;
|
||||
|
||||
set notificationsPolicy(ConversationNotificationPolicy newVal) {
|
||||
_notificationPolicy = newVal;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
GlobalKey<MessageRowState> getMessageKey(int conversation, int message) {
|
||||
String index = "c: " + conversation.toString() + " m:" + message.toString();
|
||||
if (keys[index] == null) {
|
||||
|
@ -244,4 +276,16 @@ class ContactInfoState extends ChangeNotifier {
|
|||
this.messageCache.ackCache(messageID);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
static ConversationNotificationPolicy notificationPolicyFromString(String val) {
|
||||
switch (val) {
|
||||
case "ConversationNotificationPolicy.Default":
|
||||
return ConversationNotificationPolicy.Default;
|
||||
case "ConversationNotificationPolicy.OptIn":
|
||||
return ConversationNotificationPolicy.OptIn;
|
||||
case "ConversationNotificationPolicy.Never":
|
||||
return ConversationNotificationPolicy.Never;
|
||||
}
|
||||
return ConversationNotificationPolicy.Never;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,8 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
isGroup: contact["isGroup"],
|
||||
server: contact["groupServer"],
|
||||
archived: contact["isArchived"] == true,
|
||||
lastMessageTime: DateTime.fromMillisecondsSinceEpoch(1000 * int.parse(contact["lastMsgTime"])));
|
||||
lastMessageTime: DateTime.fromMillisecondsSinceEpoch(1000 * int.parse(contact["lastMsgTime"])),
|
||||
notificationPolicy: contact["notificationPolicy"] ?? "ConversationNotificationPolicy.Default");
|
||||
}));
|
||||
|
||||
// dummy set to invoke sort-on-load
|
||||
|
@ -100,6 +101,7 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
|
||||
// Getters and Setters for Online Status
|
||||
bool get isOnline => this._online;
|
||||
|
||||
set isOnline(bool newValue) {
|
||||
this._online = newValue;
|
||||
notifyListeners();
|
||||
|
@ -109,24 +111,28 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
bool get isEncrypted => this._encrypted;
|
||||
|
||||
String get nickname => this._nickname;
|
||||
|
||||
set nickname(String newValue) {
|
||||
this._nickname = newValue;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
String get imagePath => this._imagePath;
|
||||
|
||||
set imagePath(String newVal) {
|
||||
this._imagePath = newVal;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
String get defaultImagePath => this._defaultImagePath;
|
||||
|
||||
set defaultImagePath(String newVal) {
|
||||
this._defaultImagePath = newVal;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
int get unreadMessages => this._unreadMessages;
|
||||
|
||||
set unreadMessages(int newVal) {
|
||||
this._unreadMessages = newVal;
|
||||
notifyListeners();
|
||||
|
@ -144,6 +150,7 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
}
|
||||
|
||||
ContactListState get contactList => this._contacts;
|
||||
|
||||
ProfileServerListState get serverList => this._servers;
|
||||
|
||||
@override
|
||||
|
@ -183,6 +190,7 @@ class ProfileInfoState extends ChangeNotifier {
|
|||
isGroup: contact["isGroup"],
|
||||
server: contact["groupServer"],
|
||||
lastMessageTime: DateTime.fromMillisecondsSinceEpoch(1000 * int.parse(contact["lastMsgTime"])),
|
||||
notificationPolicy: contact["notificationPolicy"] ?? "ConversationNotificationPolicy.Default",
|
||||
));
|
||||
}
|
||||
unreadMessages += int.parse(contact["numUnread"]);
|
||||
|
|
|
@ -22,6 +22,17 @@ enum DualpaneMode {
|
|||
CopyPortrait,
|
||||
}
|
||||
|
||||
enum NotificationPolicy {
|
||||
Mute,
|
||||
OptIn,
|
||||
DefaultAll,
|
||||
}
|
||||
|
||||
enum NotificationContent {
|
||||
SimpleEvent,
|
||||
ContactInfo,
|
||||
}
|
||||
|
||||
/// Settings govern the *Globally* relevant settings like Locale, Theme and Experiments.
|
||||
/// We also provide access to the version information here as it is also accessed from the
|
||||
/// Settings Pane.
|
||||
|
@ -29,12 +40,16 @@ class Settings extends ChangeNotifier {
|
|||
Locale locale;
|
||||
late PackageInfo packageInfo;
|
||||
OpaqueThemeType theme;
|
||||
|
||||
// explicitly set experiments to false until told otherwise...
|
||||
bool experimentsEnabled = false;
|
||||
HashMap<String, bool> experiments = HashMap.identity();
|
||||
DualpaneMode _uiColumnModePortrait = DualpaneMode.Single;
|
||||
DualpaneMode _uiColumnModeLandscape = DualpaneMode.CopyPortrait;
|
||||
|
||||
NotificationPolicy _notificationPolicy = NotificationPolicy.DefaultAll;
|
||||
NotificationContent _notificationContent = NotificationContent.SimpleEvent;
|
||||
|
||||
bool blockUnknownConnections = false;
|
||||
bool streamerMode = false;
|
||||
String _downloadPath = "";
|
||||
|
@ -94,6 +109,9 @@ class Settings extends ChangeNotifier {
|
|||
_uiColumnModePortrait = uiColumnModeFromString(settings["UIColumnModePortrait"]);
|
||||
_uiColumnModeLandscape = uiColumnModeFromString(settings["UIColumnModeLandscape"]);
|
||||
|
||||
_notificationPolicy = notificationPolicyFromString(settings["NotificationPolicy"]);
|
||||
_notificationContent = notificationContentFromString(settings["NotificationContent"]);
|
||||
|
||||
// auto-download folder
|
||||
_downloadPath = settings["DownloadPath"] ?? "";
|
||||
|
||||
|
@ -173,17 +191,33 @@ class Settings extends ChangeNotifier {
|
|||
}
|
||||
|
||||
DualpaneMode get uiColumnModePortrait => _uiColumnModePortrait;
|
||||
|
||||
set uiColumnModePortrait(DualpaneMode newval) {
|
||||
this._uiColumnModePortrait = newval;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
DualpaneMode get uiColumnModeLandscape => _uiColumnModeLandscape;
|
||||
|
||||
set uiColumnModeLandscape(DualpaneMode newval) {
|
||||
this._uiColumnModeLandscape = newval;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
NotificationPolicy get notificationPolicy => _notificationPolicy;
|
||||
|
||||
set notificationPolicy(NotificationPolicy newpol) {
|
||||
this._notificationPolicy = newpol;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
NotificationContent get notificationContent => _notificationContent;
|
||||
|
||||
set notificationContent(NotificationContent newcon) {
|
||||
this._notificationContent = newcon;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
List<int> uiColumns(bool isLandscape) {
|
||||
var m = (!isLandscape || uiColumnModeLandscape == DualpaneMode.CopyPortrait) ? uiColumnModePortrait : uiColumnModeLandscape;
|
||||
switch (m) {
|
||||
|
@ -238,6 +272,43 @@ class Settings extends ChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
static NotificationPolicy notificationPolicyFromString(String? np) {
|
||||
switch (np) {
|
||||
case "NotificationPolicy.None":
|
||||
return NotificationPolicy.Mute;
|
||||
case "NotificationPolicy.OptIn":
|
||||
return NotificationPolicy.OptIn;
|
||||
case "NotificationPolicy.OptOut":
|
||||
return NotificationPolicy.DefaultAll;
|
||||
}
|
||||
return NotificationPolicy.DefaultAll;
|
||||
}
|
||||
|
||||
static NotificationContent notificationContentFromString(String? nc) {
|
||||
switch (nc) {
|
||||
case "NotificationContent.SimpleEvent":
|
||||
return NotificationContent.SimpleEvent;
|
||||
case "NotificationContent.ContactInfo":
|
||||
return NotificationContent.ContactInfo;
|
||||
}
|
||||
return NotificationContent.SimpleEvent;
|
||||
}
|
||||
|
||||
static String notificationPolicyToString(NotificationPolicy np, BuildContext context) {
|
||||
switch (np) {
|
||||
case NotificationPolicy.Mute: return AppLocalizations.of(context)!.notificationPolicyMute;
|
||||
case NotificationPolicy.OptIn: return AppLocalizations.of(context)!.notificationPolicyOptIn;
|
||||
case NotificationPolicy.DefaultAll: return AppLocalizations.of(context)!.notificationPolicyDefaultAll;
|
||||
}
|
||||
}
|
||||
|
||||
static String notificationContentToString(NotificationContent nc, BuildContext context) {
|
||||
switch (nc) {
|
||||
case NotificationContent.SimpleEvent: return AppLocalizations.of(context)!.notificationContentSimpleEvent;
|
||||
case NotificationContent.ContactInfo: return AppLocalizations.of(context)!.notificationContentContactInfo;
|
||||
}
|
||||
}
|
||||
|
||||
// checks experiment settings and file extension for image previews
|
||||
// (ignores file size; if the user manually accepts the file, assume it's okay to preview)
|
||||
bool shouldPreview(String path) {
|
||||
|
@ -247,18 +318,21 @@ class Settings extends ChangeNotifier {
|
|||
}
|
||||
|
||||
String get downloadPath => _downloadPath;
|
||||
|
||||
set downloadPath(String newval) {
|
||||
_downloadPath = newval;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool get allowAdvancedTorConfig => _allowAdvancedTorConfig;
|
||||
|
||||
set allowAdvancedTorConfig(bool torConfig) {
|
||||
_allowAdvancedTorConfig = torConfig;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool get useTorCache => _useTorCache;
|
||||
|
||||
set useTorCache(bool useTorCache) {
|
||||
_useTorCache = useTorCache;
|
||||
notifyListeners();
|
||||
|
@ -266,18 +340,21 @@ class Settings extends ChangeNotifier {
|
|||
|
||||
// Settings / Gettings for setting the custom tor config..
|
||||
String get torConfig => _customTorConfig;
|
||||
|
||||
set torConfig(String torConfig) {
|
||||
_customTorConfig = torConfig;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
int get socksPort => _socksPort;
|
||||
|
||||
set socksPort(int newSocksPort) {
|
||||
_socksPort = newSocksPort;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
int get controlPort => _controlPort;
|
||||
|
||||
set controlPort(int controlPort) {
|
||||
_controlPort = controlPort;
|
||||
notifyListeners();
|
||||
|
@ -285,6 +362,7 @@ class Settings extends ChangeNotifier {
|
|||
|
||||
// Setters / Getters for toggling whether the app should use a custom tor config
|
||||
bool get useCustomTorConfig => _useCustomTorConfig;
|
||||
|
||||
set useCustomTorConfig(bool useCustomTorConfig) {
|
||||
_useCustomTorConfig = useCustomTorConfig;
|
||||
notifyListeners();
|
||||
|
@ -302,6 +380,8 @@ class Settings extends ChangeNotifier {
|
|||
"ThemeMode": theme.mode,
|
||||
"PreviousPid": -1,
|
||||
"BlockUnknownConnections": blockUnknownConnections,
|
||||
"NotificationPolicy": _notificationPolicy.toString(),
|
||||
"NotificationContent": _notificationContent.toString(),
|
||||
"StreamerMode": streamerMode,
|
||||
"ExperimentsEnabled": this.experimentsEnabled,
|
||||
"Experiments": experiments,
|
||||
|
|
|
@ -53,11 +53,13 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
|||
isAlwaysShown: true,
|
||||
child: SingleChildScrollView(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
padding: EdgeInsets.all(20),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight: viewportConstraints.maxHeight,
|
||||
),
|
||||
child: Column(children: [
|
||||
Row(mainAxisAlignment: MainAxisAlignment.center, children: [Text(AppLocalizations.of(context)!.settingsGroupAppearance, style: TextStyle(fontWeight: FontWeight.bold))]),
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.settingLanguage, style: TextStyle(color: settings.current().mainTextColor)),
|
||||
leading: Icon(CwtchIcons.change_language, color: settings.current().mainTextColor),
|
||||
|
@ -135,24 +137,78 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
|||
style: TextStyle(color: settings.current().mainTextColor),
|
||||
),
|
||||
leading: Icon(Icons.table_chart, color: settings.current().mainTextColor),
|
||||
trailing: Container(
|
||||
width: MediaQuery.of(context).size.width / 4,
|
||||
child: DropdownButton(
|
||||
isExpanded: true,
|
||||
value: settings.uiColumnModeLandscape.toString(),
|
||||
onChanged: (String? newValue) {
|
||||
settings.uiColumnModeLandscape = Settings.uiColumnModeFromString(newValue!);
|
||||
saveSettings(context);
|
||||
},
|
||||
items: Settings.uiColumnModeOptions(true).map<DropdownMenuItem<String>>((DualpaneMode value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value.toString(),
|
||||
child: Text(
|
||||
Settings.uiColumnModeToString(value, context),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
}).toList()))),
|
||||
trailing: DropdownButton(
|
||||
value: settings.uiColumnModeLandscape.toString(),
|
||||
onChanged: (String? newValue) {
|
||||
settings.uiColumnModeLandscape = Settings.uiColumnModeFromString(newValue!);
|
||||
saveSettings(context);
|
||||
},
|
||||
items: Settings.uiColumnModeOptions(true).map<DropdownMenuItem<String>>((DualpaneMode value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value.toString(),
|
||||
child: Text(
|
||||
Settings.uiColumnModeToString(value, context),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
}).toList())),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.streamerModeLabel, style: TextStyle(color: settings.current().mainTextColor)),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionStreamerMode),
|
||||
value: settings.streamerMode,
|
||||
onChanged: (bool value) {
|
||||
settings.setStreamerMode(value);
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.streamer_bunnymask, color: settings.current().mainTextColor),
|
||||
),
|
||||
SizedBox(
|
||||
height: 40,
|
||||
),
|
||||
Row(mainAxisAlignment: MainAxisAlignment.center, children: [Text(AppLocalizations.of(context)!.settingGroupBehaviour, style: TextStyle(fontWeight: FontWeight.bold))]),
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.notificationPolicySettingLabel),
|
||||
subtitle: Text(AppLocalizations.of(context)!.notificationPolicySettingDescription),
|
||||
trailing: DropdownButton(
|
||||
value: settings.notificationPolicy,
|
||||
onChanged: (NotificationPolicy? newValue) {
|
||||
settings.notificationPolicy = newValue!;
|
||||
saveSettings(context);
|
||||
},
|
||||
items: NotificationPolicy.values.map<DropdownMenuItem<NotificationPolicy>>((NotificationPolicy value) {
|
||||
return DropdownMenuItem<NotificationPolicy>(
|
||||
value: value,
|
||||
child: Text(
|
||||
Settings.notificationPolicyToString(value, context),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
}).toList()),
|
||||
leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.notificationContentSettingLabel),
|
||||
subtitle: Text(AppLocalizations.of(context)!.notificationContentSettingDescription),
|
||||
trailing: DropdownButton(
|
||||
value: settings.notificationContent,
|
||||
onChanged: (NotificationContent? newValue) {
|
||||
settings.notificationContent = newValue!;
|
||||
saveSettings(context);
|
||||
},
|
||||
items: NotificationContent.values.map<DropdownMenuItem<NotificationContent>>((NotificationContent value) {
|
||||
return DropdownMenuItem<NotificationContent>(
|
||||
value: value,
|
||||
child: Text(
|
||||
Settings.notificationContentToString(value, context),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
);
|
||||
}).toList()),
|
||||
leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.blockUnknownLabel, style: TextStyle(color: settings.current().mainTextColor)),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionBlockUnknownConnections),
|
||||
|
@ -171,19 +227,10 @@ class _GlobalSettingsViewState extends State<GlobalSettingsView> {
|
|||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.block_unknown, color: settings.current().mainTextColor),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.streamerModeLabel, style: TextStyle(color: settings.current().mainTextColor)),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionStreamerMode),
|
||||
value: settings.streamerMode,
|
||||
onChanged: (bool value) {
|
||||
settings.setStreamerMode(value);
|
||||
// Save Settings...
|
||||
saveSettings(context);
|
||||
},
|
||||
activeTrackColor: settings.theme.defaultButtonColor,
|
||||
inactiveTrackColor: settings.theme.defaultButtonDisabledColor,
|
||||
secondary: Icon(CwtchIcons.streamer_bunnymask, color: settings.current().mainTextColor),
|
||||
SizedBox(
|
||||
height: 40,
|
||||
),
|
||||
Row(mainAxisAlignment: MainAxisAlignment.center, children: [Text(AppLocalizations.of(context)!.settingsGroupExperiments, style: TextStyle(fontWeight: FontWeight.bold))]),
|
||||
SwitchListTile(
|
||||
title: Text(AppLocalizations.of(context)!.experimentsEnabled, style: TextStyle(color: settings.current().mainTextColor)),
|
||||
subtitle: Text(AppLocalizations.of(context)!.descriptionExperiments),
|
||||
|
|
|
@ -130,7 +130,26 @@ class _GroupSettingsViewState extends State<GroupSettingsView> {
|
|||
SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
// TODO
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.conversationNotificationPolicySettingLabel, style: TextStyle(color: settings.current().mainTextColor)),
|
||||
subtitle: Text(AppLocalizations.of(context)!.conversationNotificationPolicySettingDescription),
|
||||
leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
|
||||
trailing: DropdownButton(
|
||||
value: Provider.of<ContactInfoState>(context).notificationsPolicy,
|
||||
items: ConversationNotificationPolicy.values.map<DropdownMenuItem<ConversationNotificationPolicy>>((ConversationNotificationPolicy value) {
|
||||
return DropdownMenuItem<ConversationNotificationPolicy>(
|
||||
value: value,
|
||||
child: Text(value.toName(context)),
|
||||
);
|
||||
}).toList(),
|
||||
onChanged: (ConversationNotificationPolicy? newVal) {
|
||||
Provider.of<ContactInfoState>(context, listen: false).notificationsPolicy = newVal!;
|
||||
var profileOnion = Provider.of<ContactInfoState>(context, listen: false).profileOnion;
|
||||
var identifier = Provider.of<ContactInfoState>(context, listen: false).identifier;
|
||||
const NotificationPolicyKey = "profile.notification-policy";
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SetConversationAttribute(profileOnion, identifier, NotificationPolicyKey, newVal.toString());
|
||||
},
|
||||
)),
|
||||
]),
|
||||
|
||||
Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, children: [
|
||||
|
|
|
@ -40,9 +40,13 @@ class _PeerSettingsViewState extends State<PeerSettingsView> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var handle = Provider.of<ContactInfoState>(context).nickname;
|
||||
if (handle.isEmpty) {
|
||||
handle = Provider.of<ContactInfoState>(context).onion;
|
||||
}
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(Provider.of<ContactInfoState>(context).onion),
|
||||
title: Text(handle + " " + AppLocalizations.of(context)!.conversationSettings),
|
||||
),
|
||||
body: _buildSettingsList(),
|
||||
);
|
||||
|
@ -211,6 +215,26 @@ class _PeerSettingsViewState extends State<PeerSettingsView> {
|
|||
child: Text(value),
|
||||
);
|
||||
}).toList())),
|
||||
ListTile(
|
||||
title: Text(AppLocalizations.of(context)!.conversationNotificationPolicySettingLabel, style: TextStyle(color: settings.current().mainTextColor)),
|
||||
subtitle: Text(AppLocalizations.of(context)!.conversationNotificationPolicySettingDescription),
|
||||
leading: Icon(CwtchIcons.chat_bubble_empty_24px, color: settings.current().mainTextColor),
|
||||
trailing: DropdownButton(
|
||||
value: Provider.of<ContactInfoState>(context).notificationsPolicy,
|
||||
items: ConversationNotificationPolicy.values.map<DropdownMenuItem<ConversationNotificationPolicy>>((ConversationNotificationPolicy value) {
|
||||
return DropdownMenuItem<ConversationNotificationPolicy>(
|
||||
value: value,
|
||||
child: Text(value.toName(context)),
|
||||
);
|
||||
}).toList(),
|
||||
onChanged: (ConversationNotificationPolicy? newVal) {
|
||||
Provider.of<ContactInfoState>(context, listen: false).notificationsPolicy = newVal!;
|
||||
var profileOnion = Provider.of<ContactInfoState>(context, listen: false).profileOnion;
|
||||
var identifier = Provider.of<ContactInfoState>(context, listen: false).identifier;
|
||||
const NotificationPolicyKey = "profile.notification-policy";
|
||||
Provider.of<FlwtchState>(context, listen: false).cwtch.SetConversationAttribute(profileOnion, identifier, NotificationPolicyKey, newVal.toString());
|
||||
},
|
||||
)),
|
||||
]),
|
||||
Column(mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end, children: [
|
||||
SizedBox(
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import '../main.dart';
|
||||
import '../settings.dart';
|
||||
|
||||
class SplashView extends StatefulWidget {
|
||||
|
@ -14,6 +15,13 @@ class SplashView extends StatefulWidget {
|
|||
class _SplashViewState extends State<SplashView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var cwtch = Provider.of<FlwtchState>(context, listen: false).cwtch;
|
||||
if (!cwtch.isL10nInit()) {
|
||||
if (AppLocalizations.of(context) != null && AppLocalizations.of(context)!.newMessageNotificationSimple.isNotEmpty ) {
|
||||
cwtch.l10nInit(AppLocalizations.of(context)!.newMessageNotificationSimple, AppLocalizations.of(context)!.newMessageNotificationConversationInfo);
|
||||
}
|
||||
}
|
||||
|
||||
return Consumer<AppState>(
|
||||
builder: (context, appState, child) => Scaffold(
|
||||
key: Key("SplashView"),
|
||||
|
|
Loading…
Reference in New Issue