Status + Profile Attributes

This commit is contained in:
Sarah Jamie Lewis 2023-04-04 13:58:42 -07:00 committed by Gitea
parent c83ef21f90
commit 267b1b09b1
36 changed files with 561 additions and 96 deletions

View File

@ -483,6 +483,17 @@ class MainActivity: FlutterActivity() {
val v: String = call.argument("Val") ?: ""
Cwtch.setProfileAttribute(profile, key, v)
}
"GetProfileAttribute" -> {
val profile: String = call.argument("ProfileOnion") ?: ""
val key: String = call.argument("Key") ?: ""
Data.Builder().putString("result", Cwtch.getProfileAttribute(profile, key)).build()
}
"GetConversationAttribute" -> {
val profile: String = call.argument("ProfileOnion") ?: ""
val conversation: Int = call.argument("conversation") ?: 0
val key: String = call.argument("Key") ?: ""
Data.Builder().putString("result", Cwtch.getConversationAttribute(profile, conversation.toLong(), key)).build()
}
"SetConversationAttribute" -> {
val profile: String = call.argument("ProfileOnion") ?: ""
val conversation: Int = call.argument("conversation") ?: 0

View File

@ -95,9 +95,12 @@ abstract class Cwtch {
Future<dynamic> ImportBundle(String profile, String bundle);
// ignore: non_constant_identifier_names
void SetProfileAttribute(String profile, String key, String val);
String? GetProfileAttribute(String profile, String key);
// ignore: non_constant_identifier_names
void SetConversationAttribute(String profile, int conversation, String key, String val);
// ignore: non_constant_identifier_names
String? GetConversationAttribute(String profile, int identifier, String s);
// ignore: non_constant_identifier_names
void SetMessageAttribute(String profile, int conversation, int channel, int message, String key, String val);
// ignore: non_constant_identifier_names
void LoadServers(String password);

View File

@ -30,14 +30,15 @@ class CwtchNotifier {
late NotificationsManager notificationManager;
late AppState appState;
late ServerListState serverListState;
late FlwtchState flwtchState;
String? notificationSimple;
String? notificationConversationInfo;
SeenMessageCallback? seenMessageCallback;
CwtchNotifier(
ProfileListState pcn, Settings settingsCN, ErrorHandler errorCN, TorStatus torStatusCN, NotificationsManager notificationManagerP, AppState appStateCN, ServerListState serverListStateCN) {
CwtchNotifier(ProfileListState pcn, Settings settingsCN, ErrorHandler errorCN, TorStatus torStatusCN, NotificationsManager notificationManagerP, AppState appStateCN,
ServerListState serverListStateCN, FlwtchState flwtchStateCN) {
profileCN = pcn;
settings = settingsCN;
error = errorCN;
@ -45,6 +46,7 @@ class CwtchNotifier {
notificationManager = notificationManagerP;
appState = appStateCN;
serverListState = serverListStateCN;
flwtchState = flwtchStateCN;
}
void l10nInit(String notificationSimple, String notificationConversationInfo) {
@ -74,6 +76,19 @@ class CwtchNotifier {
// if tag != v1-defaultPassword then it is either encrypted OR it is an unencrypted account created during pre-beta...
profileCN.add(data["Identity"], data["name"], data["picture"], data["defaultPicture"], data["ContactsJson"], data["ServerList"], data["Online"] == "true", data["autostart"] == "true",
data["tag"] != "v1-defaultPassword");
// Update Profile Attributes
profileCN.getProfile(data["Identity"])?.setAttribute(0, flwtchState.cwtch.GetProfileAttribute(data["Identity"], "profile.profile-attribute-1"));
profileCN.getProfile(data["Identity"])?.setAttribute(1, flwtchState.cwtch.GetProfileAttribute(data["Identity"], "profile.profile-attribute-2"));
profileCN.getProfile(data["Identity"])?.setAttribute(2, flwtchState.cwtch.GetProfileAttribute(data["Identity"], "profile.profile-attribute-3"));
profileCN.getProfile(data["Identity"])?.setAvailabilityStatus(flwtchState.cwtch.GetProfileAttribute(data["Identity"], "profile.profile-status") ?? "");
profileCN.getProfile(data["Identity"])?.contactList.contacts.forEach((contact) {
contact.setAttribute(0, flwtchState.cwtch.GetConversationAttribute(data["Identity"], contact.identifier, "public.profile.profile-attribute-1"));
contact.setAttribute(1, flwtchState.cwtch.GetConversationAttribute(data["Identity"], contact.identifier, "public.profile.profile-attribute-2"));
contact.setAttribute(2, flwtchState.cwtch.GetConversationAttribute(data["Identity"], contact.identifier, "public.profile.profile-attribute-3"));
contact.setAvailabilityStatus(flwtchState.cwtch.GetConversationAttribute(data["Identity"], contact.identifier, "public.profile.profile-status") ?? "");
});
break;
case "ContactCreated":
EnvironmentConfig.debugLog("ContactCreated $data");
@ -291,6 +306,10 @@ class CwtchNotifier {
profileCN.getProfile(data["ProfileOnion"])?.downloadSetPathForSender(filekey, data["Data"]);
}
}
} else if (data["Key"].toString().startsWith("public.profile.profile-attribute")) {
// ignore these events...
} else if (data["Key"].toString().startsWith("public.profile.profile-status")) {
profileCN.getProfile(data["ProfileOnion"])?.setAvailabilityStatus(data["Data"]);
} else {
EnvironmentConfig.debugLog("unhandled set attribute event: ${data['Key']}");
}
@ -377,6 +396,30 @@ class CwtchNotifier {
profileCN.getProfile(data["ProfileOnion"])?.waitForDownloadComplete(contact.identifier, fileKey);
}
}
} else if (data['Path'] == "profile.profile-attribute-1" || data['Path'] == "profile.profile-attribute-2" || data['Path'] == "profile.profile-attribute-3") {
if (data["Exists"] == "true") {
var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]);
if (contact != null) {
switch (data['Path']) {
case "profile.profile-attribute-1":
contact.setAttribute(0, data["Data"]);
break;
case "profile.profile-attribute-2":
contact.setAttribute(1, data["Data"]);
break;
case "profile.profile-attribute-3":
contact.setAttribute(2, data["Data"]);
break;
}
}
}
} else if (data['Path'] == "profile.profile-status") {
if (data["Exists"] == "true") {
var contact = profileCN.getProfile(data["ProfileOnion"])?.contactList.findContact(data["RemotePeer"]);
if (contact != null) {
contact.setAvailabilityStatus(data['Data']);
}
}
} else {
EnvironmentConfig.debugLog("unhandled ret val event: ${data['Path']}");
}

View File

@ -72,6 +72,9 @@ typedef GetJsonBlobFromStrStrIntFn = Pointer<Utf8> Function(Pointer<Utf8>, int,
typedef get_json_blob_from_str_int_function = Pointer<Utf8> Function(Pointer<Utf8>, Int32, Int32);
typedef GetJsonBlobFromStrIntFn = Pointer<Utf8> Function(Pointer<Utf8>, int, int);
typedef get_json_blob_from_str_str_function = Pointer<Utf8> Function(Pointer<Utf8>, Int32, Pointer<Utf8>, Int32);
typedef GetJsonBlobFromStrStrFn = Pointer<Utf8> Function(Pointer<Utf8>, int, Pointer<Utf8>, int);
typedef get_json_blob_from_str_int_int_str_function = Pointer<Utf8> Function(Pointer<Utf8>, Int32, Int32, Int32, Pointer<Utf8>, Int32);
typedef GetJsonBlobFromStrIntIntStrFn = Pointer<Utf8> Function(
Pointer<Utf8>,
@ -962,4 +965,54 @@ class CwtchFfi implements Cwtch {
}
return false;
}
@override
String? GetProfileAttribute(String profile, String key) {
var getProfileAttributeC = library.lookup<NativeFunction<get_json_blob_from_str_str_function>>("c_GetProfileAttribute");
// ignore: non_constant_identifier_names
final GetProfileAttribute = getProfileAttributeC.asFunction<GetJsonBlobFromStrStrFn>();
final utf8profile = profile.toNativeUtf8();
final utf8key = key.toNativeUtf8();
Pointer<Utf8> jsonMessageBytes = GetProfileAttribute(utf8profile, utf8profile.length, utf8key, utf8key.length);
String jsonMessage = jsonMessageBytes.toDartString();
_UnsafeFreePointerAnyUseOfThisFunctionMustBeDoubleApproved(jsonMessageBytes);
malloc.free(utf8profile);
malloc.free(utf8key);
try {
dynamic attributeResult = json.decode(jsonMessage);
if (attributeResult["Exists"]) {
return attributeResult["Value"];
}
} catch (e) {
EnvironmentConfig.debugLog("error getting profile attribute: $e");
}
return null;
}
@override
String? GetConversationAttribute(String profile, int conversation, String key) {
var getConversationAttributeC = library.lookup<NativeFunction<get_json_blob_from_str_int_string_function>>("c_GetConversationAttribute");
// ignore: non_constant_identifier_names
final GetConversationAttribute = getConversationAttributeC.asFunction<GetJsonBlobFromStrIntStringFn>();
final utf8profile = profile.toNativeUtf8();
final utf8key = key.toNativeUtf8();
Pointer<Utf8> jsonMessageBytes = GetConversationAttribute(utf8profile, utf8profile.length, conversation, utf8key, utf8key.length);
String jsonMessage = jsonMessageBytes.toDartString();
_UnsafeFreePointerAnyUseOfThisFunctionMustBeDoubleApproved(jsonMessageBytes);
malloc.free(utf8profile);
malloc.free(utf8key);
try {
dynamic attributeResult = json.decode(jsonMessage);
if (attributeResult["Exists"]) {
return attributeResult["Value"];
}
} catch (e) {
EnvironmentConfig.debugLog("error getting profile attribute: $e");
}
return null;
}
}

View File

@ -388,4 +388,22 @@ class CwtchGomobile implements Cwtch {
// Blodeuwedd is not currently supported on lower end devices.
return false;
}
@override
String? GetProfileAttribute(String profile, String key) {
dynamic attributeResult = cwtchPlatform.invokeMethod("GetProfileAttribute", {"ProfileOnion": profile, "key": key});
if (attributeResult["Exists"]) {
return attributeResult["Value"];
}
return null;
}
@override
String? GetConversationAttribute(String profile, int conversation, String key) {
dynamic attributeResult = cwtchPlatform.invokeMethod("GetProfileAttribute", {"ProfileOnion": profile, "conversation": conversation, "key": key});
if (attributeResult["Exists"]) {
return attributeResult["Value"];
}
return null;
}
}

View File

@ -1,6 +1,13 @@
{
"@@locale": "cy",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "da",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "de",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "el",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "en",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusAway": "Away",
"availabilityStatusBusy": "Busy",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddSummarize": "Summarize Conversation",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "es",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "fr",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "it",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,14 +1,21 @@
{
"@@locale": "ko",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddExperimentEnable": "Blodeuwedd (블러드웨드) 어시스턴트",
"blodeuweddDescription": "Blodeuwedd (불러드웨드) 어시스턴트는 로컬에서 호스팅되는 언어 모델을 통한 대화 내용 요약 및 메시지 번역과 같은 Cwtch에 새로운 기능을 추가합니다.",
"blodeuweddSummarize": "Summarize Conversation",
"blodeuweddTranslate": "메시지 번역",
"blodeuweddProcessing": "Blodeuwedd 처리 중...",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddPath": "The directory where the Blodeuwedd is located on your computer.",
"blodeuweddNotSupported": "This version of Cwtch has been compiled without support for the Blodeuwedd Assistant.",
"blodeuweddDescription": "The Blodeuwedd assistant adds new features to Cwtch such as chat transcript summarization and message translation via a locally hosted language model.",
"blodeuweddExperimentEnable": "Blodeuwedd Assistant",
"labelACNCircuitInfo": "ACN 회로 정보",
"clickableLinksWarning": "이 URL을 열면 Cwtch 외부에서 응용 프로그램이 시작되고 메타데이터가 노출되거나 Cwtch의 보안이 손상될 수 있습니다. 신뢰할 수 있는 사용자의 URL만 엽니다. 계속하시겠습니까?",
"thisFeatureRequiresGroupExpermientsToBeEnabled": "이 기능을 사용하려면 설정에서 그룹 실험을 사용하도록 설정해야 합니다.",

View File

@ -1,6 +1,13 @@
{
"@@locale": "lb",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "nl",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "no",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "pl",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "pt",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "pt_BR",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "ro",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "ru",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "sk",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -1,6 +1,13 @@
{
"@@locale": "tr",
"@@last_modified": "2023-03-27T20:38:31+02:00",
"@@last_modified": "2023-04-03T22:39:52+02:00",
"profileInfoHint3": "Contacts will be able to see this information in Conversation Settings ",
"profileInfoHint2": "You can add up to 3 fields.",
"profileInfoHint": "Add some public information about yourself here e.g. blog, websites, brief bio.",
"availabilityStatusTooltip": "Set your availability status.",
"availabilityStatusBusy": "Busy",
"availabilityStatusAway": "Away",
"availabilityStatusAvailable": "Available",
"blodeuweddWarning": "Blodeuwedd uses a local language model and a set of small auxiliary models to power its functionality. These techniques are often very effective they are not without error. \n\nWhile we have taken efforts to minimize the risk, there is still the possibility that Blodeuwedd outputs will be incorrect, hallucinated and\/or offensive.\n\nBecause of that Blodeuwedd requires downloading two additional components separate from Cwtch, the Blodeuwedd Model (or a compatible model) and the Blodeuwedd Runner. \n\nSee https:\/\/docs.cwtch.im\/docs\/settings\/experiments\/blodeuwedd for more information on obtaining these components and setting them up.",
"blodeuweddProcessing": "Blodeuwedd is processing...",
"blodeuweddTranslate": "Translate Message",

View File

@ -88,13 +88,15 @@ class FlwtchState extends State<Flwtch> with WindowListener {
shutdownLinuxMethodChannel.setMethodCallHandler(shutdownDirect);
print("initState: creating cwtchnotifier, ffi");
if (Platform.isAndroid) {
var cwtchNotifier = new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, NullNotificationsManager(), globalAppState, globalServersList);
var cwtchNotifier = new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, NullNotificationsManager(), globalAppState, globalServersList, this);
cwtch = CwtchGomobile(cwtchNotifier);
} else if (Platform.isLinux) {
var cwtchNotifier = new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, newDesktopNotificationsManager(_notificationSelectConvo), globalAppState, globalServersList);
var cwtchNotifier =
new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, newDesktopNotificationsManager(_notificationSelectConvo), globalAppState, globalServersList, this);
cwtch = CwtchFfi(cwtchNotifier);
} else {
var cwtchNotifier = new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, newDesktopNotificationsManager(_notificationSelectConvo), globalAppState, globalServersList);
var cwtchNotifier =
new CwtchNotifier(profs, globalSettings, globalErrorHandler, globalTorStatus, newDesktopNotificationsManager(_notificationSelectConvo), globalAppState, globalServersList, this);
cwtch = CwtchFfi(cwtchNotifier);
}
print("initState: invoking cwtch.Start()");

View File

@ -1,6 +1,10 @@
import 'dart:ffi';
import 'package:cwtch/main.dart';
import 'package:cwtch/models/message_draft.dart';
import 'package:cwtch/models/profile.dart';
import 'package:cwtch/themes/opaque.dart';
import 'package:cwtch/views/contactsview.dart';
import 'package:cwtch/widgets/messagerow.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
@ -101,7 +105,7 @@ class ContactInfoState extends ChangeNotifier {
keys = Map<String, GlobalKey<MessageRowState>>();
}
String get nickname => this._nickname + (this._messageDraft.isEmpty() ? "" : "*");
String get nickname => this._nickname;
String get savePeerHistory => this._savePeerHistory;
String? get acnCircuit => this._acnCircuit;
@ -354,4 +358,61 @@ class ContactInfoState extends ChangeNotifier {
this.messageCache.updateTranslationEvent(messageID, translation);
notifyListeners();
}
// Contact Attributes. Can be set in Profile Edit View...
List<String?> attributes = [null, null, null];
void setAttribute(int i, String? value) {
this.attributes[i] = value;
notifyListeners();
}
ProfileStatusMenu availabilityStatus = ProfileStatusMenu.available;
void setAvailabilityStatus(String status) {
switch (status) {
case "available":
availabilityStatus = ProfileStatusMenu.available;
break;
case "busy":
availabilityStatus = ProfileStatusMenu.busy;
break;
case "away":
availabilityStatus = ProfileStatusMenu.away;
break;
default:
ProfileStatusMenu.available;
}
notifyListeners();
}
Color getBorderColor(OpaqueThemeType theme) {
if (this.isBlocked) {
return theme.portraitBlockedBorderColor;
}
if (this.isOnline()) {
switch (this.availabilityStatus) {
case ProfileStatusMenu.available:
return theme.portraitOnlineBorderColor;
case ProfileStatusMenu.away:
return theme.portraitOnlineAwayColor;
case ProfileStatusMenu.busy:
return theme.portraitOnlineBusyColor;
}
}
return theme.portraitOfflineBorderColor;
}
String augmentedNickname(BuildContext context) {
return this.nickname + (this.availabilityStatus == ProfileStatusMenu.available ? "" : " (" +this.statusString(context) + ")");
}
String statusString(BuildContext context) {
switch (this.availabilityStatus) {
case ProfileStatusMenu.available:
return AppLocalizations.of(context)!.availabilityStatusAvailable;
case ProfileStatusMenu.away:
return AppLocalizations.of(context)!.availabilityStatusAway;
case ProfileStatusMenu.busy:
return AppLocalizations.of(context)!.availabilityStatusBusy;
}
}
}

View File

@ -33,11 +33,11 @@ class FileMessage extends Message {
int fileSize = shareObj['s'] as int;
String fileKey = rootHash + "." + nonce;
if (metadata.attributes["file-downloaded"] == "true") {
if (!Provider.of<ProfileInfoState>(context).downloadKnown(fileKey)) {
Provider.of<FlwtchState>(context, listen: false).cwtch.CheckDownloadStatus(Provider.of<ProfileInfoState>(context, listen: false).onion, fileKey);
}
}
// if (metadata.attributes["file-downloaded"] == "true") {
// if (!Provider.of<ProfileInfoState>(context).downloadKnown(fileKey)) {
Provider.of<FlwtchState>(context, listen: false).cwtch.CheckDownloadStatus(Provider.of<ProfileInfoState>(context, listen: false).onion, fileKey);
// }
//}
if (!validHash(rootHash, nonce)) {
return MessageRow(MalformedBubble(), index);

View File

@ -1,9 +1,12 @@
import 'dart:convert';
import 'package:cwtch/config.dart';
import 'package:cwtch/models/remoteserver.dart';
import 'package:flutter/widgets.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import '../themes/opaque.dart';
import '../views/contactsview.dart';
import 'contact.dart';
import 'contactlist.dart';
import 'filedownloadprogress.dart';
@ -398,4 +401,40 @@ class ProfileInfoState extends ChangeNotifier {
this._downloads.remove(fileKey);
notifyListeners();
}
// Profile Attributes. Can be set in Profile Edit View...
List<String?> attributes = [null, null, null];
void setAttribute(int i, String? value) {
this.attributes[i] = value;
notifyListeners();
}
ProfileStatusMenu availabilityStatus = ProfileStatusMenu.available;
void setAvailabilityStatus(String status) {
switch (status) {
case "available":
availabilityStatus = ProfileStatusMenu.available;
break;
case "busy":
availabilityStatus = ProfileStatusMenu.busy;
break;
case "away":
availabilityStatus = ProfileStatusMenu.away;
break;
default:
ProfileStatusMenu.available;
}
notifyListeners();
}
Color getBorderColor(OpaqueThemeType theme) {
switch (this.availabilityStatus) {
case ProfileStatusMenu.available:
return theme.portraitOnlineBorderColor;
case ProfileStatusMenu.away:
return theme.portraitOnlineAwayColor;
case ProfileStatusMenu.busy:
return theme.portraitOnlineBusyColor;
}
}
}

View File

@ -106,6 +106,9 @@ abstract class OpaqueThemeType {
get portraitProfileBadgeColor => red;
get portraitProfileBadgeTextColor => red;
get portraitOnlineAwayColor => Color(0xFFFFF59D);
get portraitOnlineBusyColor => Color(0xFFEF9A9A);
// dropshaddpow
// todo: probably should not be reply icon color in messagerow
get dropShadowColor => red;

View File

@ -38,6 +38,11 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
final ctrlrPass = TextEditingController(text: "");
final ctrlrPass2 = TextEditingController(text: "");
final ctrlrOnion = TextEditingController(text: "");
final ctrlrAttribute1 = TextEditingController(text: "");
final ctrlrAttribute2 = TextEditingController(text: "");
final ctrlrAttribute3 = TextEditingController(text: "");
ScrollController controller = ScrollController();
late bool usePassword;
late bool deleted;
@ -93,42 +98,89 @@ class _AddEditProfileViewState extends State<AddEditProfileView> {
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [
Visibility(
visible: Provider.of<ProfileInfoState>(context).onion.isNotEmpty,
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
MouseRegion(
cursor: Provider.of<Settings>(context).isExperimentEnabled(ImagePreviewsExperiment) ? SystemMouseCursors.click : SystemMouseCursors.basic,
child: GestureDetector(
// don't allow setting of profile images if the image previews experiment is disabled.
onTap: Provider.of<AppState>(context, listen: false).disableFilePicker ||
!Provider.of<Settings>(context, listen: false).isExperimentEnabled(ImagePreviewsExperiment)
? null
: () {
filesharing.showFilePicker(context, MaxImageFileSharingSize, (File file) {
var profile = Provider.of<ProfileInfoState>(context, listen: false).onion;
// Share this image publicly (conversation handle == -1)
Provider.of<FlwtchState>(context, listen: false).cwtch.ShareFile(profile, -1, file.path);
// update the image cache locally
Provider.of<ProfileInfoState>(context, listen: false).imagePath = file.path;
}, () {
final snackBar = SnackBar(
content: Text(AppLocalizations.of(context)!.msgFileTooBig),
duration: Duration(seconds: 4),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}, () {});
},
child: ProfileImage(
imagePath: Provider.of<Settings>(context).isExperimentEnabled(ImagePreviewsExperiment)
? Provider.of<ProfileInfoState>(context).imagePath
: Provider.of<ProfileInfoState>(context).defaultImagePath,
diameter: 120,
tooltip:
Provider.of<Settings>(context).isExperimentEnabled(ImagePreviewsExperiment) ? AppLocalizations.of(context)!.tooltipSelectACustomProfileImage : "",
maskOut: false,
border: theme.theme.portraitOnlineBorderColor,
badgeTextColor: theme.theme.portraitContactBadgeTextColor,
badgeColor: theme.theme.portraitContactBadgeColor,
badgeEdit: Provider.of<Settings>(context).isExperimentEnabled(ImagePreviewsExperiment))))
])),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
MouseRegion(
cursor: Provider.of<Settings>(context).isExperimentEnabled(ImagePreviewsExperiment) ? SystemMouseCursors.click : SystemMouseCursors.basic,
child: GestureDetector(
// don't allow setting of profile images if the image previews experiment is disabled.
onTap: Provider.of<AppState>(context, listen: false).disableFilePicker ||
!Provider.of<Settings>(context, listen: false).isExperimentEnabled(ImagePreviewsExperiment)
? null
: () {
filesharing.showFilePicker(context, MaxImageFileSharingSize, (File file) {
var profile = Provider.of<ProfileInfoState>(context, listen: false).onion;
// Share this image publicly (conversation handle == -1)
Provider.of<FlwtchState>(context, listen: false).cwtch.ShareFile(profile, -1, file.path);
// update the image cache locally
Provider.of<ProfileInfoState>(context, listen: false).imagePath = file.path;
}, () {
final snackBar = SnackBar(
content: Text(AppLocalizations.of(context)!.msgFileTooBig),
duration: Duration(seconds: 4),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}, () {});
},
child: ProfileImage(
imagePath: Provider.of<Settings>(context).isExperimentEnabled(ImagePreviewsExperiment)
? Provider.of<ProfileInfoState>(context).imagePath
: Provider.of<ProfileInfoState>(context).defaultImagePath,
diameter: 120,
tooltip: Provider.of<Settings>(context).isExperimentEnabled(ImagePreviewsExperiment)
? AppLocalizations.of(context)!.tooltipSelectACustomProfileImage
: "",
maskOut: false,
border: theme.theme.portraitOnlineBorderColor,
badgeTextColor: theme.theme.portraitContactBadgeTextColor,
badgeColor: theme.theme.portraitContactBadgeColor,
badgeEdit: Provider.of<Settings>(context).isExperimentEnabled(ImagePreviewsExperiment))))
]),
SizedBox(
width: MediaQuery.of(context).size.width / 2,
child: Column(
children: [
Padding(
padding: EdgeInsets.all(5.0),
child: CwtchTextField(
controller: ctrlrAttribute1,
multiLine: false,
onChanged: (profileAttribute1) {
String onion = Provider.of<ProfileInfoState>(context, listen: false).onion;
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(onion, "profile.profile-attribute-1", profileAttribute1);
Provider.of<ProfileInfoState>(context, listen: false).attributes[0] = profileAttribute1;
},
hintText: Provider.of<ProfileInfoState>(context).attributes[0] ?? AppLocalizations.of(context)!.profileInfoHint!)),
Padding(
padding: EdgeInsets.all(5.0),
child: CwtchTextField(
controller: ctrlrAttribute2,
multiLine: false,
onChanged: (profileAttribute2) {
String onion = Provider.of<ProfileInfoState>(context, listen: false).onion;
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(onion, "profile.profile-attribute-2", profileAttribute2);
Provider.of<ProfileInfoState>(context, listen: false).attributes[1] = profileAttribute2;
},
hintText: Provider.of<ProfileInfoState>(context).attributes[1] ?? AppLocalizations.of(context)!.profileInfoHint2!)),
Padding(
padding: EdgeInsets.all(5.0),
child: CwtchTextField(
controller: ctrlrAttribute3,
multiLine: false,
onChanged: (profileAttribute3) {
String onion = Provider.of<ProfileInfoState>(context, listen: false).onion;
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(onion, "profile.profile-attribute-3", profileAttribute3);
Provider.of<ProfileInfoState>(context, listen: false).attributes[2] = profileAttribute3;
},
hintText: Provider.of<ProfileInfoState>(context).attributes[2] ?? AppLocalizations.of(context)!.profileInfoHint3!)),
],
))
],
)),
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
SizedBox(
height: 20,

View File

@ -25,6 +25,8 @@ import 'messageview.dart';
enum ShareMenu { copyCode, qrcode }
enum ProfileStatusMenu { available, away, busy }
class ContactsView extends StatefulWidget {
const ContactsView({Key? key}) : super(key: key);
@ -137,12 +139,43 @@ class _ContactsViewState extends State<ContactsView> {
? Provider.of<ProfileInfoState>(context).imagePath
: Provider.of<ProfileInfoState>(context).defaultImagePath,
diameter: 42,
border: Provider.of<ProfileInfoState>(context).isOnline
? Provider.of<Settings>(context).current().portraitOnlineBorderColor
: Provider.of<Settings>(context).current().portraitOfflineBorderColor,
border: Provider.of<ProfileInfoState>(context).getBorderColor(Provider.of<Settings>(context).theme),
badgeTextColor: Colors.red,
badgeColor: Colors.red,
),
PopupMenuButton<ProfileStatusMenu>(
icon: Icon(Icons.online_prediction),
tooltip: AppLocalizations.of(context)!.availabilityStatusTooltip,
splashRadius: Material.defaultSplashRadius / 2,
onSelected: (ProfileStatusMenu item) {
String onion = Provider.of<ProfileInfoState>(context, listen: false).onion;
switch (item) {
case ProfileStatusMenu.available:
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(onion, "profile.profile-status", "available");
break;
case ProfileStatusMenu.away:
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(onion, "profile.profile-status", "away");
break;
case ProfileStatusMenu.busy:
Provider.of<FlwtchState>(context, listen: false).cwtch.SetProfileAttribute(onion, "profile.profile-status", "busy");
break;
}
},
itemBuilder: (BuildContext context) => <PopupMenuEntry<ProfileStatusMenu>>[
PopupMenuItem<ProfileStatusMenu>(
value: ProfileStatusMenu.available,
child: Text(AppLocalizations.of(context)!.availabilityStatusAvailable!,),
),
PopupMenuItem<ProfileStatusMenu>(
value: ProfileStatusMenu.away,
child: Text(AppLocalizations.of(context)!.availabilityStatusAway!,),
),
PopupMenuItem<ProfileStatusMenu>(
value: ProfileStatusMenu.busy,
child: Text(AppLocalizations.of(context)!.availabilityStatusBusy!,),
),
],
),
SizedBox(
width: 10,
),

View File

@ -196,7 +196,7 @@ class _MessageViewState extends State<MessageView> {
? Provider.of<ContactInfoState>(context).imagePath
: Provider.of<ContactInfoState>(context).defaultImagePath,
diameter: 42,
border: Provider.of<Settings>(context).current().portraitOnlineBorderColor,
border: Provider.of<ContactInfoState>(context).getBorderColor(Provider.of<Settings>(context).theme),
badgeTextColor: Colors.red,
badgeColor: Provider.of<Settings>(context).theme.portraitContactBadgeColor,
badgeIcon: Provider.of<ContactInfoState>(context).isGroup
@ -230,14 +230,15 @@ class _MessageViewState extends State<MessageView> {
),
Expanded(
child: Container(
height: 24,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(),
child: Text(
Provider.of<ContactInfoState>(context).nickname,
overflow: TextOverflow.clip,
maxLines: 1,
)))
height: 42,
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(),
child: Align(
alignment: Alignment.centerLeft, child: Text(
Provider.of<ContactInfoState>(context).augmentedNickname(context),
overflow: TextOverflow.clip,
maxLines: 1,
))))
]),
actions: appBarButtons,
),

View File

@ -96,8 +96,8 @@ class _PeerSettingsViewState extends State<PeerSettingsView> {
child: Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(2),
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
child: Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [
Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
ProfileImage(
imagePath: Provider.of<Settings>(context).isExperimentEnabled(ImagePreviewsExperiment)
? Provider.of<ContactInfoState>(context).imagePath
@ -107,7 +107,23 @@ class _PeerSettingsViewState extends State<PeerSettingsView> {
border: settings.theme.portraitOnlineBorderColor,
badgeTextColor: settings.theme.portraitContactBadgeTextColor,
badgeColor: settings.theme.portraitContactBadgeColor,
badgeEdit: false)
badgeEdit: false),
SizedBox(
width: MediaQuery.of(context).size.width / 2,
child: Column(children: [
Padding(
padding: EdgeInsets.all(1),
child: SelectableText(Provider.of<ContactInfoState>(context, listen: false).attributes[0] ?? ""),
),
Padding(
padding: EdgeInsets.all(1),
child: SelectableText(Provider.of<ContactInfoState>(context, listen: false).attributes[1] ?? ""),
),
Padding(
padding: EdgeInsets.all(1),
child: SelectableText(Provider.of<ContactInfoState>(context, listen: false).attributes[2] ?? ""),
)
]))
]),
Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [

View File

@ -44,20 +44,16 @@ class _ContactRowState extends State<ContactRow> {
color: Provider.of<AppState>(context).selectedConversation == contact.identifier ? Provider.of<Settings>(context).theme.backgroundHilightElementColor : Colors.transparent,
child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Padding(
padding: const EdgeInsets.all(6.0), //border size
child: ProfileImage(
padding: const EdgeInsets.all(6.0), //border size
child: ProfileImage(
badgeCount: contact.unreadMessages,
badgeColor: Provider.of<Settings>(context).theme.portraitContactBadgeColor,
badgeTextColor: Provider.of<Settings>(context).theme.portraitContactBadgeTextColor,
diameter: 64.0,
imagePath: Provider.of<Settings>(context).isExperimentEnabled(ImagePreviewsExperiment) ? contact.imagePath : contact.defaultImagePath,
disabled: !contact.isOnline(),
border: contact.isOnline()
? Provider.of<Settings>(context).theme.portraitOnlineBorderColor
: contact.isBlocked
? Provider.of<Settings>(context).theme.portraitBlockedBorderColor
: Provider.of<Settings>(context).theme.portraitOfflineBorderColor),
),
border: contact.getBorderColor(Provider.of<Settings>(context).theme),
)),
Expanded(
child: Padding(
padding: EdgeInsets.all(10.0),
@ -69,7 +65,7 @@ class _ContactRowState extends State<ContactRow> {
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(),
child: Text(
contact.nickname, //(contact.isInvitation ? "invite " : "non-invite ") + (contact.isBlocked ? "blokt" : "nonblokt"),//
contact.augmentedNickname(context) + (contact.messageDraft.isEmpty() ? "" : "*"),
style: TextStyle(
fontSize: Provider.of<Settings>(context).theme.contactOnionTextSize(),

View File

@ -505,7 +505,7 @@ void modalShowTranslation(BuildContext context, ProfileInfoState profile, Settin
var bubble = StaticMessageBubble(
profile,
settings,
MessageMetadata(profile.onion, Provider.of<ContactInfoState>(context).identifier, 1, DateTime.now(), "blodeuwedd", null, null, null, true, false, false, ""),
MessageMetadata(profile.onion, Provider.of<ContactInfoState>(context, listen: false).identifier, 1, DateTime.now(), "blodeuwedd", null, null, null, true, false, false, ""),
Row(children: [
Provider.of<MessageMetadata>(context).translation == ""
? Column(crossAxisAlignment: CrossAxisAlignment.center, children: [

View File

@ -68,6 +68,7 @@ class _CwtchTextFieldState extends State<CwtchTextField> {
decoration: InputDecoration(
errorMaxLines: 2,
hintText: widget.hintText,
hintStyle: TextStyle(color: (theme.current().mainTextColor as Color).withOpacity(0.5)),
floatingLabelBehavior: FloatingLabelBehavior.never,
filled: true,
focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(6.0), borderSide: BorderSide(color: theme.current().textfieldBorderColor, width: 1.0)),